具有已分区的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进行第一个 LOADINSERT 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
每天插入仍然无法解决问题。任何可以遵循的替代方法将非常有帮助。
答案 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;