运行Hive脚本时遇Protocol message end-group tag不匹配错误求解析
背景说明
你运行数月的关联两张表的Hive SQL脚本(如下)近5-6天持续失败,报错为:
java.lang.RuntimeException: java.io.IOException: com.google.protobuf.InvalidProtocolBufferException: Protocol message end-group tag did not match expected tag
SQL脚本:
select distinct cast(date_format(A.created_ts ,'yyyy-MM-dd HH:mm:ss') as char(20)) as created_date, A.c360_id,A.external_id,A.business_name,A.first_name,A.last_name,A.email,A.phone, A.address_id,A.address_type,A.Address_Line1,A.Address_Line2,A.Address_Line3,A.city, A.state,A.postal_code,A.country,A.created_ts,A.ext_org_code, cast(' ' as char(01)) as guild_created_ts, cast(' ' as char(01)) as guild_last_modified_ts, cast(' ' as char(01)) as residence_created_ts, cast(' ' as char(01)) as residence_last_modified_ts, current_timestamp() as transaction_date, cast('YES' as char(03)) as Opt_out_flag from( select c360_id,acxiom_opt_out_deceased_flag,deceased_data_suppression_flag,large_prison_suppression_flag from SA where (acxiom_opt_out_deceased_flag is true or deceased_data_suppression_flag is true or large_prison_suppression_flag is true) and (created_ts > (select current_run_time from delta_run_time where job_type = 'customer') or last_modified_ts > (select current_run_time from delta_run_time where job_type = 'customer')) ) s join( select *,row_number() over (partition by c360_id order by edsr_key desc) as rank from SE ) A on A.c360_id = s.c360_id where rank =1 and A.ext_org_code = '30'
错误触发场景
这个错误属于Protobuf序列化/反序列化异常,结合生产环境运行情况,常见触发原因如下:
底层存储文件损坏:
任务依赖的SA、SE或delta_run_time表对应的HDFS文件出现损坏,比如节点故障导致块丢失、写入任务中途中断留下残缺文件。当Hive读取这些文件时,Protobuf解析器无法识别正确的数据结构标签,就会抛出标签不匹配的错误。表结构变更不兼容:
近几天如果对SA、SE表做了结构修改(新增字段、修改字段类型等),但未处理新旧数据的兼容性。尤其是使用ORC、Parquet这类依赖Protobuf序列化的列式存储格式时,旧数据的序列化格式和新结构不匹配,读取时就会触发解析错误。集群组件版本或依赖冲突:
若近几天升级了Hive、Spark或Protobuf相关依赖库,新旧版本的序列化规则不一致。比如旧版本写入的数据用Protobuf 2.x格式,新版本用Protobuf 3.x解析,就会出现标签不匹配问题。增量分区数据异常:
任务通过created_ts/last_modified_ts过滤增量数据,近几天新增的分区数据可能存在格式错误。比如上游写入任务生成的分区文件不符合Protobuf规范,或者分区元数据与实际文件内容不匹配,导致读取解析失败。并发写入冲突:
多个任务同时对SA、SE表的同一分区写入,可能导致文件写入不完整或数据结构混乱。这种情况下生成的文件在读取时,Protobuf解析器无法正确识别数据结束标签,从而抛出错误。
内容的提问来源于stack exchange,提问作者Jangyasmita Priyadarshini

