spark_optimization

์ตœ์ ํ™” ํฌ์ธํŠธ

  • Spark ์—๋Š” ์ตœ์ ํ™” ๊ธฐ๋Šฅ๋“ค(optimizer) ์„ ๊ฐ–์ถ”๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

    • 1.x ๋ฒ„์ „์—์„œ๋Š” Rule-Based Optimizer๋งŒ ๊ฐ–๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

    • 2.x ๋ฒ„์ „์—์„œ Cost-Based Optimizer๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

    • 3.x ๋ฒ„์ „์—๋Š” Adaptive Query Execution(AQE) ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

AQE(Adaptive Query Execution)

  • image - https://www.databricks.com/blog/2020/05/29/adaptive-query-execution-speeding-up-spark-sql-at-runtime.html

  • ์‹คํ–‰ ์‹œ๊ฐ„ ๋™์•ˆ ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ๊ณ„ํš์„ ๋™์ ์œผ๋กœ ์žฌ์กฐ์ •ํ•˜๊ณ  ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค. AQE๋Š” ์‹คํ–‰ ๊ณ„ํš์„ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋Ÿฐํƒ€์ž„ ํ†ต๊ณ„๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ๋™์  ์…”ํ”Œ ํŒŒํ‹ฐ์…˜ ํ†ตํ•ฉ(Dynamically coalescing shuffle partitions)

    • image

    • ์…”ํ”Œ ์ดํ›„์— ์ƒ์„ฑ๋œ ํŒŒํ‹ฐ์…˜์˜ ํฌ๊ธฐ๊ฐ€ ๋„ˆ๋ฌด ์ž‘๊ฑฐ๋‚˜ ๋ถˆ๊ท ํ˜•์ ์ธ ๊ฒฝ์šฐ, AQE๋Š” ์ด๋Ÿฌํ•œ ํŒŒํ‹ฐ์…˜๋“ค์„ ๋™์ ์œผ๋กœ ํ†ตํ•ฉํ•˜์—ฌ ํŒŒํ‹ฐ์…˜ ์ˆ˜๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ํŒŒํ‹ฐ์…˜์— ๋Œ€ํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ  ์ „์ฒด ์ฟผ๋ฆฌ์˜ ์‹คํ–‰ ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

  • ๋™์  ์ „ํ™˜ ์กฐ์ธ ์ „๋žต(Dynamically switching join strategies)

    • image

    • ์กฐ์ธ ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ์‹ค์ œ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ๋ฅผ ํ™•์ธํ•˜๊ณ , ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ€์žฅ ์ ํ•ฉํ•œ ์กฐ์ธ ์ „๋žต (์˜ˆ: broadcast join, sort-merge join)์œผ๋กœ ๋™์ ์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

  • ์Šคํ ์กฐ์ธ์„ ๋™์ ์œผ๋กœ ์ตœ์ ํ™”(Dynamically optimizing skew joins)

    • image

    • ์กฐ์ธ ์—ฐ์‚ฐ ์‹œ ํ•œ์ชฝ์˜ ๋ฐ์ดํ„ฐ ๋ถ„ํฌ๊ฐ€ ๋งค์šฐ ๋ถˆ๊ท ํ˜•์ ์ธ ๊ฒฝ์šฐ (์ฆ‰, ์Šคํ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ), AQE๋Š” ์ด ์Šคํ๋ฅผ ์ธ์‹ํ•˜๊ณ  ํ•ด๋‹น ํŒŒํ‹ฐ์…˜์„ ์„ธ๋ถ„ํ™”ํ•˜์—ฌ ์กฐ์ธ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

์ตœ์ ํ™” ํฌ์ธํŠธ

  • ์ฝ”๋“œ ์ˆ˜์ค€์˜ ์„ค๊ณ„(์˜ˆ: RDD์™€ DataFrame ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•จ)

  • ๋ณด๊ด€์šฉ ๋ฐ์ดํ„ฐ

  • ์กฐ์ธ

  • ์ง‘๊ณ„

  • ๋ฐ์ดํ„ฐ ์ „์†ก

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋ณ„ ์†์„ฑ

  • ์ต์Šคํํ„ฐ ํ”„๋กœ์„ธ์Šค์˜ JVM

  • ์›Œ์ปค ๋…ธ๋“œ

  • ํด๋Ÿฌ์Šคํ„ฐ์™€ ๋ฐฐํฌ ํ™˜๊ฒฝ ์†์„ฑ

DataFrame vs SQL vs Dataset vs RDD

  • ๋ชจ๋“  ์–ธ์–ด์—์„œ DataFrame, Dataset ๊ทธ๋ฆฌ๊ณ  SQL์˜ ์†๋„๋Š” ๋™์ผํ•ฉ๋‹ˆ๋‹ค. DataFrame์€ ์–ด๋–ค ์–ธ์–ด์—์„œ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์„ฑ๋Šฅ์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

  • ํŒŒ์ด์ฌ์ด๋‚˜ R์„ ์‚ฌ์šฉํ•ด UDF๋ฅผ ์ •์˜ํ•˜๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ž๋ฐ”์™€ ์Šค์นผ๋ผ๋ฅผ ์‚ฌ์šฉํ•ด UDF๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • ํŒŒ์ด์ฌ์—์„œ RDD ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ํŒŒ์ด์ฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์˜ค๊ฐ€๋Š” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค., ๋งค์šฐ ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•˜๋ฉด ์—„์ฒญ๋‚œ ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜๊ณ  ์•ˆ์ •์„ฑ๊นŒ์ง€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • RDD

    • image

    • https://phoenixnap.com/kb/resilient-distributed-datasets

    • DataFrame์˜ ๊ฐ ๋ ˆ์ฝ”๋“œ๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ์•Œ๊ณ  ์žˆ๋Š” ํ•„๋“œ๋กœ ๊ตฌ์„ฑ๋œ ๊ตฌ์กฐํ™”๋œ ๋กœ์šฐ์ธ ๋ฐ˜๋ฉด, RDD์˜ ๋ ˆ์ฝ”๋“œ๋Š” ๊ทธ์ € ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์„ ํƒํ•œ ์ž๋ฐ”, ์Šค์นผ๋ผ, ํŒŒ์ด์ฌ์˜ ๊ฐ์ฒด์ผ๋ฟ RDD API๋Š” Dataset๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ RDD๋Š” ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ ์—”์ง„์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. RDD์™€ Dataset ์‚ฌ์ด์˜ ์ „ํ™˜์€ ๋งค์šฐ ์‰ฌ์šฐ๋ฏ€๋กœ ๋‘ API๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•ด ๊ฐ API์˜ ์žฅ์ ์„ ๋™์‹œ์— ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • Low Level API - Resilient Distributed Dataset (RDD)์€ ์ŠคํŒŒํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ธฐ๋ณธ์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ RDD๋Š” ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋…ธ๋“œ(์ž‘์—…์ž) ๊ฐ„์— ๋ถ„ํ• ๋œ ์š”์†Œ ๋ชจ์Œ์œผ๋กœ ๋…ธ๋“œ์—์„œ ๋ณ‘๋ ฌ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • image

    • https://www.databricks.com/blog/2015/02/17/introducing-dataframes-in-spark-for-large-scale-data-science.html

    • https://phoenixnap.com/kb/rdd-vs-dataframe-vs-dataset

  • DataFrame

    • image

    • https://www.nvidia.com/ko-kr/ai-data-science/spark-ebook/introduction-spark-processing/#p3-s1

    • Spark SQL ๋ฐ DataFrame API๋Š” Spark SQL์˜ ์ตœ์ ํ™”๋œ ์‹คํ–‰ ์—”์ง„์„ ํ†ตํ•ด ์‚ฌ์šฉ ํŽธ์˜์„ฑ, ๊ณต๊ฐ„ ํšจ์œจ์„ฑ ๋ฐ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

    • ๋ชจ๋“ˆ์‹(์ผ๋ช… ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ)์œผ๋กœ ์‰ฝ๊ฒŒ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ.์ฝ๊ธฐ๊ฐ€ ์‰ฌ์šฐ๋ฉฐ ๋…ผ๋ฆฌ๊ฐ€ ๋ถ„ํ•ด๋˜๊ณ  ์บก์Аํ™”๋ฉ๋‹ˆ๋‹ค.

    • DataFrame์ด Catalyst ์˜ตํ‹ฐ๋งˆ์ด์ €๋ฅผ ํ†ต๊ณผํ•˜์—ฌ Spark SQL ์ฟผ๋ฆฌ์™€ ์œ ์‚ฌํ•œ ์ตœ์ ํ™”๋œ ์‹คํ–‰์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • Spark sql

    • image

    • https://www.nvidia.com/ko-kr/ai-data-science/spark-ebook/spark-sql-dataframes/

    • Spark SQL์€ ํ•„์š”ํ•œ ์—ด๋งŒ ์Šค์บ”ํ•˜๊ณ , ์••์ถ•์„ ์ž๋™์œผ๋กœ ์กฐ์ •ํ•˜๋ฉฐ, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ตœ์†Œํ™”ํ•˜๋ฉฐ, JVM ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”๋œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด ์—ด ๊ธฐ๋ฐ˜ ํ˜•์‹์„ ์‚ฌ์šฉํ•˜์—ฌ DataFrame์„ ์บ์‹œ(dataFrame.cache ํ˜ธ์ถœ ์‹œ)ํ•ฉ๋‹ˆ๋‹ค.

    • ์ปดํŒฉํŠธ, ๋ชจ๋“  ๋…ผ๋ฆฌ๊ฐ€ ํ•จ๊ป˜, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋Š” ๋œ ์‚ฌ์†Œํ•˜์ง€๋งŒ ๋ถˆ๊ฐ€๋Šฅํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.์ฝ๊ธฐ ์‰ฌ์šฐ๋ฉฐ ์•„๋งˆ๋„ ์‰ฝ๊ฒŒ ์žฌ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค

  • DataFrame ์‚ฌ์šฉ์ž๋“ค์€ SparkSQL ์‚ฌ์šฉ์— ๋Œ€ํ•ด ๋ฌด์—‡์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š”์ 

    • ๋•Œ๋กœ๋Š” ๋ณต์žกํ•œ ๋ณ€ํ™˜์˜ ๊ฐ€๋…์„ฑ์ด ๋” ์‰ฝ๊ฒŒ ๋”ฐ๋ฅด๊ณ  SQL๋กœ ๋งˆ์Œ์„ ๊ฐ์Œ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • SparkSQL์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” CTE์™€ ๊ฐ™์€ ๋ฉ‹์ง„ ๊ธฐ๋Šฅ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

    • ์ผ๋ถ€ ๋ณ€ํ™˜์€ SparkSQL์—์„œ ๋” ์‰ฝ๊ณ  ๋” ์งง์€ ์–‘์˜ ์ฝ”๋“œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

  • SparkSQL ์‚ฌ์šฉ์ž๋Š” DataFrame์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š”์ 

    • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ์šฉ์ดํ•จ๊ณผ ์ค‘์š”์„ฑ

    • ์ฝ”๋“œ๋ฅผ ๋” ๋ชจ๋“ˆํ™”ํ•˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ

    • SQL์„ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ๋” ๋‚˜์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์ต์ˆ™ํ•ด์ง€๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    • from pyspark.sql import DataFrame, SparkSession
      import spark.sql.functions as F
      
      def read_sales_data(uri: str = 's3a://sales-data/customer-orders/2021/*') -> DataFrame:
          df = spark.read.parquet(uri)
          return df
      
      def define_product(input_df: DataFrame) -> DataFrame:
          output_df = input_df.withColumn('product', 
                                             F.when(
                                                     F.col('product_id').isin([1,2,3,4]), F.lit('product_one')).otherwise(F.lit('product_two')
                                                   )
                                      )
          return output_df
      
      def agg_sales_by_product(input_df: DataFrame, gb: str = 'product', ag: str = 'order_amount') -> DataFrame:
           output_df = input_df.groupBy(gb).agg(F.sum(F.col(ag).alias('sales'))
           return output_df
      
      
      df = read_sales_data()
      products = define_product(df)
      metrics = agg_sales_by_product(products)
    • from pyspark.sql import DataFrame, SparkSession
      import spark.sql.functions as F
      
      def read_sales_data(uri: str = 's3a://sales-data/customer-orders/2021/*') -> DataFrame:
          df = spark.read.parquet(uri)
          return df
      
      def run_sql(input_df: DataFrame) -> DataFrame:
          input_df.createOrReplaceTempView('tmp_sales')
          df = spark.sql("""
                              SELECT CASE WHEN product_id IS IN (1,2,3,4) THEN 'product_one' ELSE 'product_two' END as product,
                                     SUM(order_amount) as sales
                              FROM tmp_sales
                              GROUP BY CASE WHEN product_id IS IN (1,2,3,4) THEN 'product_one' ELSE 'product_two' END
                         """)
          return df
      
      df = read_sales_data()
      metrics = run_sql(products)

ํ…Œ์ด๋ธ” ํŒŒํ‹ฐ์…”๋‹

  • image

    • https://selectfrom.dev/apache-spark-partitioning-bucketing-3fd350816911

  • ํŒŒํ‹ฐ์…˜์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์—ญํ™”ํ•˜๊ณ  ๋„คํŠธ์›Œํฌ ๋…ธ๋“œ์—์„œ ๋ฐ์ดํ„ฐ ์…”ํ”Œ๋ง์„ ์ค„์—ฌ ๋ณ€ํ™˜ ์ž‘์—…์˜ ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ์ธ ๋„คํŠธ์›Œํฌ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ์ค„์—ฌ ์™„๋ฃŒ ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

  • image

    • https://selectfrom.dev/apache-spark-partitioning-bucketing-3fd350816911

  • ํ…Œ์ด๋ธ” ํŒŒํ‹ฐ์…”๋‹์€ ๋ฐ์ดํ„ฐ์˜ ๋‚ ์งœ ํ•„๋“œ๋ฅผ ๊ฐ™์€ ํ‚ค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฐœ๋ณ„ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ํŒŒ์ผ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • ์ฟผ๋ฆฌ์—์„œ ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ์ž์ฃผ ํ•„ํ„ฐ๋งํ•œ๋‹ค๋ฉด ์ปฌ๋Ÿผ์„ ๊ธฐ์ค€์œผ๋กœ ํŒŒํ‹ฐ์…˜์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • ํŒŒํ‹ฐ์…”๋‹์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ์—์„œ ์ฝ์–ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์–‘์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์–ด ์ฟผ๋ฆฌ๋ฅผ ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํŒŒํ‹ฐ์…”๋‹์„ ํ•  ๋•Œ ๋„ˆ๋ฌด ์ž‘์€ ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•˜๋ฉด ์ž‘์€ ํฌ๊ธฐ์˜ ํŒŒ์ผ์ด ๋Œ€๋Ÿ‰์œผ๋กœ ์ƒ์„ฑ๋  ์ˆ˜ ์žˆ๊ณ  ์ €์žฅ์†Œ ์‹œ์Šคํ…œ์—์„œ ์ „์ฒด ํŒŒ์ผ์˜ ๋ชฉ๋ก์„ ์ฝ์„ ๋•Œ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒํ‹ฐ์…˜์ด๋‚˜ ๋ฒ„์ผ“์œผ๋กœ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ํŒŒ์ผ ์ˆ˜์™€ ์ €์žฅํ•˜๋ ค๋Š” ํŒŒ์ผ ํฌ๊ธฐ๋„ ๊ณ ๋ คํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

    • ์ž‘์€ ํŒŒ์ผ์ด ๋งŽ์€ ๊ฒฝ์šฐ ํŒŒ์ผ ๋ชฉ๋ก ์กฐํšŒ์™€ ํŒŒ์ผ ์ฝ๊ธฐ ๊ณผ์ •์—์„œ ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    • ํŠธ๋ ˆ์ด๋“œ ์˜คํ”„๋ฅผ ๊ฐ์•ˆํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

    • ์ž…๋ ฅ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์ด ์ตœ์†Œ ์ˆ˜์‹ญ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๋„๋ก ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ•˜๋Š”๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฒ„์ผ“ํŒ…

  • image

    • https://selectfrom.dev/apache-spark-partitioning-bucketing-3fd350816911

  • Bucketing ์€ ์ž‘์—… ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” Spark ๋ฐ Hive์˜ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋ฒ„ํ‚ทํŒ… ๋ฒ„ํ‚ท( ํด๋Ÿฌ์Šคํ„ฐ๋ง ์—ด )์—์„œ ๋ฐ์ดํ„ฐ ํŒŒํ‹ฐ์…”๋‹์„ ๊ฒฐ์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์…”ํ”Œ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜ ์ด์ƒ์˜ ๋ฒ„ํ‚ท ์—ด ๊ฐ’์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฏธ๋ฆฌ ์ •์˜๋œ ๋ฒ„ํ‚ท ์ˆ˜์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

  • image

    • https://www.nvidia.com/ko-kr/ai-data-science/spark-ebook/spark-sql-dataframes/

  • ํŒŒ์ผ ๋ถ„ํ•  ๋ฐ ๋ฒ„ํ‚ท์€ Spark SQL์—์„œ ์ผ๋ฐ˜์ ์ธ ์ตœ์ ํ™” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ง‘๊ณ„ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์™œ๊ณก ๋ฐ ๋ฐ์ดํ„ฐ ์ถ•์†Œ๋ฅผ ์ค„์ด๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

  • ๋ถ„ํ•  ๊ฐ€๋Šฅํ•œ ํฌ๋งท์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ํƒœ์Šคํฌ๊ฐ€ ํŒŒ์ผ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ๋™์‹œ์— ์ฝ์„ ์ˆ˜ ์žˆ์Œ

  • ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„์ผ“ํŒ…ํ•˜๋ฉด ์ŠคํŒŒํฌ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์กฐ์ธ์ด๋‚˜ ์ง‘๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์ „ ๋ถ„ํ• (pre-partition)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋‘ ๊ฐœ ํŒŒํ‹ฐ์…˜์— ์น˜์šฐ์น˜์ง€ ์•Š๊ณ  ์ „์ฒด ํŒŒํ‹ฐ์…˜์— ๊ท ๋“ฑํ•˜๊ฒŒ ๋ถ„์‚ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Hive vs Spark

    • image

    • https://selectfrom.dev/apache-spark-partitioning-bucketing-3fd350816911

    • Hive์—์„œ๋Š” ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ํŒŒ์ผ ์ˆ˜๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ๋ฆฌ๋“€์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Spark ๋ฒ„ํ‚ทํŒ…์—๋Š” ๋ฆฌ๋“€์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ž‘์—… ์ˆ˜์— ๋”ฐ๋ผ n๊ฐœ์˜ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • ํŒŒ์ผ ๊ธฐ๋ฐ˜ ์žฅ๊ธฐ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ

    • ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ด๋„ˆ๋ฆฌ ํ˜•ํƒœ๋กœ ์ €์žฅํ•˜๋ ค๋ฉด ๊ตฌ์กฐ์  API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    • CSV ๊ฐ™์€ ํŒŒ์ผ์€ ๊ตฌ์กฐํ™”๋˜์–ด ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ํŒŒ์‹ฑ ์†๋„๊ฐ€ ์•„์ฃผ ๋А๋ฆฌ๊ณ  ์˜ˆ์™ธ ์ƒํ™ฉ์ด ์ž์ฃผ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    • ํŒŒ์ผ€์ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์— ์ปฌ๋Ÿผ ์ง€ํ–ฅ ๋ฐฉ์‹์œผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

    • ์ฟผ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ๋„๋ก ๋ช‡ ๊ฐ€์ง€ ํ†ต๊ณ„๋ฅผ ํ•จ๊ป˜ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์…”ํ”Œ ์„ค์ •

  • image

  • image

    • https://engineering.linkedin.com/blog/2020/introducing-magnet

  • ์ŠคํŒŒํฌ์˜ ์™ธ๋ถ€ ์…”ํ”Œ ์„œ๋น„์Šค๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋จธ์‹ ์—์„œ ์‹คํ–‰๋˜๋Š” ์ต์Šคํํ„ฐ๊ฐ€ ๋ฐ”์œ ์ƒํ™ฉ์—์„œ๋„(์˜ˆ:๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์ˆ˜ํ–‰) ์›๊ฒฉ ๋จธ์‹ ์—์„œ ์…”ํ”Œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํŒŒํ‹ฐ์…˜ ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ์ ์œผ๋ฉด ์†Œ์ˆ˜์˜ ๋…ธ๋“œ๋งŒ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์น˜์šฐ์นจ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ํŒŒํ‹ฐ์…˜ ์ˆ˜๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์œผ๋ฉด ํŒŒํ‹ฐ์…˜์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํƒœ์Šคํฌ๋ฅผ ๋งŽ์ด ์‹คํ–‰ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ถ€ํ•˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

  • ์…”ํ”Œ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ๋Š” ๊ฒฐ๊ณผ ํŒŒํ‹ฐ์…˜๋‹น ์ตœ์†Œ ์ˆ˜์‹ญ ๋ฉ”๊ฐ€๋ฐ”์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ๊ณผ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜

  • ์ŠคํŒŒํฌ ์žก ์‹คํ–‰ ๊ณผ์ • ์ค‘์— ์ต์Šคํํ„ฐ๋‚˜ ๋“œ๋ผ์ด๋ฒ„ ๋จธ์‹ ์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•˜๊ฑฐ๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ์••๋ฐ•(memory pressure)์œผ๋กœ ์ธํ•ด ํƒœ์Šคํฌ๋ฅผ ์™„๋ฃŒํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์ค‘์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ

    • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ์ž์ฃผ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒฝ์šฐ

    • JVM ๋‚ด์—์„œ ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์ด ์ƒ์„ฑ๋˜์–ด ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ์ •๋ฆฌํ•˜๋ฉด์„œ ์‹คํ–‰ ์†๋„๊ฐ€ ๋А๋ ค์ง€๋Š” ๊ฒฝ์šฐ

  • ๊ฐ€๋น„์ง€ ์ปฌ๋ ˆ์…˜์˜ ํŠœ๋‹

    • image

      • https://www.databricks.com/blog/2015/05/28/tuning-java-garbage-collection-for-spark-applications.html

    • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์˜ ๋ฐœ์ƒ ๋นˆ๋„์™€ ์†Œ์š” ์‹œ๊ฐ„์— ๋Œ€ํ•œ ํ†ต๊ณ„๋ฅผ ๋ชจ์œผ๋Š” ๊ฒƒ, spark.executor.extraJavaOptions ์†์„ฑ์— ์ŠคํŒŒํฌ JVM ์˜ต์…˜์œผ๋กœ -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps ๊ฐ’์„ ์ถ”๊ฐ€ํ•ด ํ†ต๊ณ„๋ฅผ ๋ชจ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์†์„ฑ๊ฐ’์„ ์„ค์ •ํ•œ ๋‹ค์Œ ์ŠคํŒŒํฌ ์žก์„ ์‹คํ–‰ํ•˜๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด ๋ฐœ์ƒํ•  ๋•Œ๋งค๋‹ค ์›Œ์ปค์˜ ๋กœ๊ทธ์— ๋ฉ”์‹œ์ง€๊ฐ€ ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

    • ๋กœ๊ทธ๋Š” ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์•„๋‹Œ ์›Œ์ปค ๋…ธ๋“œ์˜ stdout ํŒŒ์ผ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

    • ์ž๋ฐ” ํž™ ๊ณต๊ฐ„์€ Young ์˜์—ญ๊ณผ Old ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆ„์–ด์ง, Young ์˜์—ญ์€ ์ˆ˜๋ช…์ด ์งง์€ ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•˜๊ณ  ๋ฐ˜๋ฉด Old ์˜์—ญ์€ ์˜ค๋ž˜ ์‚ด์•„ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

    • Young ์˜์—ญ์€ Eden, Survivor1, Survivor2 ์„ธ ์˜์—ญ์œผ๋กœ ๋‹ค์‹œ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

    • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์ˆ˜ํ–‰ ์ ˆ์ฐจ

      • Eden ์˜์—ญ์ด ๊ฐ€๋“ ์ฐจ๋ฉด Eden ์˜์—ญ์— ๋Œ€ํ•œ ๋งˆ์ด๋„ˆ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(minor garbage collection)์ด ์‹คํ–‰๋จ, Eden ์˜์—ญ์—์„œ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด์™€ Survivor1 ์˜์—ญ์˜ ๊ฐ์ฒด๋Š” Survivor2 ์˜์—ญ์œผ๋กœ ๋ณต์ œ๋ฉ๋‹ˆ๋‹ค.

      • ๋‘ Survivor ์˜์—ญ์„ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค.

      • ๊ฐ์ฒด๊ฐ€ ์•„์ฃผ ์˜ค๋ž˜๋˜์—ˆ๊ฑฐ๋‚˜ Survivor2 ์˜์—ญ์ด ๊ฐ€๋“ ์ฐจ๋ฉด ๊ฐ์ฒด๋Š” Old ์˜์—ญ์œผ๋กœ ์˜ฎ๊ฒจ์ง‘๋‹ˆ๋‹ค.

      • ๋งˆ์ง€๋ง‰์œผ๋กœ Old ์˜์—ญ์ด ๊ฑฐ์˜ ๊ฐ€๋“ ์ฐจ๋ฉด ํ’€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(full garbage collection)์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ํ’€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ํž™ ๊ณต๊ฐ„์˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์ถ”์ ํ•ด ์ฐธ์กฐ ์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฐ์ฒด๋“ค์„ ์ œ๊ฑฐํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๊ฐ์ฒด๋ฅผ ๋นˆ๊ณณ์œผ๋กœ ์˜ฎ๊ธฐ๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ’€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ๊ฐ€์žฅ ๋А๋ฆฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์—ฐ์‚ฐ์ž…๋‹ˆ๋‹ค.

    • ์ˆ˜๋ช…์ด ๊ธด ์บ์‹œ ๋ฐ์ดํ„ฐ์…‹์„ Old ์˜์—ญ์— ์ €์žฅํ•จ, Young ์˜์—ญ์—์„œ ์ˆ˜๋ช…์ด ์งง์€ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ถฉ๋ถ„ํ•œ ๊ณต๊ฐ„์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

์ŠคํŒŒํฌ ์žก์˜ ์„ฑ๋Šฅ ํŠœ๋‹ ๋ฐฉ๋ฒ•

  • ์†์„ฑ๊ฐ’์„ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์„ ๋ณ€๊ฒฝํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์„ฑ๋Šฅ์„ ๋†’์ž…๋‹ˆ๋‹ค. ์ „์ฒด ์ŠคํŒŒํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์ŠคํŒŒํฌ ์žก์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

  • ๊ฐœ๋ณ„ ์ŠคํŒŒํฌ ์žก, ์Šคํ…Œ์ด์ง€, ํƒœ์Šคํฌ ์„ฑ๋Šฅ ํŠœ๋‹์„ ์‹œ๋„ํ•˜๊ฑฐ๋‚˜ ์ฝ”๋“œ ์„ค๊ณ„๋ฅผ ๋ณ€๊ฒฝํ•ด ์ง์ ‘์ ์œผ๋กœ ์„ฑ๋Šฅ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Œ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŠน์ • ์˜์—ญ์—๋งŒ ์˜ํ–ฅ์„ ์ฃผ๋ฏ€๋กœ ์ „์ฒด ์ŠคํŒŒํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์ŠคํŒŒํฌ ์žก์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋™์  ํ• ๋‹น

  • ์ŠคํŒŒํฌ ์›Œํฌ๋กœ๋“œ์— ๋”ฐ๋ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฐจ์ง€ํ•  ์ž์›์„ ๋™์ ์œผ๋กœ ์กฐ์ ˆํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ž์›์„ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐ˜ํ™˜ํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ๋‹ค์‹œ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • spark.dynamicAllocation.enabled ์†์„ฑ๊ฐ’์„ true๋กœ ์„ค์ •

๋ฐ์ดํ„ฐ ์ง€์—ญ์„ฑ(data locality)

  • image

    • http://www.datascienceassn.org/content/data-locality-hpc-vs-hadoop-vs-spark

  • ๊ธฐ๋ณธ์ ์œผ๋กœ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋ธ”๋ก์„ ๊ตํ™˜ํ•˜์ง€ ์•Š๊ณ  ํŠน์ • ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ๋…ธ๋“œ์—์„œ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์ •ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์ง์ ‘์ ์ธ ์„ฑ๋Šฅ ํ–ฅ์ƒ ๊ธฐ๋ฒ•

  • ๋ณ‘๋ ฌํ™”

    • spark.defaul.parallelism๊ณผ spark.sql.shuffle.partitions์˜ ๊ฐ’์„ ํด๋Ÿฌ์Šคํ„ฐ ์ฝ”์–ด ์ˆ˜์— ๋”ฐ๋ผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    • ์Šคํ…Œ์ด์ง€์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผํ•  ๋ฐ์ดํ„ฐ์–‘์ด ๋งค์šฐ ๋งŽ๋‹ค๋ฉด ํด๋Ÿฌ์Šคํ„ฐ์˜ CPU ์ฝ”์–ด๋‹น ์ตœ์†Œ 2~3๊ฐœ์˜ ํƒœ์Šคํฌ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

  • ํŒŒํ‹ฐ์…˜ ์žฌ๋ถ„๋ฐฐ์™€ ๋ณ‘ํ•ฉ

    • ํŒŒํ‹ฐ์…˜ ์žฌ๋ถ„๋ฐฐ ๊ณผ์ •์€ ์…”ํ”Œ์„ ์ˆ˜๋ฐ˜ํ•จ, ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ๊ฑธ์ณ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ท ๋“ฑํ•˜๊ฒŒ ๋ถ„๋ฐฐ๋˜๋ฏ€๋กœ ์žก์˜ ์ „์ฒด ์‹คํ–‰ ๋‹จ๊ณ„๋ฅผ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

    • ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€๋Šฅํ•œ ํ•œ ์ ์€ ์–‘์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์…”ํ”Œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    • ์…”ํ”Œ ๋Œ€์‹  ๋™์ผ ๋…ธ๋“œ์˜ ํŒŒํ‹ฐ์…˜์„ ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๋Š” coalesce ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•ด DataFrame์ด๋‚˜ RDD์˜ ์ „์ฒด ํŒŒํ‹ฐ์…˜ ์ˆ˜๋ฅผ ๋จผ์ € ์ค„์˜‡์•ผ ํ•จ, ์ด๋ณด๋‹ค ๋А๋ฆฐ repartition ๋ฉ”์„œ๋“œ๋Š” ๋ถ€ํ•˜๋ฅผ ๋ถ„์‚ฐํ•˜๊ธฐ ์œ„ํ•ด ๋„คํŠธ์›Œํฌ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์…”ํ”Œ๋งํ•ฉ๋‹ˆ๋‹ค.

    • ํŒŒํ‹ฐ์…˜ ์žฌ๋ถ„๋ฐฐ๋Š” ์กฐ์ธ์ด๋‚˜ cache ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ ์‹œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

    • ํŒŒํ‹ฐ์…˜ ์žฌ๋ถ„๋ฐฐ ๊ณผ์ •์€ ๋ถ€ํ•˜๋ฅผ ์œ ๋ฐœํ•˜์ง€๋งŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ „์ฒด์ ์ธ ์„ฑ๋Šฅ๊ณผ ์ŠคํŒŒํฌ ์žก์˜ ๋ณ‘๋ ฌ์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ์Œ์„ ๊ธฐ์–ตํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

  • ํ–ฅ์ƒ๋œ ํ•„ํ„ฐ๋ง

  • ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒํ‹ฐ์…”๋‹

    • ์žก์ด ์—ฌ์ „ํžˆ ๋А๋ฆฌ๊ฒŒ ๋™์ž‘ํ•˜๊ฑฐ๋‚˜ ๋ถˆ์•ˆ์ •ํ•˜๋‹ค๋ฉด RDD๋ฅผ ์ด์šฉํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ํŒŒํ‹ฐ์…”๋‹ ๊ธฐ๋ฒ•์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์‚ฌ์šฉ์ž ์ •์˜ ํ•จ์ˆ˜(UDF)

  • ์ž„์‹œ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ(์บ์‹ฑ)

    • image

      • https://livebook.manning.com/book/spark-in-action-with-examples-in-java/16-cache-and-checkpoint-enhancing-spark-s-performances/v-14/185

    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ฐ™์€ ๋ฐ์ดํ„ฐ์…‹์„ ๊ณ„์†ํ•ด์„œ ์žฌ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์บ์‹ฑ์„ ์‚ฌ์šฉํ•ด ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    • ์บ์‹ฑ์€ ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ต์Šคํํ„ฐ ์ „๋ฐ˜์— ๊ฑธ์ณ ๋งŒ๋“ค์–ด์ง„ ์ž„์‹œ ์ €์žฅ์†Œ(๋ฉ”๋ชจ๋ฆฌ๋‚˜ ๋””์Šคํฌ)์— DataFrame, ํ…Œ์ด๋ธ” ๋˜๋Š” RDD๋ฅผ ๋ณด๊ด€ํ•ด ๋น ๋ฅด๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค

    • ์บ์‹ฑ์ด ํ•„์š”ํ•œ ์ƒํ™ฉ : ์ŠคํŒŒํฌ์˜ ๋Œ€ํ™”ํ˜• ์„ธ์…˜์ด๋‚˜ ์Šคํƒ ๋“œ์–ผ๋ก  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํŠน์ • ๋ฐ์ดํ„ฐ์…‹(DataFrame ๋˜๋Š” RDD)์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๋ ค ํ•  ๊ฒฝ์šฐ

    • ์บ์‹ฑ์€ ์ง€์—ฐ ์—ฐ์‚ฐ, ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•ด์•ผ ์บ์‹ฑ์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

    • DF1 = spark.read.format("csv")\
        .option("inferSchema", "true")\
        .option("header","true")\
        .load("/data/flight-data/csv/2015-summary.csv")
      DF2 = DF1.groupBy("DEST_COUNTRY_NAME").count().collect()
      DF3 = DF1.groupBy("ORIGIN_COUNTRY_NAME").count().collect()
      DF4 = DF1.groupBy("count").count().coolect()
      DF1.cache()
      DF1.count()
    • DataFrame์˜ cache ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ŠคํŒŒํฌ๋Š” ์ตœ์ดˆ ์—ฐ์‚ฐ ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ๋‚˜ ๋””์Šคํฌ์— ์ €์žฅํ•จ, ๋‹ค์Œ ์บ์‹ฑ๋œ DataFrame์„ ์‚ฌ์šฉํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์›๋ณธ ํŒŒ์ผ์„ ์ฝ๋Š” ๋Œ€์‹  ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

    • ์บ์‹ฑ์€ ์ง€์—ฐ ์ฒ˜๋ฆฌ, ์ŠคํŒŒํฌ๋Š” DataFrame์— ์•ก์…˜์„ ์‹คํ–‰ํ•˜๋Š” ์‹œ์ ์— ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค.

    • DF2 = DF1.groupBy("DEST_COUNTRY_NAME").count().collect()  
      DF3 = DF1.groupBy("ORIGIN_COUNTRY_NAME").count().collect()
      DF4 = DF1.groupBy("count").count().collect()
    • ์บ์‹ฑ์€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์ ‘๊ทผํ•˜๋Š” ๋ฐ˜๋ณต์ ์ธ ๋จธ์‹ ๋Ÿฌ๋‹ ์›Œํฌ๋กœ๋“œ์—๋„ ๋งค์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.

    • ์ŠคํŒŒํฌ์˜ cache ๋ช…๋ น์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

    • ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๊ฐ€๋“ ์ฐผ๋‹ค๋ฉด ๋ฐ์ดํ„ฐ์…‹์˜ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋งŒ ์บ์‹ฑํ•ฉ๋‹ˆ๋‹ค.

    • ์ •๊ตํ•œ ์ œ์–ด๋ฅผ ์œ„ํ•ด persist ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•จ, persist ๋ฉ”์„œ๋“œ๋Š” ๋ฐ์ดํ„ฐ ์บ์‹œ ์˜์—ญ(๋ฉ”๋ชจ๋ฆฌ, ๋””์Šคํฌ ๋˜๋Š” ๋‘˜ ๋‹ค)์„ ์ง€์ •ํ•˜๋Š” StorageLevel ๊ฐ์ฒด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์กฐ์ธ

    • ๋™๋“ฑ ์กฐ์ธ์€ ์ตœ์ ํ™”ํ•˜๊ธฐ ๊ฐ€์žฅ ์‰ฌ์šฐ๋ฏ€๋กœ ์šฐ์„ ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    • ์กฐ์ธ ์ˆœ์„œ ๋ณ€๊ฒฝ์€ ๋‚ด๋ถ€ ์กฐ์ธ์„ ์‚ฌ์šฉํ•ด ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํšจ๊ณผ๋ฅผ ๋ˆ„๋ฆผ, ์•ˆ์ •์„ฑ๊ณผ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์นดํ…Œ์‹œ์•ˆ ์กฐ์ธ์ด๋‚˜ ์ „์ฒด ์™ธ๋ถ€ ์กฐ์ธ์˜ ์‚ฌ์šฉ์„ ์ตœ๋Œ€ํ•œ ํ”ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • ๋ฐ์ดํ„ฐ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋ฒ„์ผ“ํŒ…ํ•˜๋ฉด ์กฐ์ธ ์ˆ˜ํ–‰ ์‹œ ๊ฑฐ๋Œ€ํ•œ ์–‘์˜ ์…”ํ”Œ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋ฏธ๋ฆฌ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ง‘๊ณ„

    • ์ง‘๊ณ„ ์ „์— ์ถฉ๋ถ„ํžˆ ๋งŽ์€ ์ˆ˜์˜ ํŒŒํ‹ฐ์…˜์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ๋ฐ์ดํ„ฐ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Reference

  • https://www.amazon.com/Spark-Definitive-Guide-Processing-Simple/dp/1491912219

  • https://sparkbyexamples.com/spark/spark-performance-tuning/?amp=1#udf

  • https://mageswaran1989.medium.com/spark-optimizations-for-advanced-users-spark-cheat-sheet-d74464618c20

Last updated