假设我们有以下表:
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
的参数,它有两个值:STATIC
和 DYNAMIC
。默认值是 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)