1.前言
在进行大数据开发过程中,避免不了遇到数据错位的情况,出现数据错位的情况通常处于大数据开发的上游环节,为了保证数据质量需要对Hive表数据进行修复处理,本文由一次真实的Hive数据错位修复经历所启发,在这个基础上总结和扩展数据错位发生场景、数据错位修复思路和修复案例演示demo。
2. 发生数据错位的场景
首先需要清楚以下2个概念:
1.上游数据来源表为不同渠道的数据,如关系型数据库MySQL的数据、网站或应用的埋点数据日志和第三方提供的数据等;
2.下游Hive表在这边主要指的是ODS层的表,即从各个渠道来的数据所抽取到Hive的表。
在将原始数据导入到Hive表的时候可能会发生数据错位,发生错位的场景有以下2种
1.数据来源表的结构发生变化
因为不可避免的原因如业务调整或别的不可控因素,上游数据来源表的结构发生了变化,这种表结构的变化包含了数据来源表字段的增加、删除、修改这3种变化,复杂度依次增加,这些情况都会导致数据错位。
2.数据的分隔符发生变化
还有因为分隔符导致的数据错位,第1种情况是切换数据来源之后数据的分隔符和以前的不一致,第2种情况是某些字段中包含了分隔符,这2种情况都会导致数据错位。
3. 数据修复的思路
我们在上一节已经描述了问题产生的场景,接下来是确定解决问题的思路
3.1 数据来源表结构发生变化情况下的修复思路
在数据来源表结构发生变化的场景中,不管是增删改中的哪一种情况,核心解决思路是通过建立临时表对最新数据进行处理再回填到Hive表完成修复。
3.1.1 数据来源表字段增加
如果Hive表的下游加工需要用到新增的字段,则根据新增字段的位置重新建表,并将历史数据回填到新表,一般情况下新增字段的表结构为在旧表的后面追加新增字段,如果新增字段不在旧表的后面则按照来源表结构新建;如果下游加工用不到新增字段,则建立Hive临时中间表,表结构与数据来源表一致,把需要的数据从Hive临时中间表回填到Hive表。
3.1.2 数据来源表字段删除
如果Hive表的下游加工需要用到删除的字段,则需要提前通知下游评估影响并反馈解决方案;如果下游未使用删除的字段,则新建Hive临时中间表并将数据回填到Hive表中,Hive表结构不变,被删除字段做置空处理。
3.1.3 数据来源表字段修改(字段名称或类型发生变化、数据错位且字段不一致)
数据来源表的字段名称或类型发生变化,如果Hive表的下游加工需要用到修改的字段,则需要提前通知下游评估影响并反馈解决方案;数据来源表的字段发生数据错位且字段不一致这种情况比较复杂,需要先将旧数据与新数据的字段名和几条数据放到同一张Excel表进行比对,再参考完整数据按照旧表字段名来确定新表字段名,尽量保证2种表的共有字段的字段名一致,如果旧表中的字段没有完全体现在新表中,则需要提前通知下游评估影响并反馈解决方案,如果没有使用的话在将Hive临时中间表回填到Hive表的时候将没用到的字段做置空处理。
3.2 数据分割符发生变化情况下的修复思路
切换数据来源之后数据的分隔符前后不一致的情况,在情况允许的情况下可以先对分隔符进行转换,然后上传数据,和上游沟通格式要求。
某些字段中包含了分隔符,如CSV格式文件的部分字段中出现了',' ,这种情况是比较复杂且不合理的,如果还是用英文的逗号的话必然会导致数据错位,这个需要和上游数据提供方共同约定将分隔符改为其他不常用的字符如 ' ' 或其他不会出现在字段内容中的特殊符号。
4. demo
通过一个数据来源表字段修改的案例来了解怎么进行Hive数据错位修复,实际情况有时候会非常复杂,但是思路是一致的。
4.1 查看表结构与新旧数据源
Hive表app.student的表结构
app.student 表结构 |
||
字段英文名 |
字段中文名 |
字段类型 |
no |
学号 |
int |
name |
姓名 |
string |
age |
年龄 |
int |
旧数据来源student.dat ,字段分隔符为 ' '
新数据来源student2.dat ,字段分隔符为 ' '
4.2 比对新旧数据源字段差异
确认新旧数据源的字段差异,最重要的是判断旧数据源的字段在新数据源中是否存在且格式是否一致。
4.3 新建Hive临时中间表
根据新数据来源student2.dat的结构新建Hive临时中间表
app.student_tmp 表结构 |
||
字段英文名 |
字段中文名 |
字段类型 |
no |
学号 |
int |
name |
姓名 |
string |
gender |
性别 |
string |
age |
年龄 |
int |
hobby |
爱好 |
string |
新建Hive临时中间表 app.student_tmp 在建表时指定字段分隔符为 ' ',和数据来源的分隔符一致
CREATE TABLE `app.student_tmp`( `no` int, `name` string, `gender` string, `age` int, `hobby` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' WITH SERDEPROPERTIES ( 'field.delim'=' ', 'serialization.format'=' ');
4.4 加载本地数据到Hive临时中间表
在Hive命令行下执行以上命令将本地数据加载到Hive临时中间表 app.student_tmp 中。
hive> load data local inpath '/home/share/data/student2.dat' into table app.student_tmp;
4.5 回填数据到Hive表
将数据从Hive临时中间表回填到Hive表
hive> insert into table app.student select no,name,age from app.student_tmp;
4.6 检查Hive表数据状态
查看Hive表数据,已经将数据回填到Hive表中。
5.总结
在进行大数据开发过程中,难免会遇到Hive数据错位问题,出现问题的原因包含了数据调研不充分和上下游沟通不到位,问题发生之后先让自己静下来整理思路,然后再进行修复,最终的目标是为了保证数据质量而不影响下游的加工。