火花缓存的奇怪问题

时间:2018-07-30 17:19:12

标签: apache-spark hadoop dataframe caching

我们正在使用Spark 2.2.0。蜂巢表中有1.5 TB的数据。我们有80个节点群集,其中每个节点大约有512 GB RAM和40个内核。

我正在使用Spark SQL访问此数据。使用普通的Spark SQL(不进行缓存)时,简单的命令(例如,获取特定列值的不同计数)大约需要13秒。但是,当我在缓存表后运行相同的命令时,它花费了超过10分钟的时间。不确定是什么问题?

export SPARK_MAJOR_VERSION=2
spark-shell --master yarn --num-executors 40 --driver-memory 5g --executor-memory 100g --executor-cores 5
spark.conf.set("spark.sql.shuffle.partitions", 10)
val df = spark.sql("select * from analyticalprofiles.customer_v2")
df.createOrReplaceTempView("tmp")
spark.time(spark.sql("select count(distinct(household_number)) from tmp").show())
>> Time taken: 13927 ms



import  org.apache.spark.storage.StorageLevel
val df2 = df.persist(StorageLevel.MEMORY_ONLY)
df2.createOrReplaceTempView("tmp2")
spark.time(spark.sql("select count(distinct(household_number)) from tmp2").show())
>> 1037482 ms ==> FIRST TIME - okay if this is more
spark.time(spark.sql("select count(distinct(household_number)) from tmp2").show())
>> 834740 ms  ==> SECOND TIME - Was expecting much faster execution ???

使用“ spark.catalog.cacheTable(“ tmp”)“进行了相同的尝试,但仍使用缓存查询需要花费更多时间。不知道为什么有人可以帮忙吗?

df2.storageLevel.useMemory
res6: Boolean = true

sc.getPersistentRDDs
res8: scala.collection.Map[Int,org.apache.spark.rdd.RDD[_]] = Map(12 -> In-memory table tmp MapPartitionsRDD[12] at cacheTable at <console>:24)

spark.conf.get("spark.sql.inMemoryColumnarStorage.compressed")
res11: String = true

spark.conf.get("spark.sql.inMemoryColumnarStorage.batchSize")
res12: String = 10000

spark.catalog.isCached("tmp")
res13: Boolean = true

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。

  1. 您可以使用以下公式来增加执行者的数量并减少执行者的内存

      SPARK_EXECUTOR_CORES (--executor-cores) : 5 
    
      Number of Executors (--num-executors) : (number of nodes) *  (number of cores) /(executor cores) -1 (for Application Master) = (80*40)/5 ~ 640-1 = 639
    
      SPARK_EXECUTOR_MEMORY (--executor-memory): Memory/(Number of Executors/Number of Nodes):  512/(639/80) ~ 64 GB
    
  2. 如果要保留数据框,请使用StorageLevel.MEMORY_AND_DISK_SER。如果内存(RAM)已满,它将保存在磁盘中。

希望它对您有帮助。