有一张离线同步用到的表 源表新增了一个字段,所以对应的ods的表也要相应改变。
这张 表比较特殊,源表数据后端自己维护,只会保留最近几天的数据,对于历史数据是按天分区存放在ods的,所以对于历史数据的查询只能到数仓才行。目前ods的历史数据累计大于3亿多条。
公司一个小伙伴在做的时候,一开始不清楚这一点,然后直接把源表给干掉了,源表其实还是使用的外部表,他也直接把HDFS上的文件直接给删除了,然后重建了新的表。然后重新同步了数据,任务也能成功,但就是历史数据也没啦,呜呜呜~~
这里其实有一个点:如果使用sqoop直接导入数据到ods的分区表,很有可能无法查到对应分区数据的,因为通过直接挪动数据的方式是无法将获取更新到元数据信息里面的,需要使用 MSCK REPAIR TABLE 进行分区修复。
所以我们公司这里的做法一般是 ods 不是分区表,ods文件格式直接用text file,然后到dwd dim 才转换格式为orc 的分区表 ,用SQL对ods的数据处理插入,SQL插入的方式是可以更新到元数据信息的。
我们也有另一种做法是如果你的ODS也想要做分区,也不想要太麻烦,那么就需要用到一张外部表,类似于上面这样,相当于把ODS给前置了,ODS当做dwd dim类似进行处理。
我们用命令hdfs dfs -rm -r 删除某一个文件的时候,其实并没有实际删除,而是把数据移动到了
/user/用户名/.Trash/ 目录下,一般来说会保留6小时,这个保留时间可以在core-site.xml 中配置
我们的大部分数据是放在cos上的,这个其实放哪都一样,我猜主要是cos便宜把
废话有点多,下面正式开始
1.为了保险,我还是拷贝了一份数据hdfs dfs -cp cosn://earth-161546546**/user/hadoop/.Trash/Current/warehouse/ods/ods_database_tablename1644993855109 cosn://earth-161546546**/tmp/liuge/
2.基于拷贝的这份数据创建了一个外部分区表CREATE EXTERNAL TABLE `ods_database_tablename_history`( `id` int, `access` string, `json_extend` string, `extend_column1` string, `extend_column2` string)COMMENT '某系统访问流水归档表'PARTITIonED BY ( `ts_date` string)ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'LOCATION 'cosn://earth-161546546**/tmp/liuge/ods_database_tablename1644993855109'
此时查数据,0条?
这里其实就需要执行一下修复命令即可:
MSCK REPAIR TABLE ods_database_tablename_history;
3.接着,把正确的源表重新创建一下CREATE EXTERNAL TABLE `ods_database_tablename`( `id` int, `access` string, `json_extend` string, `user_id` string)COMMENT '系统访问流水归档表'PARTITIonED BY ( `ts_date` string)ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'LOCATION 'cosn://earth-161546546**//warehouse/ods/ods_database_tablename'
基本是去掉了两个字段,新增一个字段
4.将数据插入插入之前需要进行动态分区参数配置:
# 开启动态分区set hive.exec.dynamic.partition=true; # 设置动态分区模式 。动态分区的模式为strict:表示必须指定至少一个分区为静态分区, nonstrict模式表示允许所有的分区字段都可以使用动态分区。一般需要设置为nonstrictset hive.exec.dynamic.partition.mode=nonstrick;# 在每个执行MR的节点上,最大可以创建多少个动态分区set hive.exec.max.dynamic.partitions.pernode =1000;# 在所有执行MR的节点上,最大一共可以创建多少个动态分区set hive.exec.max.dynamic.partitions =10000;# 整个MR Job中,最大可以创建多少个HDFS文件set hive.exec.max.created.files = 100000;# 当有空分区生成时,是否抛出异常。默认值:falseset hive.error.on.empty.partition=true;
一般来说,配置前4个就可以了,具体大小根据你的数据情况来定即可。
INSERT OVERWRITE TABLE ods_database_tablename partition(ts_date)select id,access,json_extend, null as user_id,ts_datefrom ods_database_tablename_history
注意点:插入语句的写法,partition(ts_date) 里面的分区字段,默认是查询的最后一个字段,如果是多个分区字段,顺序相应的对上就行
至此,如果顺利的话,你的ods_database_tablename 就能查到历史数据了。