Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 为什么我的拼花地板分区数据比非分区数据慢?_Apache Spark_Parquet - Fatal编程技术网

Apache spark 为什么我的拼花地板分区数据比非分区数据慢?

Apache spark 为什么我的拼花地板分区数据比非分区数据慢?,apache-spark,parquet,Apache Spark,Parquet,我的理解是:如果我将数据划分到一个列上,我将按它进行查询,这样应该会更快。然而,当我尝试它时,它似乎变慢了,为什么 我有一个用户数据框,我尝试对我的yearmonth进行分区,但没有 因此,我有一个数据集按照creation\u yearmonth进行分区 questionsCleanedDf.repartition("creation_yearmonth") \ .write.partitionBy('creation_yearmonth') \ .parquet('wasb:

我的理解是:如果我将数据划分到一个列上,我将按它进行查询,这样应该会更快。然而,当我尝试它时,它似乎变慢了,为什么

我有一个用户数据框,我尝试对我的
yearmonth
进行分区,但没有

因此,我有一个数据集按照
creation\u yearmonth
进行分区

questionsCleanedDf.repartition("creation_yearmonth") \
    .write.partitionBy('creation_yearmonth') \
    .parquet('wasb://.../parquet/questions.parquet')
我还有一个没有分区的房间

questionsCleanedDf \
    .write \
    .parquet('wasb://.../parquet/questions_nopartition.parquet')
然后我尝试从这两个拼花文件创建一个数据框,并运行相同的查询

questionsDf = spark.read.parquet('wasb://.../parquet/questions.parquet')

询问

spark.sql("""
    SELECT * FROM questions
    WHERE creation_yearmonth = 201606
""")
似乎没有分区的一个始终更快,或者有相似的时间(~2-3秒),而分区的一个则稍慢(~3-4秒)

我试着解释一下:

对于分区数据集:

== Physical Plan ==
*FileScan parquet [id#6404,title#6405,tags#6406,owner_user_id#6407,accepted_answer_id#6408,view_count#6409,answer_count#6410,comment_count#6411,creation_date#6412,favorite_count#6413,creation_yearmonth#6414] Batched: false, Format: Parquet, Location: InMemoryFileIndex[wasb://data@cs4225.blob.core.windows.net/parquet/questions.parquet], PartitionCount: 1, PartitionFilters: [isnotnull(creation_yearmonth#6414), (creation_yearmonth#6414 = 201606)], PushedFilters: [], ReadSchema: struct<id:int,title:string,tags:array<string>,owner_user_id:int,accepted_answer_id:int,view_count...

也很奇怪。首先,数据集将日期作为字符串,因此我需要执行如下查询:

spark.sql("""
    SELECT * FROM questions
    WHERE CAST(creation_date AS date) BETWEEN '2017-06-01' AND '2017-07-01'
""").show(20, False)
我以为这会更慢,但事实证明,它的性能最好~1-2秒。为什么呢?我想在这种情况下,它需要投每一行

此处的解释输出:

== Physical Plan ==
*Project [id#6521, title#6522, tags#6523, owner_user_id#6524, accepted_answer_id#6525, view_count#6526, answer_count#6527, comment_count#6528, creation_date#6529, favorite_count#6530]
+- *Filter ((isnotnull(creation_date#6529) && (cast(cast(creation_date#6529 as date) as string) >= 2017-06-01)) && (cast(cast(creation_date#6529 as date) as string) <= 2017-07-01))
   +- *FileScan parquet [id#6521,title#6522,tags#6523,owner_user_id#6524,accepted_answer_id#6525,view_count#6526,answer_count#6527,comment_count#6528,creation_date#6529,favorite_count#6530] Batched: false, Format: Parquet, Location: InMemoryFileIndex[wasb://data@cs4225.blob.core.windows.net/filtered/questions.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(creation_date)], ReadSchema: struct<id:string,title:string,tags:array<string>,owner_user_id:string,accepted_answer_id:string,v...
==物理计划==
*项目[id 6521,标题6522,标签6523,所有者用户id 6524,接受回答id 6525,查看计数6526,回答计数6527,评论计数6528,创建日期6529,喜爱计数6530]

+-*Filter((isnotnull(创建日期6529)和&(cast(创建日期6529作为字符串)>=2017-06-01))和&(cast(创建日期6529作为字符串)过度分区实际上会降低性能:

如果一列只有几行与每个值匹配,则 要处理的目录可能成为限制因素,而数据文件 每个目录中的文件可能太小,无法利用Hadoop 以多兆字节块传输数据的机制

此摘录摘自另一个Hadoop组件的文档,但提供的参数应该对Hadoop堆栈的所有组件都有效


我认为,无论使用何种分区方案,分区的优势都不会明显,直到表的增长速度超过900 MB-s。

您没有说明如何对代码进行基准测试,因此甚至不清楚这些值代表什么。但只要看看与对象存储相结合的范围和差异,我想majori其中有90%的时间花在扫描“文件系统”上而且读取元数据和数据的大小不足以进行有意义的基准测试。@user6910411我使用的是HDInsight/Jupyter笔记本,在那里我似乎无法使用
%time
功能…因此我大致手动计时。关于文件大小,您可能是对的…每个拼花地板文件约为10-60MB。即使没有适当的基准测试,它似乎也会出现问题e一致但意外的性能拼花地板中的总数据集大小只有900MB,如果900对于有用的基准测试来说太低了(8个核心左右足以完全覆盖所有数据)。即使您手动测量时间,也希望知道您测量的内容(
show
在这里没有用处).两种情况下的分区数是多少?(questionsDf.rdd.getNumPartitions()。
spark.sql("""
    SELECT * FROM questions
    WHERE CAST(creation_date AS date) BETWEEN '2017-06-01' AND '2017-07-01'
""").show(20, False)
== Physical Plan ==
*Project [id#6521, title#6522, tags#6523, owner_user_id#6524, accepted_answer_id#6525, view_count#6526, answer_count#6527, comment_count#6528, creation_date#6529, favorite_count#6530]
+- *Filter ((isnotnull(creation_date#6529) && (cast(cast(creation_date#6529 as date) as string) >= 2017-06-01)) && (cast(cast(creation_date#6529 as date) as string) <= 2017-07-01))
   +- *FileScan parquet [id#6521,title#6522,tags#6523,owner_user_id#6524,accepted_answer_id#6525,view_count#6526,answer_count#6527,comment_count#6528,creation_date#6529,favorite_count#6530] Batched: false, Format: Parquet, Location: InMemoryFileIndex[wasb://data@cs4225.blob.core.windows.net/filtered/questions.parquet], PartitionFilters: [], PushedFilters: [IsNotNull(creation_date)], ReadSchema: struct<id:string,title:string,tags:array<string>,owner_user_id:string,accepted_answer_id:string,v...