shell+pythonjava+hive 日志数据切割入库实践经验总结

    科技2023-11-20  93

    这篇文章对前不久做的一个数据切割的小项目做一个总结,会对其中涉及到的一些需要注意的事项进行补充说明。【出于隐私保护需要,文章只给出数据切割的通用流程参考】。

     

    背景:在日常的生产环境中,机器会源源不断产生日志数据,日志内容通常包括【日志路径】,【日志名】,【记录时间】,【字段键值对】等,需要对这部分数据进行整理和提炼,但是在这个过程中,通常会面临下面的情况:

    1.在业务涉及到的场景比较多的情况下,日志类型也随之会很多,字段会更多

    2.业务维护过程中表的字段可能会不断变化

    在海量的日志数据下,上述问题使得人工维护日志信息变得不太现实,因此需要一个自动化的过程来帮助完成上述工作,即数据自动切割入库功能,包括表配置文件生成,数据切割,数据入库,从而实现对海量日志自动化维护,下面进一步介绍。

     

    表配置文件生成

    利用MapReduce遍历日志数据,找出每个日志字段的最大集合,然后生成表-字段文件 conf,接着利用shell脚本自动生成hive建表语句,批量建表。这个步骤可以保证实时追踪到日志字段变化情况并且进行相应的更新,取字段最大集合可以避免部分日志字段缺失导致建表语句字段不完整的情况。需要注意的点:

    1.建表的时候可以根据压缩比,读取性能选择合适的存储格式,常用的有ORCFile,SequenceFile,Textfile。src表一般选择TextFile,ods,dw表一般选择ORCFile。

    2.根据业务需要选择建立内部表或者是外部表

    3.通过shell+hive+crontab配置自动化脚本可以简化工作。

     

    数据切割

    首先根据conf 文件内容获取日志对应的字段,然后利用正则表达式提取对应字段的value值,按照conf文件字段的顺序存储到hdfs文件系统(写入过程根据业务需求做好相应的分区,比如按照日期分区等)。需要注意的点:

    1.日志记录格式不统一/不规范,比如缺少“”,{}符号,json格式和文本格式混合等情况都需要考虑到

    2.关于字符的处理,比如中文,特殊字符这种,一定要检查好是否解析正确,比如python2的版本下,如果不事先对中文字段进行utf-8编码转换则很有可能会解析错误,此外还有日志中本身存在的换行符,制表符这类也可能会对后续切割入库产生影响,所以需要事先排查清楚。

    3.根据特定业务需要加入预处理和后处理函数,而且这类函数应该与通用的切割模块解耦,最好是写到对应业务的conf文件里面,符合插件化思想。

    4.在项目中,需要将不同的日志数据加载到不同的hive表,也就是对每张表需要创建和表名一致的文件夹并将数据写到该文件夹下面。MR默认输出是part-0,part-1这种显然无法满足需要,因此改写了Outputformat的输出格式,使得输出的key(即表名)作为文件夹名,然后将value写入该文件夹下的文件。

    5.MR过程中需要注意设置好Reducer的数量和数据倾斜问题,避免局部Reducer的负担过大,比较简单的做法比如在key前面加上一个随机数,范围为[0,reducer数量)。

    6.MR过程中需要考虑到Map,Reduce任务的效率采用合适的处理方式,比如有时候Map端做预处理可以减小主机之间后续数据传输开销;数据量过大时可以考虑使用多个MR任务级联处理;Hadoop streaming模式下reducer端可以加入数据界限判定逻辑(hadoop streaming默认对map输出进行了shffle和sort,相同key是连在一起的),定期释放资源,防止无效数据大量堆积。

    7.通常hql是隐藏了执行细节的,底层会自动转成MR任务分发执行,但是在hql中涉及到一些比较复杂的处理,需要将底层的一些执行情况考虑进来,比如hql+transformer/自定义UDAF时涉及到多reducer执行时,需要加入distribute by sort by保证程序入参是按key分区排序,同时也需要注意好资源的释放。

     

    数据入库

    加载到hive数据仓库。需要注意的点:

    1.这一步也是根据conf文件生成load hql语句然后导入就可以了

     

    暂时想到这么多,待补充

    Processed: 0.015, SQL: 9