欢迎关注大数据技术架构与案例微信公众号:过往记忆大数据
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
过往记忆大数据

Apache Spark 动态分区 OverWrite 问题

Apache Spark 动态分区 OverWrite 问题
如果想及时了解Spark、Hadoop或者HBase相关的文章,欢迎关注微信公众号:iteblog_hadoop

假设我们有以下表:

scala> spark.sql("""CREATE TABLE iteblog_test (name STRING, id int) using orc  PARTITIONED BY (id)""").show(100)

我们往里面插入一些数据:

scala> spark.sql("insert into  table iteblog_test select 'iteblog1', 1").show(100)

scala> spark.sql("insert into  table iteblog_test select 'iteblog2', 2").show(100)

scala> spark.sql("insert into  table iteblog_test select 'iteblog3', 3").show(100)

这时候我们的表有如下数据:

scala> spark.sql("select * from iteblog_test").show(100)
+--------+---+
|    name| id|
+--------+---+
|iteblog1|  1|
|iteblog2|  2|
|iteblog3|  3|
+--------+---+

当我们运行以下语句,我们发现 Spark 把 iteblog_test 表里面的数据全部清除了:

scala> spark.sql("insert overwrite  table iteblog_test select 'iteblog3_new', 3").show(100)
++
||
++
++


scala> spark.sql("select * from iteblog_test").show(100)
+------------+---+
|        name| id|
+------------+---+
|iteblog3_new|  3|
+------------+---+

这是因为当我们往分区表里面 overwrite 数据时,Spark 默认会 truncate 掉所有表的数据,然后再写入新的数据;或者 overwrite 指定分区时,会删除对应分区所有的数据。如果有多个分区,比如分区 a 和分区 b,当执行以下语句:

INSERT OVERWRITE tbl PARTITION (a=1, b)

Spark 默认会清除掉分区 a=1 里面的所有数据,然后再写入新的数据。但是如果我们是从 Hive 过来的用户,这个行为和我们预期的是不一样的。在 Hive 中,上面 SQL 只会覆盖相关分区里面的数据,比如 insert overwrite table iteblog_test select 'iteblog3_new', 3 只会覆盖分区 id=3 里面的数据,其他分区的数据是不会动的。

为了解决这个问题,从 Spark 2.3 开始,Spark 给我们提供了名为 spark.sql.sources.partitionOverwriteMode 的参数,它有两个值:STATICDYNAMIC。默认值是 STATIC,也就是默认会删除所有分区或者部分分区,这个是为了兼容 Spark 2.3 之前的行为。关于这个 ISSUE 可以参见 SPARK-20236,对应的 Patch 为 这里

所以为了达到 Hive 的效果,我们可以设置 spark.sql.sources.partitionOverwriteMode=dynamic,如下:

scala> spark.conf.set("spark.sql.sources.partitionOverwriteMode","dynamic")

之后我们再往 iteblog_test 表插入数据,只有相关分区的数据会被覆盖:

scala> spark.sql("insert overwrite  table iteblog_test select 'iteblog2_new', 2").show(100)
20/08/03 23:32:04 WARN log: Updating partition stats fast for: iteblog_test
20/08/03 23:32:04 WARN log: Updated size to 272
++
||
++
++


scala> spark.sql("select * from iteblog_test").show(100)
+------------+---+
|        name| id|
+------------+---+
|iteblog2_new|  2|
|iteblog3_new|  3|
+------------+---+


scala>
本博客文章除特别声明,全部都是原创!
原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
本文链接: 【Apache Spark 动态分区 OverWrite 问题】(https://www.iteblog.com/archives/2609.html)
喜欢 (4)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!