大白话twitter storm效率

前提

    能单进程搞定就不要分布式,分布式毕竟带来很多开销,系统也复杂不止一个等级,性能当然没有单进程的给力

到底要不要用分布式系统

    基于前提的描述,如果服务单进程内无法搞定,不得不用分布式解决方案,这个时候我们需要考虑分布式解决方案,分布式这概念大家都懂,这里详细说下storm效率问题

storm效率如何

    如果要谈storm只顾效率的话,似乎过于偏颇,毕竟storm带给我们的不只这一点,其优势很多很多。

    真要谈效率的话我们不妨从以下两方面着手:数据处理和数据传输。

数据处理方面

    storm框架本身不负责你的业务处理,所以这块其实和自己开发的代码的业务处理效率息息相关,在充分理解各业务(bolt)到底是io密集型还是cpu密集型的情况下,合理的分配storm集群资源,具体到每个bolt的线程数,task数,spout task的pending数等。所以这部分总结一句话就是数据处理效率不和storm发生关系!

数据传输方面

    关注三个关键词,单线程、disruptor、zeroMq,在storm中数据传输包括进程内和进程外,进程内数据传输采用disruptor,这个的效率大家可以到网上了解下,资料已经比较多了,而且原代码量也不是很大,有兴趣的可以读读源代码,我们需要关注的是多少tuple一打包交给executor和disruptor的waitcategory。对于进程外,需要关注的稍多一些,storm中进程间数据传输采用zeroMQ,效率同样很可观,另外对于传输的数据需要序列化,storm默认序列化支持java serialization和kryo,对数据的序列化可以自己进行调整,另外每个进程中分别有且仅有一个线程用于数据的传送,假如单进程内开启了过多线程势必会对传输线程造成影响,得不到充分调用也是有可能的。这部分之前测试看,KM的网络,普通pc机网络上行/下行可以分别达到80M,所以总结一句话这方面storm的效率也比较可观!

如何优化topology

  1.  尽量细分spout/bolt,使其更贴近分布式,对不同的component灵活分配资源。

  2. 对于grouping,尽量采用localgrouping,经测试观察,storm默认scheduler是对每个component从worker1轮训分配到workerN,这里假如有三个worker,bolt1可以是3*N个线程,这样bolt1是平均分配到各worker上的,其余bolt也这样处理,这时我们使用localgrouping可以实现数据尽量在进程内传输,降低网络带来的开销。

  3. spout端,假如在topology中,处理瓶颈在spout端,而且你又不能增加spout的数量,可以试试修改spoutWaitStrategy,默认waitstrategy是sleep(1ms),如果嫌这个也慢,不妨试试yield(),当然会带来一定的cpu压力。

  4. 让spout nextTuple()尽量简单,没有阻塞,没有处理逻辑,直接取数据emit就好

  5. 另外推荐这篇:storm topology 一种优化思路

工作案例分析

    用事实说话,我们的服务有个场景,消息进入系统后需要保证其时序性,也就是说消息进来的顺序是1,2,3,出去的时候也要1,2,3   虽然很长一段时间对这个需求非常排斥,觉得这需求完全和分布式是相悖的,那如果硬要在分布式场景下解决只能硬头皮上了。下面详细介绍下调优的过程,假设过程中机器资源一定,topology的worker数量为3。

    首先凭直觉,设定各bolt的executor和task数,待topology启动后,在ui界面中我们可以观察到几个关键参数,即每bolt的execute latency和ack latency,通过这几个关键参数我们可以基本定位到topology的瓶颈,然后回头对bolt的executor和task数进行设置,使个bolt的处理效率基本平衡,不至于导致某个bolt成为系统的瓶颈。调整后处理效率大概能到8K/S

    然后通过dstat观察pc机负载情况,发现cpu还有很大富余,因为topology中有服务需要访问网络资源,所以会有阻塞,所以适当调整worker的executorPool大小,(storm中默认pool大小等于物理核数),调整后处理效率又有了提高能到1W/S

    前面说过这个场景需要保证消息的时序性,所以我们的topology中有一个单线程单task的sortbolt,用于将前面乱序的消息排序进行输出。这里还要提一下,原始的消息是zip消息,然后unzipbolt会解包,将小消息发送给后面业务bolt进行分布式处理(不关心消息顺序),交给sortbolt进行排序,交给zipbolt打包,交给sendbolt发送到queue。第一条中提到可以根据ui调整各bolt的executor数和task数,假如bolt1线程数是3,而bolt2的线程数是2,这样就造成bolt1和bolt2间消息顺序性乱序比较严重,再交给sortbolt进行排序时,导致很多线程的唤醒都没做具体工作,所以现在的目标是尽量缓解bolt间消息乱序情况,我们采用各bolt尽量在每worker上都有,然后让这个worker上的bolt消息传输采用localgrouping,不通过网络,同时也减少了worker间单线程传输导致的消息汇聚与分散带来的乱序,这样处理后效率又有了很大的提高,大概到了1.5W/!


jerry 于 2014年5月8号下午

转载于:https://my.oschina.net/jerrysearch/blog/262122

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值