您的位置:首页 > 编程语言 > Java开发

Storm短暂的Worker脑裂之旅

2016-05-14 20:42 483 查看
Storm中supervisor控制着worker的生命周期,负责worker的启停。

前端时间开发类似Storm中这样的一套系统时(worker和storm差别很大)脑裂的问题,supervisor负责启动一个worker,而最后上机器ps看到却有两个相同的worker,这两个相同的worker反复重启导致一堆奇怪的现象。

Supervisor与Worker
Storm中,supervisor主要有两个线程。如下图:



(图来自Twitter发的Storm论文)

10s运行一次的线程负责同步分配信息等。

3s一次的线程负责启动worker,创建worker需要的心跳目录等。

问题就出在3s一次的Sync-Process线程上。

Supervisor在Sync-Process中,大概会有一下动作:

1.杀掉超时或不合法的,删除心跳目录,注意,不合法的还包括workerId匹配不上的。

2.生成需要启动的worker的workerId。

3.创建心跳目录。

4.启动worker。

5.等worker首次心跳直到超时。

合理的剧本应该是启动好,supervisor等到worker心跳回来,正常运行。

但当时的情况时,worker在超时时间内没有心跳回来,不是因为worker异常退出了,而是worker还没来得及。

Supervisor在下次循环时,删除先前的心跳目录,再次生成新的workerId,启动一个worker,这时就有两个worker同时在运行。

worker1在worker2启动成功心跳了(强制创建了心跳目录),但是此时worker1的Id已经被worker2的Id覆盖了,所以worker1被认为不合法,被supervisor kill掉。

worker2也和先前的worker1一样,心跳慢了一拍,启动超时了,supervisor继续启动了worker3。

就这样反复重启,机器上一直保留着两个worker。如下图。



导致这一现象的原因还是supervisor的worker启动超时时间配得太小,worker启动后没有优先心跳导致,worker在心跳时也没判断心跳目录是否存在。

所以解决方案是:

1.supervisor的worker启动超时时间加大。

2.worker启动后立即心跳。

3.worker心跳时判断父目录,不存在立即退出。

从这里可以看出storm原本设计的合理性,在首次心跳超时的情况下,只会反复起不来,而不会脑裂(不会有两个worker同时服务),因为Storm worker在心跳目录被删了之后,再次心跳会由于目录不存在而退出,而且worker在启动后不会做额外的事,直接心跳。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息