写入Hive表时多个Parquet文件(增量)

时间:2018-12-28 13:44:51

标签: hive pyspark pyspark-sql parquet

具有已分区的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从ORACLE到HIVE进行第一个 LOAD
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

是否可以将值附加到分区下的现有镶木地板文件中,直到达到块大小为止,而不必为每个插入创建较小的文件。

重写整个分区是一种选择,但我不希望这样做

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

为Hive设置了以下属性

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

每天插入仍然无法解决问题。任何可以遵循的替代方法将非常有帮助。

2 个答案:

答案 0 :(得分:1)

据我所知,我们无法为每日分区数据存储单个文件,因为数据将由每天分区的不同零件文件存储。

由于您提到要从Oracle DB导入数据,因此每次都可以从oracle DB导入整个数据并覆盖到HDFS中。这样,您可以维护单个零件文件。

不建议将HDFS用于少量数据。

答案 1 :(得分:0)

对于这种情况,我可以想到以下方法:

方法1:

重新创建Hive表,即在将增量数据加载到 CUSTOMER_PART 表中之后。

  • 使用全部 temp_CUSTOMER_PART 表数据的快照创建 CUSTOMER_PART 表。

  • 运行覆盖最终表 CUSTOMER_PART ,从 temp_CUSTOMER_PART 表中选择

  • 在这种情况下,您将拥有没有小文件的最终表。

  • 注意,您需要确保在创建临时表后没有将新数据插入到 CUSTOMER_PART 表中。


方法2:

使用input_file_name()函数:

  • 检查每个分区中有多少个不同的文件名,然后仅选择每个分区中具有10..etc个文件的分区。

  • 使用这些分区创建temporary table,仅创建选定分区的overwrite the final table

  • 注意,您需要确保在创建临时表后没有将新数据插入到 CUSTOMER_PART 表中,因为将覆盖决赛桌。


方法3:

配置单元(非火花)提供覆盖并选择相同的表。即

insert overwrite table default.t1 partition(partiton_column) 
select * from default.t1; //overwrite and select from same t1 table
  • 如果您按照这种方式进行操作,那么火花作业完成后就需要hive job triggered

  • running overwrite/select相同的表中配置单元将获得锁定,因此,如果有任何正在写入表的作业将等待。

此外: Orc format 将提供concatenate,它将合并小的ORC文件以创建更大的新文件文件。

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