flume-ng的CPU高消耗定位及改进

公司用的flume-ng采集数据,数据源是日志文件,然后通过正则表达式来过滤指定日志,最后发送给kafka。使用的是apache-flume-ng1.6.0版本。

最初消耗如下:

144212_ixQo_223522.png

经过我改进后,消耗如下:

144140_zimA_223522.png

cpu消耗整整降低了几十甚至百倍。


其中改进点有两个:一是自定义一个关键字筛选器;二是重写KafkaSink.java文件为另一个类,添加无事件处理睡眠配置。

我们的日志格式大概是这样子:

XXXXXXXX`XXXXXXX`XXXXXX`…`op=0x38(OP_REPORT_ACTION)`seq=3424`xxx=xxxx`xxx=xxxx`xxx=xxxx……

关键字筛选器fm.lizhi.flume.channel.OpChannelSelector,配置如下:

agent2.sources.Usersource2.selector.type = fm.lizhi.flume.channel.OpChannelSelector
agent2.sources.Usersource2.selector.mapping.0x3a(OP_ADD_COLLECT_PROGRAM)=Userchannel2
agent2.sources.Usersource2.selector.mapping.0x38(OP_REPORT_ACTION) = Userchannel2
agent2.sources.Usersource2.selector.skip = 90

上面的skip意思是直接跳过90个字符不检测(因为我们打印的op=肯定在90个字符以后,所以为了节约资源设置)。

这个selector主要检测op=后的值,匹配上mapping后的值,就发送给相应的channel,否则丢弃。从而达到筛选目的。


对KafkaSink的改进如下:

package fm.lizhi.flume.sink;


/**
 * 近实时的KafkaSink,相比KafkaSink多了backoffSleepMillisecond属性。<br>
 * 改造自1.6.0版本的KafkaSink
 * @author zhenghaofeng
 */
public class NRTKafkaSink extends AbstractSink implements Configurable {

	private int bakoffSleepMillisecond;

	private static final String BACKOFF_SLEEP_MILLISECOND = "backoffSleepMillisecond";
	private static final int DEFUALT_BACKOFF_SLEEP_MILLISECOND = 0;

	public Status process() throws EventDeliveryException {
		
		boolean isNoEventMore = false;

		try {
			……………………
			for (; processedEvents < batchSize; processedEvents += 1) {
				event = channel.take();

				if (event == null) {
					// no events available in channel
					isNoEventMore = true;
					break;
				}
                                ……………………

			}
                        ……………………

			transaction.commit();

			if (isNoEventMore) {
				try {
					Thread.sleep(bakoffSleepMillisecond);
				} catch (InterruptedException e) {
					// TODO: handle exception
				}
			}

		} catch (Exception ex) {
			……………………
		} finally {
			……………………
		}

		return result;
	}


	public void configure(Context context) {

		………………
		bakoffSleepMillisecond = context.getInteger(BACKOFF_SLEEP_MILLISECOND, DEFUALT_BACKOFF_SLEEP_MILLISECOND);
		…………………………
	}
}

为什么event=null的时候不返回BACKOFF状态,而采用标记睡眠呢?因为如果返回BACKOFF状态,flume默认会睡眠1~5秒。而我们通常不希望延时这么久,所以为了不侵入flume原先的代码,就直接在这里添加睡眠中断。

配置里写法如下:

agent2.sinks.Usersink2.type=fm.lizhi.flume.sink.NRTKafkaSink
agent2.sinks.Usersink2.backoffSleepMillisecond=100


转载于:https://my.oschina.net/u/223522/blog/515260

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值