WTable数据导入Hive三步曲
背景
五月份招聘企业团队开发了企业字典项目。基于对业务场景的分析,存储选型中采用了WTable。项目开发完毕后核心表数据大约有1.8亿左右,为了满足产品、运营同学对企业字典数据的盘点、运营需求,需要建立多张字典Hive表,将字典数据导入Hive表用于统计分析。
目前通过58dp平台可较为方便的对源自mysql或hdfs日志导入Hive表,可是WTable如何导入Hive还没有直接方式。几番打探后没有找到可拿来参考的案例,已知的WTable导入Hive是通过冗余的mysql表来实现,虽然这个实现比较简单,可是多申请与使用了一个mysql,不仅没有节约存储资源,反而多了一个WTable 与mysql数据一致性的问题。于是决定摸索一条WTable直接导入Hive表之路。
三步骤
通过实践后WTable直接导入Hive表可行,主要分为如下三个步骤:
-
执行WTable Dump服务
-
运行MR任务解压缩
-
执行Hive脚本添加表分区
以企业字典1.8亿数据为例:
WTable dump服务运行至输出压缩的hdfs文件大约耗时45分钟–2个小时,如下是最近两次不同时间段运行的起始时间与结束时间
自定义MR解压输出任务耗时,1–3小时不等时间跳动范围比较大
解压后文件大小
Hive表数据总量
基于现有条件导入Hive表,其处理过程重点在于mr任务,如何解压WTable dump的压缩数据,并输出既定格式的hdfs文件。
详细过程
-
WTable Dump
WTable除了dump接口外,还提供了dump服务,它可以将数据按照特定的格式保存到hdfs中。使用dump服务的基本流程为:发送dump请求。dump服务提供的接口使用http协议。详见文末参考资料:WTable Dump服务。
-
自定义MR任务
多数同学对基于文本的MR处理比较熟悉,可是为了实现对WTable dump出来的文件解压缩,其关键点在于实现自定义输入格式,非对文本数据的处理。
处理原则:
1.由于dump文件属于特定的压缩格式,因此不可对压缩文件分割处理
2.实现自定义输入,运行解压缩算法,对数据还原且按照指定格式输出
Main入口类
代码解读:
WTBFileInputFormat
isSplitable 须返回fasle,由于输入文件是特定的压缩格式,因此需要指定输入文件不可合并处理
createRecordReader 需要实现读取压缩文件方法,这里需要继承且实现RecordReader类的方法
WTBFileReader extends RecordReader
NullWritable, BytesWritable
由于主要处理的是特定压缩文件格式的内容,所以这里把输出Key指定为NullWritable类型,Value指定为BytesWritable类型,这是为了便于之后对压缩数据解压缩处理;其中箭头是重点需要关注的部分,nextKeyValue 虽然该方法调用一次即可以处理完整个压缩文件,实际中直接返回false后,导致后续mapper也不再调用;BytesWritable 返回值一定要重新实例化,不能使用set此方法将导致数组长度发生变化,之后解压缩导致数据错误,务必确保数组长度一定与读取压缩文件完全一致。
BytesWritable的set方法实现:
WTBEnterpriseDictMapper
mapperclass实现对压缩文件数据的解压,这里主要负责实现解压缩算法,并按照指定格式输出,mapper的输入与输出类型都指定为Text,其中OutKey输出实际上为字典表的主键,OutValue为要导入hive的表字段并且按照指定分割符,如\t分隔符处理为一行数据
mapper输入key value 对应 WTBFileInputFormat的输出类型 NullWritable, BytesWritable
这里key等于字典数据id,value为格式化处理的行字段
WTBReduce
ReducerClass这里不需要特别处理
TextOutputFormat
OutputFormatClass的输出格式指定为 TextOutputFormat;这里需要说明下如果需要修改分割符请在config修改如下:
conf.set(“mapreduce.output.textoutputformat.separator”,”\1″);
目前公司所使用的hadoop2.3 TextOutputFormat 默认输出分割为\t;在实际使用中招聘有通过\1 来进行分割
通过实践后发现 如果修改config分隔符替换为 \1 导致mr任务运行失败,具体什么原因目前还不知道,如下错误截图:
由于mapreduce会将程序的输出按照key/velue的形式组织,而且key/value之间需要有一个分隔符,方便程序区分。因此在输出value时候不要重复添加id(或者理解为hive表首列)
如下是key为第一列通过\t分割,二三列通过\1分割,这将导致hive表字段对应出现问题
建议大家使用\t分割,避免未知的分隔符导致mr执行错误
-
Hive脚本创建分区表
创建hive表,请严格对照hdfs 输出分割符
这里不再赘述,参照58dp帮助手册。
未来优化,脚本完全自动化
由于wtable dump 是通过http异步接口实现,所以什么时候dump完毕,依赖主动监测,与mr任务启动存在衔接问题,mr执行时需要获取dump服务生成的hdfs的文件目录,且需要保证dump任务成功执行完毕,才能开启mr解压任务。
参考资料
WTable Dump服务:
http://wiki.58corp.com/index.php?title=WTable#Dump.E6.8E.A5.E5.8F.A3
MR脚本源码地址:
http://igit.58corp.com/enterprise_group/mr/entdict-mr.git
MapReduce常见问题:
http://wiki.58corp.com/index.php?title=MapReduce%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95
欢迎大家的意见与建议请@乔海舟@赵昆鹏