数据采集实践(二)

问题

消息中间件比如kafka、rockMQ中的消息怎么保存到hdfs等分布式文件系统中?用户的一条行为数据,要历经怎样的跋涉才能展现在一张看是普通的报表上?

背景

基于Flume的二次数据采集与中转。作为数据分析类产品,魔镜面临的第一个问题就是怎么全面、高效、准确地收集用户的行为数据。上一篇文章,我们详细地介绍了JS SDK的工作原理与API说明,知道如何从美的分期应用的前端,通过埋点的方式采集与上报用户的行为数据到Nginx服务器。下面我们来感知一下数据采集模块的整体流程:

这里写图片描述

数据采集@魔镜

笔者忍不住感叹一句,仅仅是用户数据的采集,就真心不容易,借用鲍勃·迪伦的一句话 “一个人要经历多长的旅途 才能成为真正的男人 鸽子要飞跃几重大海 才能在沙滩上安眠 ” … 用户的一条行为数据,要经历怎样曲折的ETL ,才能展现在一张看似普通的报表上啊!现在假设用户的行为数据已经在Nginx服务器上了,怎么收集Nginx上的数据,并发送至hdfs文件上呢?我们当然可以像下面那样(伪代码)自己基于hadoop的mapreduce写一个分布式程序,读取Nginx上本地目录的行为数据,然后直接写到hdfs上来:

in = new FileInputStream(new File(local));//读Ngnix上行为数据
FileSystem fs = FileSystem.get(URI.create(uri), conf);
out = fs.create(new Path(uri), new Progressable() {
                @Override
                public void progress() {
                   // 可在这里进行清洗等工作
                }});
 byte[] buffer = newbyte[1024];int bytesRead = in.read(buffer);
 out.write(buffer, 0, bytesRead);// 写到 hdfs上

但,这样做程序本身不灵活且容错性差 eg、由于网络异常等原因可能造成数据丢失,无法控制数据的发送时间。实际上,我们主要使用一款开源的日志采集组件Flume 来完成数据的二次才集与中转:先通过Flume将数据sink至kafka,然后再从kafka中sink至hdfs。接下来介绍Flume在项目中的实践。

方 案

Flume 简 介

flume是一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统。支持在日志系统中定制各类数据发送方,用于收集数据,同时提供对数据进行简单处理,并写到各种数据接受方(比如文本、HDFS、Hbase等)的能力 。 flume的数据流由事件(Event)贯穿始终。事件是Flume的基本数据单位,它携带日志数据(字节数组形式)并且携带有头信息,这些Event由Agent外部的Source生成,当Source捕获事件后会进行特定的格式化,然后Source会把事件推入(单个或多个)Channel中。你可以把Channel看作是一个缓冲区,它将保存事件直到Sink处理完该事件。Sink负责持久化日志或者把事件推向另一个Source。主要特点:

这里写图片描述

数据流模型

  • 核心概念
    Agent :使用JVM 运行Flume。每台机器运行一个agent,但是可以在一个agent中包含多个sources和sinks。
    Client :生产数据,运行在一个独立的线程。
    Source:从Client收集数据,传递给Channel。
    Sink :从Channel收集数据,运行在一个独立线程。
    Channel :连接 sources 和 sinks ,这个有点像一个队列。
    Events :可以是日志记录、 avro 对象等。

  • 可靠性
    当节点出现故障时,日志能够被传送到其他节点上而不会丢失。Flume提供了三种级别的可靠性保障,从强到弱依次分别为:end-to-end(收到数据agent首先将event写到磁盘上,当数据传送成功后,再删除;如果数据发送失败,可以重新发送。),Store on failure(这也是scribe采用的策略,当数据接收方crash时,将数据写到本地,待恢复后,继续发送),Besteffort(数据发送到接收方后,不会进行确认)。

  • 可恢复性
    还是靠Channel。推荐使用FileChannel,事件持久化在本地文件系统里(性能较差)
      

实 践

这里以采集kafka中的数据并sink至 hdfs 为例加以说明,至于从Nginx采集与sink至kafka部分略。kafka中的数据格式:

kafka中数据举例

flume核心配置文件:

kafka2hdfs_mdf_pro.sources = kafkasource //kafka作为数据源
kafka2hdfs_mdf_pro.channels = fileChannel
kafka2hdfs_mdf_pro.sinks = hdfsSink
#配置sources,即被监听的源目录  
kafka2hdfs_mdf_pro.sources.kafkasource.channels = fileChannel
kafka2hdfs_mdf_pro.sources.kafkasource.type = org.apache.flume.source.kafka.KafkaSource
kafka2hdfs_mdf_pro.sources.kafkasource.bootstrap.servers = 0.0.0.0:0000,0.0.0.0:0000,0.0.0.0:0000
kafka2hdfs_mdf_pro.sources.kafkasource.topic = mdf_prod
#配置sinks,即目的目录:每天生成一个分区
kafka2hdfs_mdf_pro.sinks.hdfsSink.type=hdfs
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.path=/user/hive/qd/web_event/fenqi/part_dt=%Y-%m-%d 
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.filePrefix=mdf_fenqi
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.fileSuffix=.log
kafka2hdfs_mdf_pro.sinks.sink1.hdfs.round = true
# 每隔一小时or当前日志文件达到128M时生成一份日志文件(如果没有数据则不会生成)
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.rollInterval = 3600
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.rollSize = 128000000
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.rollCount = 0
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.batchSize = 1000
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.roundValue = 1
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.roundUnit = minute
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.useLocalTimeStamp = true
kafka2hdfs_mdf_pro.sinks.hdfsSink.channel=fileChannel
kafka2hdfs_mdf_pro.sinks.hdfsSink.hdfs.fileType = DataStream
#channels,通道目录配置:把文件事件持久化到本地硬盘上
kafka2hdfs_mdf_pro.channels.fileChannel.type = file
kafka2hdfs_mdf_pro.channels.fileChannel.checkpointDir=/tmp/flume/checkpoint
kafka2hdfs_mdf_pro.channels.fileChannel.dataDirs=/tmp/flume/datadir

是不是很简洁?不用写代码,配置一下相关参数就行(具体的参数说明,请参看 flume官方文档关于数据源的配置)。
配置完了后,执行:

/bin/flume-ng agent --conf ./conf/ -f conf/flume-conf.properties -Dflume.root.logger=DEBUG,console -n kafka2hdfs_mdf_pro > log.log 2>&1 &

一段时间后,会按天分区,每天多份日志文件:

这里写图片描述

至此,用户的行为数据,终于采集到了 hdfs 上。

总结

本文从应用的角度,介绍了为什么要用 flume及其基本的使用方法。Logstash也是一种与Flume同级别的日志采集组件-事实上,魔镜美的分期数据采集中 Nginx至Kafka部分正是用了Logstash。接下来我们将继续结合魔镜的实际应用,代码级别解读JS SDK、H5端行为数据的格式以及Nginx的配置。

参考

Flume官网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值