背景
五月份招聘企业团队开发了企业字典项目。基于对业务场景的分析,存储选型中采用了WTable。项目开发完毕后核心表数据大约有1.8亿左右,为了满足产品、运营同学对企业字典数据的盘点、运营需求,需要建立多张字典Hive表,将字典数据导入Hive表用于统计分析。
目前通过58dp平台可较为方便的对源自mysql或hdfs日志导入Hive表,可是WTable如何导入Hive还没有直接方式。几番打探后没有找到可拿来参考的案例,已知的WTable导入Hive是通过冗余的mysql表来实现,虽然这个实现比较简单,可是多申请与使用了一个mysql,不仅没有节约存储资源,反而多了一个WTable 与mysql数据一致性的问题。于是决定摸索一条WTable直接导入Hive表之路。
![baf36f67f87ddce2648467fcb8162238.png](https://i-blog.csdnimg.cn/blog_migrate/94c33ed0f248da893c040917fc447dbc.jpeg)
三步骤
通过实践后WTable直接导入Hive表可行,主要分为如下三个步骤:
- 执行WTable Dump服务
- 运行MR任务解压缩
- 执行Hive脚本添加表分区
![39442cb1b11808a4f215392be3a9194e.png](https://i-blog.csdnimg.cn/blog_migrate/6c3c77f950fbd9bdfddf45777039adc8.jpeg)
以企业字典1.8亿数据为例:
WTable dump服务运行至输出压缩的hdfs文件大约耗时45分钟--2个小时,如下是最近两次不同时间段运行的起始时间与结束时间
![5a88bea5eb4b617e2c727c918872193f.png](https://i-blog.csdnimg.cn/blog_migrate/e148450ee40951d4497f0e9b53caafbe.jpeg)
自定义MR解压输出任务耗时,1--3小时不等时间跳动范围比较大
![c1991480fd43001ad3d7fb4b927da1e7.png](https://i-blog.csdnimg.cn/blog_migrate/8333687804e66e252c399255df3fdc93.jpeg)
解压后文件大小
![5ec0d4f5a6242cdfe2ed135cf00cf6c8.png](https://i-blog.csdnimg.cn/blog_migrate/f639177d738738c3d0cd324d7256e0fc.jpeg)
Hive表数据总量
![8bddd7317f21eac94065e762bfe18640.png](https://i-blog.csdnimg.cn/blog_migrate/4b1debc6312bbf219adefd9d814171d5.jpeg)
基于现有条件导入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入口类
![81aefe38265a2c7a677387c747638b2b.png](https://i-blog.csdnimg.cn/blog_migrate/c9f2d5619870c1c122b212e0125a5349.jpeg)
代码解读:
WTBFileInputFormat
![69e8b7fac6cb9972401b0636c92d9f54.png](https://i-blog.csdnimg.cn/blog_migrate/f4aef2d9f67980bc85e33c4485e60371.jpeg)
isSplitable 须返回fasle,由于输入文件是特定的压缩格式,因此需要指定输入文件不可合并处理
createRecordReader 需要实现读取压缩文件方法,这里需要继承且实现RecordReader类的方法
WTBFileReader extends RecordReader
![07f7eb02769eb7e95111f76b0c3d92ef.png](https://i-blog.csdnimg.cn/blog_migrate/1ad7c78a15f6da8389f6757c736fc14a.jpeg)
NullWritable, BytesWritable
由于主要处理的是特定压缩文件格式的内容,所以这里把输出Key指定为NullWritable类型,Value指定为BytesWritable类型,这是为了便于之后对压缩数据解压缩处理;其中箭头是重点需要关注的部分,nextKeyValue 虽然该方法调用一次即可以处理完整个压缩文件,实际中直接返回false后,导致后续mapper也不再调用;BytesWritable 返回值一定要重新实例化,不能使用set此方法将导致数组长度发生变化,之后解压缩导致数据错误,务必确保数组长度一定与读取压缩文件完全一致。
BytesWritable的set方法实现:
![70d9b46031e2739016b987a2c4a28989.png](https://i-blog.csdnimg.cn/blog_migrate/bb104fba6f7fa095fa3db23bfa77c977.jpeg)
WTBEnterpriseDictMapper
mapperclass实现对压缩文件数据的解压,这里主要负责实现解压缩算法,并按照指定格式输出,mapper的输入与输出类型都指定为Text,其中OutKey输出实际上为字典表的主键,OutValue为要导入hive的表字段并且按照指定分割符,如分隔符处理为一行数据
![8e0071256f5378ca8d36a88c543bdebb.png](https://i-blog.csdnimg.cn/blog_migrate/4f73a0aa3e1cceaf575b9747cad1d926.jpeg)
mapper输入key value 对应 WTBFileInputFormat的输出类型 NullWritable, BytesWritable
![3dc789a1603f935ac496a15510ffd4e8.png](https://i-blog.csdnimg.cn/blog_migrate/45289e7df4406b4b68c491bfbb232dc7.jpeg)
这里key等于字典数据id,value为格式化处理的行字段
![432fad6a16b3344521755bc045f10d08.png](https://i-blog.csdnimg.cn/blog_migrate/ad8382e1383112293dfadd9f2d1fdbbe.jpeg)
WTBReduce
ReducerClass这里不需要特别处理
![0a340ea7e56e4b7e88e2af29c264e805.png](https://i-blog.csdnimg.cn/blog_migrate/3f9c1acec08ee506ad26e7886337b0aa.jpeg)
TextOutputFormat
OutputFormatClass的输出格式指定为 TextOutputFormat;这里需要说明下如果需要修改分割符请在config修改如下:
conf.set("mapreduce.output.textoutputformat.separator