数据从kafka到hive(1)

来源:互联网 发布:linux的基本操作 编辑:程序博客网 时间:2024/05/22 06:29

背景

公司的系统是一个对外提供服务的接口,每一次调用日志都需要保存到hive中,以便后期做数据分析。每天的调用量在亿级,日志数据量100G以上,在量级还没有这么大的时候,采取的办法比较原始:直接通过log4j打印到日志文件,然后通过抽数工具同步到hive中,每天凌晨同步前一天的数据。随着量级增大,日志文件越来越大,每天抽数就要抽好几个小时,而且偶尔还由于网络问题等原因失败。

方案

日志数据不能直接发送给hive,这样耦合度太强了。既然说到去耦合,肯定是采用消息管道了,kafka由于其与大数据结合的紧密程度,成为不二选择。所以初步方案是先将日志发送到kafka,再通过其他工具从kafka读到hive表中,在遇到峰值时,即便kafka挂了,也不会影响接口服务。
下一步就是如何将数据从kafka读到hive中,kafka的东家LinkedIn给出了解决方案:camus(https://github.com/linkedin/camus)和gobblin(https://github.com/linkedin/gobblin)。camus在2015年已经停止维护了,gobblin是后续产品,camus功能是是gobblin的一个子集,通过执行mapreduce任务实现从kafka读取数据到HDFS,而gobblin是一个通用的数据提取框架,可以将各种来源的数据同步到HDFS上,包括数据库、FTP、KAFKA等。因为只需要同步kafka数据,所以我们采用了实现相对简单的camus。在测试过程中,同步一个小时的数据(5G以上),大概需要2分钟左右,即便日志量翻10倍,也是可以接受的,当然,抽数时间也不会随数据量增大而线性增长。
只差最后一步了,camus只能把数据读到HDFS,从HDFS到hive是通过shell脚本实现的,shell脚本执行load命令直接将数据搬到hive中。

实施

下载camus代码后,直接用maven编译,生成的jar包在camus-example中。源码里面包含一个camus.properties的配置文件,这里说几个重要的配置项:

#数据目标路径,最终取到的数据在HDFS上的位置etl.destination.path=/user/username/topics#执行信息存放路径,最重要的是上次读取的kafka的offsetetl.execution.base.path=/user/username/exec#消息解码类,camus读到的数据是byte[]格式的,可以在自定义类进行反序列化camus.message.decoder.class=com.linkedin.camus.etl.kafka.coders.SimpleMessageDecoder#要读取的topickafka.whitelist.topics=#时区,这个很重要,因为数据存放是按日期的etl.default.timezone=Asia/Chongqing

将jar包和properties文件放在同一目录下,通过hadoop -jar camus-example-0.1.0-SNAPSHOT-shaded.jar -p camus.properties运行任务。
camus任务执行完毕后再通过脚本将数据load到hive中,脚本内容如下:

date_string=$(date '+%Y/%m/%d/%H') partion=$(date '+%Y-%m-%d_%H')table_name= service_log_tablefilePath="/user/username/topics/hourly/"$date_string"/"hive<<EOFcreate table if not exists $table_name (mapJson STRING, desc STRING,str1 STRING,str2 STRING,str3 STRING) PARTITIONED BY (dt STRING)STORED AS TEXTFILE;load data inpath '$filePath' overwrite into table $table_name partition (dt='$partion');EOF
0 0