flume到底会丢数据吗?其可靠性如何?——轻松搞懂Flume事务机制

先给出答案:

需要结合具体使用的source、channel和sink来分析,具体结果可看本文最后一节。

Flume事务

? 一提到事务,我们首先就想到的是MySQL中的事务,事务就是将一批操作做成原子性的,即这一批要么都成功,要么都失败。

? 同样的道理,在flume中也有事务,那么Flume中的事务在哪个地方呢?在Flume中的批量操作又是指什么呢?

  • Flume中的事务存在于哪个位置?

? 在Flume中一共有两个事务,一个是在Source到Channel之间,一个是Channel到Sink之间。在Source到Channel之间的叫put事务,在Channel到Sink之间的叫Take事务

  • 在Flume中两个事务的批量操作指的是什么?

? 从source到channel过程中,数据在flume中会被封装成Event对象,也就是一批event,把这批event放到一个事务中,把这个事务也就是这批event一次性的放入channel中。同理,Take事务的时候,也是把这一批event组成的事务统一拿出来到sink放到HDFS上。

? 接下来我们看下这两个事务具体是怎么实现的:

1、Flume的Put事务

? 事务肯定有的两个特性就是:成功了提交,失败了回滚。

? 我们先考虑Put事务的正常的情况,即任务成功情况。

如图所示:

? 事务开始的时候会调用一个doPut方法,doPut方法将一批数据(多个event)batch data 放在putList中,而这批数据“批”的大小取决于配置的 batch size 的参数的值。而putList的大小取决于配置channel的参数transaction capacity的大小,这个参数的大小就体现在putList上了。(tips:channel的另一个参数capacity指的是channel的容量)。

现在这批数据顺利的放到putList之后,接下来可以调用doCommit方法,把putList中所有的event放到channel中,成功放完之后就清空putList

? 以上是顺利的情况下,那如果事务进行的过程中出问题了怎么解决呢?

第一种问题:数据传输到channel过程出问题
? 在doCommit提交之后,事务在向channel放的过程中,事务容易出问题。比如:sink那边取数据慢,而source这边放数据速度快,就容易造成channel中的数据的积压,这个时候就会造成putList中的数据放不进去。那现在事务出问题了,如何解决呢?

? 通过调用doRollback方法,doRollback方法会进行两项操作:1、将putList清空; 2、抛出channelException异常。这个时候source就会捕捉到doRollback抛出的异常,然后source就会把刚才的一批数据重新采集一下,采集完之后重新走事务的流程。这就是事务的回滚
(putList的数据在向channel发送之前先检查一下channel的容量能否放得下,如果放不下,就一个都不放。)

第二种问题:数据采集过程出问题
? 有这么种场景,source采集数据时候采用的是tailDir source,而我们因为某种原因将监控的目录文件删除,这个时候就会出现问题,同样地,出现问题的解决方式是调用doRollback方法来对事务进行回滚。

2、Flume的Take事务

? Take事务和Put事务很相似。

同样地,我们先不考虑doRollback,先考虑顺利不出问题的情况下事务的完成。

如图所示:

? Take事务同样也有takeList,HDFS sink配置也有一个 batch size,这个参数决定sink从channel取数据的时候一次取多少个,所以这batch size 得小于takeList的大小,而takeList的大小取决于transaction capacity的大小,同样是channel 中的参数。

? Take事务流程:事务开始后,doTake方法会将channel中的event剪切到takeList中,当然,后面接的是HDFS Sink的话,在把channel中的event剪切到takeList中的同时也往写入HDFS的IO缓冲流中放一份event(数据写入HDFS是先写入IO缓冲流然后flush到HDFS)。

? 当takeList中存放了batch size 数量的event之后,就会调用doCommit方法,doCommit方法会做两个操作:1、针对HDFS Sink,手动调用IO流的flush方法,将IO流缓冲区的数据写入到HDFS磁盘中;2、然后直接清空takeList中的数据。

? 以上是顺利的情况下,那如果事务进行的过程中出问题了怎么解决呢?

什么时候最容易出问题呢?——flush到HDFS的时候组容易出问题

? 如:flush到HDFS的时候,可能由于网络原因超时导致数据传输失败,这个时候同样地调用doRollback方法来进行回滚,回滚的时候,由于takeList中还有备份数据,所以将takeList中的数据原封不动地还给channel,这时候就完成了事务的回滚。

? 但是,如果flush到HDFS的时候,数据flush了一半之后出问题了,这意味着已经有一半的数据已经发送到HDFS上面了,现在出了问题,同样需要调用doRollback方法来进行回滚,回滚并没有“一半”之说,它只会把整个takeList中的数据返回给channel,然后继续进行数据的读写。这样开启下一个事务的时候就容易造成数据重复的问题。

? 所以,在某种程度上,flume对数据进行采集传输的时候,它有可能会造成数据的重复,但是其数据不丢失

3、flume传输是否会丢失或重复数据?

? 这个问题需要分情况来看,需要结合具体使用的source、channel和sink来分析。

? 首先,分析source:

? (1)exec source ,后面接 tail -f ,这个数据也是有可能丢的。
? (2)TailDir source ,这个是不会丢数据的,它可以保证数据不丢失。

? 其次,分析sink:

? (1)hdfs sink,数据有可能重复,但是不会丢失。

一般生产过程中,都是使用 TailDir source HDFS sink,所以数据会重复但是不会丢失。

? 最后,分析channel
? 要想数据不丢失的话,还是要用 File channel,而memory channel 在flume挂掉的时候还是有可能造成数据的丢失的。

原文地址:https://www.cnblogs.com/zhqin/p/12231632.html

时间: 2024-10-14 01:46:12

flume到底会丢数据吗?其可靠性如何?——轻松搞懂Flume事务机制的相关文章

UDT协议实现分析——UDT数据收发的可靠性保障

不管是数据的发送还是数据的接收,大体的流程我们基本上是都理了一下,还分析了数据收发过程中用的数据结构,接下来就看一些UDT中数据收发更精细的一些控制. UDT数据收发的可靠性保障 来看一下UDT中数据收发的可靠性保障. 接收包丢失列表CRcvLossList 先来看一下CRcvLossList的定义: class CRcvLossList { public: CRcvLossList(int size = 1024); ~CRcvLossList(); // Functionality: //

MongoDB丢数据问题的分析

坊间有很多传说MongoDB会丢数据.特别是最近有一个InfoQ翻译的Sven的一篇水文(为什么叫做水文?因为里面并没有他自己的原创,只是搜罗了一些网上的博客,炒了些冷饭吃),其中又提到了丢数据的事情.大家知道作为一个数据库来说,数据的持久性基本上是数据库的最低要求了.如果MongoDB真的有那么糟糕的数据安全问题,它早就在技术选择众多的今天被无情地淘汰掉了.那么真相到底如何呢? 实事求是地来说,MongoDB确实在其发展的过程中,有一些数据持久化的问题没有处理好,特别是一些默认值的选定上.大部

利用Flume将MySQL表数据准实时抽取到HDFS

转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取从MySQL数据库增量抽取数据到HDFS,然后用HAWQ的外部表进行访问.这种方式只需要很少量的配置即可完成数据抽取任务,但缺点同样明显,那就是实时性.Sqoop使用MapReduce读写数据,而MapReduce是为了批处理场景设计的,目标是大吞吐量,并不太关心低延时问题.就像实验中所做的,每天定

mysql recovery 1 (允许停机,不许丢数据)

1.备份策略: 1)按天备份: 优点:恢复时间短,维护成本低 缺点:占用空间大,占用资源多(比如说老是要锁表) 2)按周备份: 优点:占用空间小,资源占用低 缺点:维护成本大 2.增量恢复的场景 1)数据库迁移,或者跨机房灾备. 2)增加从库. 3)认为操作失误,从库也没办法. 3.案例(可以停机,但是不能丢数据) 1)增量,全备开启 [[email protected] ~]# grep log-bin /etc/my.cnf log-bin=mysql-bin mysqldump -uroo

2016年大数据Spark“蘑菇云”行动之spark streaming消费flume采集的kafka数据Directf方式

王家林老师的课程:2016年大数据Spark"蘑菇云"行动之spark streaming消费flume采集的kafka数据Directf方式作业.     一.基本背景 Spark-Streaming获取kafka数据的两种方式Receiver与Direct的方式,本文介绍Direct的方式.具体的流程是这样的: 1.Direct方式是直接连接到kafka的节点上获取数据了. 2.基于Direct的方式:周期性地查询Kafka,来获得每个topic+partition的最新的offs

flume学习(三):flume将log4j日志数据写入到hdfs(转)

原文链接:flume学习(三):flume将log4j日志数据写入到hdfs 在第一篇文章中我们是将log4j的日志输出到了agent的日志文件当中.配置文件如下: [plain] view plaincopy tier1.sources=source1 tier1.channels=channel1 tier1.sinks=sink1 tier1.sources.source1.type=avro tier1.sources.source1.bind=0.0.0.0 tier1.sources

Mysql丢数据及主从数据不一致的场景

Mysql丢数据及主从数据不一致的场景 随着对MySQL的学习,发现了MySQL的很多问题,最重要的就是丢数据的问题.对于丢数据问题,我们应该了解丢数据的场景,这样在以后的学习中多考虑如何去避免及解决这些问题. 1.MySQL数据库层丢数据场景   本节我们主要介绍一下在存储引擎层上是如何会丢数据的. 1.1.InnoDB丢数据   InnoDB支持事务,同Oracle类似,事务提交需要写redo.undo.采用日志先行的策略,将数据的变更在内存中完成,并且将事务记录成redo,顺序的写入red

一个高效的数据分页的存储过程 可以轻松应付百万数据

一个高效的数据分页的存储过程 可以轻松应付百万数据 CREATE PROCEDURE pageTest --用于翻页的测试--需要把排序字段放在第一列 (@FirstID nvarchar(20)=null, --当前页面里的第一条记录的排序字段的值@LastID nvarchar(20)=null, --当前页面里的最后一条记录的排序字段的值@isNext bit=null, --true 1 :下一页:false 0:上一页@allCount int output, --返回总记录数@pag

抽象类和接口你到底搞懂了吗?

http://download.csdn.net/detail/w1025508785/7598195 抽象类和接口你到底搞懂了吗?