Storm+Redis性能优化问题

来源:互联网 发布:mysql 读写分离插件 编辑:程序博客网 时间:2024/06/05 02:23

结合自己的开发及调试经历,总结一下经验教训。

提升 Storm Topology的性能,不能只关注提高进程(worker)及线程(executor: spout/bolt)并发度, 也要注意是否有外部瓶颈;

     我的问题就在于Topology最后一级Bolt是要把分析结果写入Redis, 由于tuple吞吐量为每分钟数百万级,给Redis服务器带来很大压力。

    我的优化思路如下:

     (1) 首先需要确定瓶颈位置,究竟是Redis并发过大还是Topology处理能力不够;很遗憾,最初我对这一点不是很明确,所以只能根据性能数据做猜测;

     (2) 正是因为对(1)的不确定,我决定从优化访问Redis开始,如果起的作用不大,再优化Topology的数据处理逻辑;

     (3) 对于访问Redis的优化,我首先考虑的是如何降低访问Redis的频率。以前的代码是每处理一个tuple就访问一次redis(计数器功能,每次+1), 显然对于海量数据的实时处理是不合理的。我在代码中,实现了N秒内在本地内存中计数,间隔N秒向Redis中定期更新;那么程序每分钟访问Redis的理论上限为:

                  写redis的线程数 * 每个redis写线程(Bolt)可能的Redis Key数目  *  (60s / N s)

           结合我的具体场景, 该优化将Redis访问压力从10w / min降低到 5w / min以下。(我的思路也从尽可能提高写Redis的线程并发度改为缩小Redis写Bolts的并发度,因为每个线程的Redis Key数目是大致相同的,每增加一个线程就会放大写redis的并发)

     (4) 接下来我发现应用性能在一段时间后还是不能跟不上数据到来速度,看来topology处理逻辑仍需改进,对此我将最高频的execute()函数做了优化,主要是减少for循环中的重复函数调用(发现一个对性能影响比较严重的bug)。该步对性能提升发挥了积极作用,仍然不能满足场景需要;

     (5) 最后我想到目前虽然把访问Redis的频率降低,但是高并发下每次发送Redis访问请求的网络传输速度会对性能有很大影响。所以我用jedis pipeline进一步改造我的写redis代码部分,分批次发送Redis访问请求。这样可以极大的减少访问redis的网络延时。事实证明pipeline的使用对高并发访问redis的性能提升显著。

    优化后的结果:目前写redis的Bolt并发度为原来1/5, 但是延时缩小为原来的近1/3。

1 0