记一次不成功的拉链表

2019-05-10 02:19:37,565 INFO [AsyncDispatcher event handler] org.apache.hadoop.mapreduce.v2.app.job.impl.TaskAttemptImpl: Diagnostics report from attempt_1556531708937_6923_r_000000_0: Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{},"value":{"_col0":"A904A900-AA07-A0C6-907A-CCC60CBA9AB7","_col1":426.02,"_col2":1,"_col3":426.02,"_col4":429.32,"_col5":0.0,"_col6":"FINISHED","_col7":"2019-04-19 12:13:25.0","_col8":"2019-04-19 00:35:19.0","_col9":22,"_col10":"A8092000-A044-46A9-400A-CB74427979C6","_col11":429.32,"_col12":53.05,"_col13":0.0,"_col14":30,"_col15":"转-凤灵珑-20190419-54413","_col16":0.0,"_col17":3.3,"_col18":"2019-04-19","_col19":"FINISHED","_col20":"2019-04-19 00:35:19.0","_col21":"2019-04-19 14:07:35.0","_col22":"EE31263C-D894-45DA-9220-7288CB84CFD8","_col23":"Y","_col24":"DUE_QUIT","_col25":"N","_col26":"2019-05-08","_col27":"9999-12-31","_col28":"2019-05-08"}}
	at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:265)
	at org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:444)
	at org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392)
	at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:164)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:422)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1920)
	at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row (tag=0) {"key":{},"value":{"_col0":"A904A900-AA07-A0C6-907A-CCC60CBA9AB7","_col1":426.02,"_col2":1,"_col3":426.02,"_col4":429.32,"_col5":0.0,"_col6":"FINISHED","_col7":"2019-04-19 12:13:25.0","_col8":"2019-04-19 00:35:19.0","_col9":22,"_col10":"A8092000-A044-46A9-400A-CB74427979C6","_col11":429.32,"_col12":53.05,"_col13":0.0,"_col14":30,"_col15":"转-凤灵珑-20190419-54413","_col16":0.0,"_col17":3.3,"_col18":"2019-04-19","_col19":"FINISHED","_col20":"2019-04-19 00:35:19.0","_col21":"2019-04-19 14:07:35.0","_col22":"EE31263C-D894-45DA-9220-7288CB84CFD8","_col23":"Y","_col24":"DUE_QUIT","_col25":"N","_col26":"2019-05-08","_col27":"9999-12-31","_col28":"2019-05-08"}}
	at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:253)
	... 7 more
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.IllegalArgumentException: No enum constant parquet.hadoop.metadata.CompressionCodecName.SNAPPY;
	at org.apache.hadoop.hive.ql.exec.FileSinkOperator.createBucketFiles(FileSinkOperator.java:527)
	at org.apache.hadoop.hive.ql.exec.FileSinkOperator.createNewPaths(FileSinkOperator.java:812)
	at org.apache.hadoop.hive.ql.exec.FileSinkOperator.getDynOutPaths(FileSinkOperator.java:919)
	at org.apache.hadoop.hive.ql.exec.FileSinkOperator.processOp(FileSinkOperator.java:666)
	at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:815)
	at org.apache.hadoop.hive.ql.exec.ExtractOperator.processOp(ExtractOperator.java:45)
	at org.apache.hadoop.hive.ql.exec.mr.ExecReducer.reduce(ExecReducer.java:244)

 

报错如上,将parquet作为拉链的底层存储,通过insert overwrite的方式进行拉链,分析原因是以为初始数据导入的时候都在初始分区,这个分区的数据很大,做insert overwrite的时候就是将所有的数据全部读出来,然后关联之后再全部写进去,数据量很大,造成数据很大的倾斜,所以,这里将分区表变成了普通表,然后重新执行拉链,搞定

### Hive 中拉链的具体示例及用法 #### 1. 创建拉链结构 在构建拉链之前,需要定义其基本结构。通常情况下,拉链会包含以下几个字段: - `id`:唯一标识符。 - `start_date`:录生效日期。 - `end_date`:录失效日期(常用特殊值示当前有效,如 '9999-12-31')。 - `data_columns`:存储实际业务数据的列。 以下是创建用户信息拉链的一个例子: ```sql CREATE TABLE dws_user_his ( user_id STRING, name STRING, age INT, start_date DATE, end_date DATE ) PARTITIONED BY (dt STRING); ``` 此用于保存用户的变更历史,并通过 `start_date` 和 `end_date` 来标每一条录的有效时间范围[^3]。 --- #### 2. 初始化拉链 首次加载时,可以从源(ODS )中提取全量数据并将其作为初始版本写入拉链。假设有一个名为 `ods_user_full` 的全量用户,则可以通过如下 SQL 完成初始化: ```sql INSERT OVERWRITE TABLE dws_user_his PARTITION(dt='initial_load') SELECT user_id, name, age, current_date AS start_date, '9999-12-31' AS end_date FROM ods_user_full; ``` 这条语句将所有用户的最新状态导入到拉链中,并设置默认结束时间为远期值[^3]。 --- #### 3. 更新拉链逻辑 当每天新增或修改某些用户的信息时,需基于增量更新(如 `ods_user_update`),调整现有拉链的内容。具体流程分为两步: - **关闭旧录**:对于发生变动的用户 ID,在原拉链中标这些录为已过期(即将它们的 `end_date` 设置为当天日期)。 - **插入新录**:将最新的用户信息追加至拉链,并赋予新的起始时间和未到期标志。 以下是一个完整的更新脚本: ```sql -- Step 1: 关闭旧录 UPDATE dws_user_his SET end_date = CURRENT_DATE WHERE dt = 'latest_partition' AND user_id IN (SELECT DISTINCT user_id FROM ods_user_update); -- Step 2: 插入新录 INSERT INTO dws_user_his PARTITION(dt=CURRENT_DATE) SELECT t.user_id, t.name, t.age, CURRENT_DATE AS start_date, '9999-12-31' AS end_date FROM ods_user_update t; ``` 需要注意的是,如果使用的是 Hive 默认引擎而非支持事务的操作环境,则可能需要用临时中间来模拟上述过程[^3]。 --- #### 4. 查询特定时间点的状态 利用拉链的优势之一是可以轻松查询任意时刻的历史快照。例如,要获取某一天 (`2023-01-01`) 所有的活跃用户列,可执行以下查询: ```sql SELECT * FROM dws_user_his WHERE dt >= '2023-01-01' AND start_date <= '2023-01-01' AND end_date > '2023-01-01'; ``` 该条件筛选出了那些在指定日期范围内有效的录[^1]。 --- #### 5. 处理特殊情况——汇率转换场景下的应用 针对引用提到的汇率拉链案例,可以采用类似的思路实现日连续流水生成。下面展示了一个简单的 UDF 方法辅助处理缺失值的情况: ```java package udf; import org.apache.hadoop.hive.ql.exec.UDF; public class GetNotNull extends UDF { private static String lrkey = null; private static String lrvalue = null; public String evaluate(String key, String value) { if (key.equals(lrkey)) { if (value.isEmpty()) { value = lrvalue; } else { lrvalue = value; } } else { lrkey = key; lrvalue = value; } return value; } } ``` 这个自定义函数能够在遇到重复键但为空值的情况下返回最近一次非空的结果[^2]。 --- ### 注意事项 为了保障数据一致性和准确性,在设计与维护拉链的过程中应特别注意以下几点: - 防止因并发写入引发冲突; - 明确分区策略以便高效管理大规模数据集; - 测试边界条件以验证算法鲁棒性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值