本文翻译自:Flume Memory Consumption
每个Source或者Sink需要的内存
单个event占用的heap(堆)内存取决于event body的数据大小以及任何header带来的附加空间占用。所以从总体上说,一个source或者sink会分配的空间大概是event body + 可能占100字节的headers(这受到事务agent增加的header的影响)。估算一个batch(批次)需要的总内存的方法是,将你的平均(或九分数)event大小乘以最大的batch大小。
每个Sink只需要缓存一个batch,所以它需要的内存大小是一个batch的大小。而每个Source要面对多个client,所以它需要的内存大小是batch大小乘以同时连接的client数目。记住这点并按照你所期望的吞吐量来计划event发送速率。
File Channel需要的内存
一般情况下,每个File Channel使用部分heap内存和部分直接内存(direct memory)。给每个File Channel大概30MB的heap内存作为基本操作的内存消耗。另外每个File Channel需要大约 1MB + (channel容量 * 8) 字节的直接内存,因为Flume将这些更新内容存在一个HashMap里面。
为了在没有checkpoint的情况下快速恢复(fast replay without checkpoint),可以将File Channel的heap内存设为(channel容量 * 32)。实际使用的内存取决于log文件中正被恢复的event的数量。所以,如果File Channel保存了1亿个event,数据恢复需要3.2GB的heap内存。如果要使用没有checkpoint的快速恢复,必须将相应的配置选项设为true,也就是说:
agent.channels.ch-0.use-fast-replay = true
如果这个选项没有开启,没有checkpoint的数据恢复会慢些,不过使用的内存会明显地减少:和上文所说的File Channel的普通操作相似。
Flume核心需要的内存
Flume核心会占用总heap内存中的大概50MB。最后,推荐给计算得出的内存留有一个缓冲空间。生产环境的JVM内存使用可以通过JMX来监控和可视化,这样可以在一个特定的工作负载下,更好地理解实际的内存分配。
内存配置案例
Flume从flume-env.sh读取环境变量,这个默认是禁用的(这个文件会被命名为 $FLUME/conf/flume-env.sh.template).启用的方式就是简单地将其重命名为flume-env.sh,并根据你计算得出的需求修改配置。另外最好在启动的时候就初始化需要的内存,而不是等内存不够的时候再加,这样能避免当新的内存加入时出现朱丽叶假死(Juliet pause),也就是full GC.
经过GC优化的内存调整应该如下:
#将最小内存设置为2GB,最大为16GB,最大直接内存为256MB。
#使用并行并发的垃圾回收器来减少出现长时间 stop-the-world GC暂停的概率。
JAVA_OPTS=”-Xms2000m -Xmx16000m -Xss128k -XX:MaxDirectMemorySize=256m
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC”