聊聊对channel的认识
今天聊一聊channel的话题,最近几年从事的工作内容都跟消息流和数据通道有关系,
结合最近项目的调优,说说我对channel的认识。
ringbuffer
说到channel,就不能不提disrupter的ringbuffer,最近几年非常热门的开源项目。
ringbuffer强调对象的高度复用,减少GC的次数,有无数据的timeout的回调,方便实现batch逻辑,
多种策略的选择,应对多种业务时效场景。
selector
无论是实时流计算,还是消息通道,都会有一个类似selector的组件,基于某些字段对消息进行分类,
将event投递到不同的channel中,主要是为了解决一定程度的顺序问题,
比如将相同主键的消息顺序输出。flume中的selector就是针对header中的某个key进行mapping,
实现了灵活强大的分流功能。当然使用key也尽量不要出现热点,要不然整体的消费能力就会提早到达瓶颈。
broadcast
broadcast功能在channel中也是非常实用的,比如checkpoint相关的event向下游传递,如果下游有
多个channel,那么就需要一个broadcast功能。在业务中broadcast的应用也非常广,比如上游计算
导致了某种meta信息的变更,就可以通过broadcast的功能通知下游,这种方式比借助外部存储要高效的多,
而且天然不用解决多version的问题。
balance
如果你碰到了一拆N的channel场景,并且对数据的顺序不那么敏感时,肯定希望能最大限度的发挥下游
channel的能力,很多人都在selector上选择roundrobin,或者是基于timestamp取模的方法,如果下游
的消费能力非常强,这种做法是没有问题的。但如果你在下游sink是重IO类型的,这种做法就不会达到
你想要的效果了。你会发现流经常会因为某一条下游的blocking,导致整条链路卡主,你使用了多条通道
,但性能并没有成线性增长。这个问题在我的分发kafka消息至hdfs时就碰到了,一旦HDFS的响应速度下降
整个job的吞吐量大大降低,增加channel并没有解决这个问题,只能增加jvm实例来解决,非常耗资源。
这时,你需要的是类似负载均衡方面的WLC算法的解决方案。首先,你需要让下游的channel暴露出自己
的余量。然后根据余量的情况选择最为空闲的节点,这样你增加的channel才会有意义。当然如果你有
大量的broadcast消息,也会极大的影响你的性能。