写入配置单元表时有多个Parquet文件(增量)

u5i3ibmn  于 2021-06-27  发布在  Hive
关注(0)|答案(2)|浏览(410)

有一个分区的Hive表

CREATE EXTERNAL TABLE IF NOT EXISTS CUSTOMER_PART ( 
  NAME string ,
  AGE int ,
  YEAR INT)
  PARTITIONED BY (CUSTOMER_ID decimal(15,0))
  STORED AS PARQUET LOCATION 'HDFS LOCATION'

第一次加载是通过pyspark使用

INSERT OVERWRITE TABLE CUSTOMER_PART PARTITION (CUSTOMER_ID) SELECT NAME, AGE, YEAR, CUSTOMER_ID FROM CUSTOMER;

它工作正常,并在运行期间动态创建分区。现在开始每天增量加载数据,为分区下的单个记录创建单个文件。

INSERT INTO TABLE CUSTOMER_PART PARTITION (CUSTOMER_ID = 3) SELECT NAME, AGE, YEAR FROM CUSTOMER WHERE CUSTOMER_ID = 3; --Assume this gives me the latest record in the database

是否有可能将值附加到分区下的现有Parquet文件中,直到它达到块大小,而不必为每个插入创建较小的文件。
重写整个分区是一种选择,但我不希望这样做

INSERT OVERWRITE TABLE CUSTOMER_PART PARTITION (CUSTOMER_ID = 3) SELECT NAME, AGE, YEAR FROM CUSTOMER WHERE CUSTOMER_ID = 3;

为配置单元设置以下属性

set hive.execution.engine=tez; -- TEZ execution engine
set hive.merge.tezfiles=true; -- Notifying that merge step is required
set hive.merge.smallfiles.avgsize=128000000; --128MB
set hive.merge.size.per.task=128000000; -- 128MB

这对日常插入仍然没有帮助。任何可以采用的替代方法都会非常有用。

sbtkgmzw

sbtkgmzw1#

我可以为这个案子想出以下方法:
方法1:
重新创建配置单元表,即在将增量数据加载到 CUSTOMER_PART table。
创建 temp_CUSTOMER_PART 包含的整个快照的表 CUSTOMER_PART 表数据。
运行覆盖最终表 CUSTOMER_PART 从中选择 temp_CUSTOMER_PART table
在这种情况下,您将有一个没有小文件的最终表。
注意:您需要确保没有新数据插入到 CUSTOMER_PART 创建临时表之后的表。
方法2:
使用input\u file\u name()函数:
检查每个分区中有多少个不同的文件名,然后只选择具有多个文件名的分区 10..etc 每个分区中的文件。
创建 temporary table 用这些隔板和 overwrite the final table 只有选定的分区。
注意:您需要确保没有新数据插入到 CUSTOMER_PART 创建临时表之后的表,因为我们将覆盖最终的表。
方法3:
hive(不是spark)提供覆盖和选择相同的表

insert overwrite table default.t1 partition(partiton_column) 
select * from default.t1; //overwrite and select from same t1 table

如果你沿着这条路走,那么就需要 hive job triggered 一旦你的Spark工作完成。
Hive将在 running overwrite/select 相同的表,因此如果有任何正在写入表的作业将等待。
此外: Orc format 将提供连接,将合并小兽人文件,以创建一个新的更大的文件。

alter table <db_name>.<orc_table_name> [partition_column="val"] concatenate;
dauxcl2d

dauxcl2d2#

据我所知,我们不能存储每日分区数据的单一文件,因为数据将存储在不同的部分文件为每一天的分区。
因为您提到要从oracledb导入数据,所以每次都可以从oracledb导入整个数据并覆盖到hdfs中。这样就可以维护单个零件文件。
对于少量数据,也不建议使用hdfs。

相关问题