flume jvm调优_Flume FileChannel优化(扩展)实践指南

本文系微博运维数据平台(DIP)在Flume方面的优化扩展经验总结,在使用Flume FileChannel的场景下将吞吐率由10M/s~20M/s提升至80M/s~90M/s,分为四个部分进行介绍:

应用场景

Flume实例架构

Flume调试及优化扩展

Flume Todo

生产环境部署

1. 应用场景

我们的应用场景是一个典型的实时数据传输(接收)过程,架构图如下:

包括三个组件:

(1)ServiceServer ScribeClient:业务产生的日志以“Log”的形式写入业务部署服务器的本地磁盘,然后通过ScribeClient传输至我们的Flume集群;

(2)Flume:使用多个Flume实例构建Flume集群,通过动态域名、VIP对外提供服务;其中,每一个Flume实例使用ScribeSource接收ServcieServer ScribeClient传输过来的日志数据,然后使用FileChannel将ScribeSource接收过来的数据以“事务”的形式持久化至本地磁盘,最近通过KafkaSink将FileChannle中的数据输出至Kafka集群;

(3)Kakfa:Kafka集群接收Flume集群传输过来的日志数据,用于后续的实时计算;

可以看出,以上整个过程就是日志实时写入Kafka集群的过程,有几点需要特殊说明:

(1)既然是实时数据传输,为什么不直接通过Kafka Producer API(或基于此实现的开源组件)将日志数据直接写入Kafka集群,而是使用Scribe间接传输数据?

假设我们有一个Web服务,需要将Web的访问日志实时写入Kafka集群,这个可以通过Log4j扩展实现(不确定是否已有开源组件支持),这种方式数据实时性较强,但是Kafka集群运行过程中一旦出现异常(如:网络流量波动)会直接影响该Web服务的运行状态,进而影响线上业务,因此不能使用这种直接传输的方式;

Scribe可以在数据接收服务(这里特指Flume集群,也可以是Kafka)出现异常或不可用的情况下,暂时将数据缓存至本地磁盘,待数据接收服务恢复之后,继续数据传输;虽然数据传输的实时性有所损耗,但整个数据传输过程更加可靠,而且避免了数据传输对线上服务的影响,因此使用这种间接传输的方式。

(2)Flume为什么使用FileChannel,而不使用吞吐率更高的MemoryChannel?

MemoryChannel使用内存存储事务,吞吐率极高,但基于内存的事务实现模式在Flume部署服务器宕机或Flume实例异常终止的情况下,所有存储在内存中的日志数据将全部丢失;另外,内存空间受限于RAM和JVM的约束,数据传输量波动(如数据量猛增)的情况下可能会引发异常;

FileChannel使用基于本地磁盘的事务实现模式,即使出现Flume部署服务器宕机或Flume实例异常终止的情况,因为接收到的日志数据都以事务的形式持久化至本地磁盘,可以在Flume实例恢复正常之后继续数据传输,不会有数据丢失的情况;而且本地磁盘相对于内存而言,存储空间比较富余,数据可靠性较强,因此使用FileChannel。

2. Flume实例架构

在我们的应用场景中,对于单独一个Flume实例而言,架构如下:

宏观上看,Flume实例内部仅有三个组件:ScribeSource、FileChannel、KafkaSink,实际上内部的结构还是比较复杂的,如下图所示:

这里先介绍两个比较重要的实例:

Receiver:Receiver是一个线程,对于Flume ScribeSource而言可以设置多个Receiver线程(通过指定ScribeSource workerThreads数值实现),它不断地将Flume ScribeSource接收到的数据以“事务”的形式写入FileChannel;

PollingRunner:PollingRunner也是一个线程,它不断地将FileChannel中的数据以“事务”的形式读取出来并写入Kafka;

对应的Flume配置文件:

myagent.sources = scribe_source

myagent.channels = file_channel

myagent.sinks = kafka_sink

# define scribe source

myagent.sources.scribe_source.type = org.apache.flume.source.scribe.ScribeSource

myagent.sources.scribe_source.port = 1466

myagent.sources.scribe_source.workerThreads = 5

# define file channel

myagent.channels.file_channel.type = file

myagent.channels.file_channel.checkpointDir = /data0/flume/checkpoint

myagent.channels.file_channel.dataDirs = /data0/flume/data

# define kafka sink

myagent.sinks.kafka_sink.type = org.apache.flume.sink.kafka.KafkaSink

myagent.sinks.kafka_sink.topic = mytopic

myagent.sinks.kafka_sink.brokerList = kafkahost:9092

myagent.sinks.kafka_sink.requiredAcks = 1

myagent.sinks.kafka_sink.batchSize = 1000

# Bind the source and sink to the channel

myagent.sources.scribe_source.channels = file_channel

myagent.sinks.kafka_sink.channel = file_channel

3. Flume调试及优化扩展

为了方便Flume的调试,我们自己开发模拟了一个Scrbie Client Simulator实例,可以兼容Scribe通信协议,以每秒大约90M/s的速率输出数据至Flume(这里特指单实例Flume),其中模拟的日志数据来源于我们平台常见的业务数据,后续的讨论均建立在这个Scribe Client Simulator实例的基础上。

3.1 ScribeSource

ScribeSource中有一个非常重要的配置属性“workerThreads”,如上所述,它的值被设定为5,那么这个值是如何得出的呢,它又会产生什么样的作用?<

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值