关于Apache Flume FileChannel

这篇文章关于Apache Flume中的File Channel,Apache Flume 是一个分布式,可靠的,高可用的服务,能够有效的收集,聚合,传输海量的日志数据,Flume具有基于流数据的简单灵活的架构,具有鲁棒性,容错性,可靠性机制和许多故障转移和回滚机制。
Flume使用简单可扩展的数据模型,支持在线分析应用程序。
FileChannel是支持并行加密写入多个磁盘的持久化Flume channel.
概述
当使用Flume 时,每个工作流都拥有Source, Channel, and Sink,典型例子是一个webserver通过RPC将事件(events)写入Source(例如:Avro Source),sources又将events写入MemoryChannel,同时HDFS Sink从MemoryChannel消费events,并写入HDFS
关于Apache Flume FileChannel

MemoryChannel提供高吞吐的性能,同时在断电和程序崩溃之后会造成数据丢失。因此需要开发一个持久化的Channel。File Channel的目标是提供一个可靠的高吞吐Channel。File Channel保证当事务被提交后,不会因为一系列程序崩溃或者掉电而造成数据丢失。
值得注意的是,FileChannel本身不会对数据进行任何复制。 因此,它只能与底层磁盘一样可靠。 由于其耐用性而使用FileChannel的用户在购买和配置硬件时应考虑到这一点。 底层磁盘应为RAID,SAN或类似磁盘。
许多系统以少量数据丢失风险换取更高的吞吐量(例如fsync,每隔几秒从内存到磁盘)。 Flume团队决定采用不同的方法实现FileChannel。 Flume是一个事务性系统,多个事件(events)可以是单个事务中实现或者put或者take的操作。 批量大小可用于控制吞吐量。 使用大的批处理容量,Flume可以通过流处理数据,在高吞吐量的情况下而不会丢失数据。 批量处理的大小完全可以由客户端控制。 这对于RDBMS用户比较熟悉。
Flume事务或者包含Puts 操作,或者Takes操作,不同时支持两个操作,同时commit和rollback 也是如此。每个事物transanction都是了Put 和Take方法。Source 调用Put 方法将事件写入Channel,Sinks执行Takes 方法从channel中取数据。
设计
FileChannel除了基于内存队列之外,还基于预写日志WAL。每个事务都根据事务类型(Take或Put)写入WAL,并相应地修改队列。每次提交事务时,都会在相应的文件上调用fsync,以确保数据确实写入磁盘上,并将指向该事件的指针放在队列中。该队列就像任何其他队列一样:它管理尚未被Sink消费的内容。在获取期间,将队列中指针删除。然后直接从WAL读取事件。由于目前可用的RAM量很大,因此从操作系统文件缓存中进行读取非常常见。
程序崩溃后,可以重放WAL以将队列置于崩溃之前的状态,因此已提交的事务不会丢失。重放WAL可能非常耗时,因此队列本身会定期写入磁盘。将队列写入磁盘称为检查点。崩溃后,队列从磁盘加载,然后只有队列保存到磁盘后才提交事务,这大大减少了必须读取的WAL数量。

例如,channel中有两个如下图所示的events。
关于Apache Flume FileChannel

WAL包含三个重要项:事务ID,序列号和事件数据。 每个事务都有一个唯一的事务ID,每个事件都有一个唯一的序列号。 事务id仅用于将事件分组到事务中,而在重放日志时使用序列号。 在上面的示例中,事务id为1,序列号为1,2和3。
当队列保存到磁盘(检查点)时,序列号也会增加并保存。 在重新启动时,首先加载来自磁盘的队列,然后重放序列号大于队列的所有WAL条目。 在检查点操作期间,通道被锁定,因此任何Put或Take操作都不能改变它的状态。 允许在检查点期间修改队列将导致存储在磁盘上的队列的快照不一致。
在上面的示例队列中,在提交事务1之后发生检查点,导致队列中的事件a,事件b被保存到磁盘,同时序列号为4。

然后,事件a在事务2中被taken。
关于Apache Flume FileChannel
如果发生崩溃,则从磁盘读取队列检查点。 请注意,由于检查点发生在事务2之前,因此队列中当前存在事件a和b。 然后读取WAL并应用序列号大于4的任何已提交事务,从而导致从队列中删除“a”(该操作的event是[2,5,Take "a"])。

上述设计不包括两个项目。 在检查点发生时正在进行的Takes和Puts将丢失。 假设在获取“a”之后发生了检查点:
关于Apache Flume FileChannel

如果此时发生崩溃,则在上述设计下,事件“b”将在队列上并且在重放时将重放序列号大于5的任何WAL条目。 将重播事务2的回滚[2,6,Rollback],但不会重放事务2的Taken[2,4,Take "a"]。 因此,“a”不会被放置在队列中,从而导致数据丢失。 Puts也会采用类似的方案。 因此,当发生队列检查点时,也会写出仍在进行中的事务,以便可以适当地解决上述场景。
实现
FileChannel存储在Flume项目的flume-file-channel模块中,包名是org.apache.flume.channel.file。 上面描述的队列的名称为FlumeEventQueue,WAL名称为Log。 队列本身是一个循环数组,由内存映射文件支持,而WAL是一组使用LogFile类及其子类编写和读取的文件。
结论
FileChannel为Flume用户提供了面对硬件,软件和环境故障时的耐用性,同时保持了高吞吐量。 对于耐用性和高吞吐很重要的大多数拓扑而言,推荐使用File Channel。

原文:http://blog.cloudera.com/blog/2012/09/about-apache-flume-filechannel/#comment-18923

猜你喜欢

转载自blog.51cto.com/10120275/2137481