尚硅谷flume笔记整理
前言
感谢尚大学,笔记里的图片都是截取自尚硅谷的课件。这份博客也是自己的学习总结
定义
Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统。Flume 基于流式架构,灵活简单。
为什么用flume
flume可以进行实时的采集,来一条采集一条
最主要就是实时读取数据,传入hdfs进行持久化
配合kafka可以实现日志信息在不同业务中共享
基础架构
source采集数据,sink传输数据,中间的管道就起到一个缓冲器的作用,允许读数据和写数据的速率不同
- Agent 是一个 JVM 进程,它以事件的形式将数据从源头送至目的。
- Source 是负责接收数据到 Flume Agent 的组件
- Sink 不断地轮询 Channel 中的事件且批量地移除它们,并将这些事件批量写入到存储或索引系统、或者被发送到另一个 Flume Agent。
- Channel 是位于 Source 和 Sink 之间的缓冲区。因此,Channel 允许 Source 和 Sink 运作在不同的速率上。Channel 是线程安全的,可以同时处理几个 Source 的写入操作和几个Sink 的读取操作。
source种类
1.7版本之后 taildir source可以做到监听多个实时追加文件,实现断点续传(flume传输数据时突然挂掉了,重启后从上一次挂掉的位置继续传输数据)
Exec source 适用于监控一个实时追加的文件,不能实现断点续传
Spooldir Source适合用于同步新文件,但不适合对实时追加日志的文件进行监听并同步;
文件追加模式的问题
进行追加操作时,flume记录inode(linux文件唯一标识符),绝对路径以及上次读取节点,有一些日志,如hive,过12点会进行文件更名,flume根据iNode值和文件名组合判断这是一个尚未上传的文件,这时会重新上传日志,导致重复的日志信息。
还有一种情况,如果在11.30挂了,第二天才重新启动,那么这半个小时的数据就丢了,因为文件已经更名了
解决
使用logbac框架,直接生成带日期的文件
更改源码:只使用iNode
事务
这里doCommit检查内存队列是否足够合并,不仅检查当前数据是否可以放到内存队列中,还会判断内存队列的数据加上拿去队列(takeList)中的数据是否大于内存队列大小,如果大了,就不能放了。这是为了防止拿去数据出现错误时,或者sink挂了,进行事务回滚时内存队列空间不足的情况
agent内部原理
-
拦截器链对发送的数据进行规则的过滤
-
channel selector选择将数据发送给哪个channel(会有多个channel,channel可以根据业务来创建),默认是replicating即备份,会把一份source发给两个channel,可以选择使用multiplexing(多路复用),需要配合拦截器使用,因为这个是根据数据的头信息配置的东西决定将数据发送给哪个channel
-
一个sink对应一个channel,一个channel可以对应多个sink所以channel通过sinkProcessor决定将数据发送给哪些sink
- default是一个channel只绑定一个sink
- failover 如果sink故障,可以发给另一个sink(这里会给多个sink设置优先级,如果选择的sink挂了,就会让下一个优先级的sink来抓取数据)
- 负载均衡的sink处理器,LoadBalancing,多个sink以轮询的方法抓取channel的数据,如果数据以流式传输,那么最终数据将会分散到多个sink中
- (面试的时候sinkProcessor可以是两个也可以是三个,看面试官怎么认为了,有的人觉得default不算一个)
拓扑结构
复制和多路复用
通过RPC进行agent之间的通信
负载均衡或故障转移
channel数量变多,缓冲能力变强
聚合
这样就可以实现不同服务器上的日志聚合
退避机制
在负载均衡的模式下,会存在退避机制,如果第一个一个sink 没有拉取到数据,就会认为这个sink有损坏,并在1m内不会再使用这个sink,之后如果还没有拉取,就2,4,8。。。直到最大值
轮询
轮询也会有问题,比如轮到3的时候一直有数据,轮到2的时候一直没有数据,因为sink是拉取数据,而不是数据主动传递
根据头信息发送
header表示获取头信息的什么信息,这里state就是key,头信息实际上是一个map
下面.mapping表示如果获取的是CZ,就发送给通道c1,如果是US就发送给c2,c3通道,其他的就发给c4通道
事务
自定义sink有log输出,可以去看一下
首先获取通道,再获取其中的事务,开启事务后可以进行数据抓取,抓取完毕后进行,返回状态。
如果出错,就需要进行事务的回滚,返回backoff的状态
最后都需要进行事务关闭
事务源码
回滚
在takeList中拿最后一个往头部加,保证数据的顺序不出错
数据重复
比如写到hdfs上,已经写了(部分),但是通信出了问题,这时候数据又要被清空(但是hdfs中的数据是不会被清楚的),并重新放到队列里面,这部分数据就会重复
数据丢失
16行开始读数据,读了4行,但是通信错误了,这4行就丢了,因为不会记录读的位置,但是taildir就不会丢。因为他写成功后,才改变pos
空间不足
内存队列一共20个空间,15个被拿去放入takeList,11个正在队列中往里面放,这时候出错了,就没有位置给15个数据进行回滚了
这里会进行判断。提交任务之前提前进行判断
附录
avro是一个轻量级的RPC通信框架,用户客户端和服务端之间的通信,服务端在哪台服务器上启用,就要用这台服务器上面的端口,avro source为服务端。