设为首页 收藏本站
查看: 726|回复: 0

[经验分享] zookeeper OOM问题排查

[复制链接]

尚未签到

发表于 2017-4-19 08:10:29 | 显示全部楼层 |阅读模式
背景
  最近折腾的数据库同步项目中,大量使用了zookeeper(版本3.3.3),可以说是强依赖,但是最近频频出现zookeeper内存使用率达到100%,而且是GC不掉,直接导致整个系统挂起,伤不起阿

分析
  因为大部分的情况都是无法GC回收,所以很大程度上怀疑出现memory leak。
  设置了jvm参数,收集了一下OOM导致jvm crash之后的日志文件进行分析

-XX:+HeapDumpOnOutOfMemoryError
leak分析: 

DSC0000.png



DSC0001.png
 


从leak分析来看,比较明显,99%的内存都被Leader类的observingLearners给吃光了,所以重点就可以落在zookeeper observer的使用上了。

zookeeper的observer模式
  官方说明: http://zookeeper.apache.org/doc/trunk/zookeeperObservers.html 
  主要用于解决读扩展性的问题,observer的节点不参与vote,也就是说写操作都只会发生在leader/follower中进行投票决策,而observer就是一个只读镜像。
  但有一点和数据库的master/slave模式不同的是,observer也会接受写请求,但会将请求转交给leader/follower集群进行处理,并同步等待返回结果。
  可以说observer比较巧妙的解决了读扩展性的问题,在zookeeper3.4.5版本,增加了readonlymode,和observer模式还是有所不同。
  在我之前的文章中,zookeeper项目使用几点小结,有描述在项目中使用observer的情况: 
  
DSC0002.jpg
  从图中可以看出: 
  1.  整个zookeeper大集群有2部分组成,杭州的一个leader/follower集群  +  美国的一个observer集群
  2.  为保证可用性,杭州集群的机器分别部署在3个机房中,(满足任意机房AB, 机房A+机房B  >  机房A+机房B+机房C/2),最小的部署结构为3+2+2机器,这样可以确保,任何一个机房挂了,都可以保证整个zookeeper集群的可用性

代码分析:
  有了以上的背景分析,再回到memory leak问题上来,翻了下zookeeper issue,发现还真有提交对应的memory leak问题,https://issues.apache.org/jira/browse/ZOOKEEPER-1303 
  看完issue后,这时候问题已经明显了。 
  在Leader.java类中:

/**
* Remove the learner from the learner list
*
* @param peer
*/
void removeLearnerHandler(LearnerHandler peer) {
synchronized (forwardingFollowers) {
forwardingFollowers.remove(peer);            
}        
synchronized (learners) {
learners.remove(peer);
}
}
  这里面Leader节点,在与对应的follower/observer之间的链接异常断开时,会清理当前内存中的引用句柄 (不然下次的vote信息还会发送到挂了的节点上)。
  而leader在往observer上推送write数据,会遍历当前内存中的observingLearners列表

/**
* send a packet to all observers     
*/
void sendObserverPacket(QuorumPacket qp) {        
synchronized(observingLearners) {
for (LearnerHandler f : observingLearners) {               
f.queuePacket(qp);
}
}
}
  再看一下LearnerHandler.java类中:

public class LearnerHandler extends Thread {
public void run() {
p = queuedPackets.poll();
........
}
void queuePacket(QuorumPacket p) {
queuedPackets.add(p);
}
}
  LearnerHandler中的处理方式是一种典型的异步处理,通过queuedPackets接受任务数据,然后线程异步进行消费处理。 因为observer可能因为网络抖动,会断开与Leader之间的链接,就会触发shutdown方法。而shutdown方法就是尝试将自己从Leader的observer句柄中移除
  所以整个问题原因已经比较明确,removeLearnerHandler没有清理observer队列中的句柄,导致一直进行queuePacket调用,又没有异步线程进行消费,所以暴内存是迟早的事。

总结
  特别注意:3.3.6中居然没修复这个问题,所以可升级zookeeper至3.4.5, 经过实际验证大家可放心升级(我的client 3.3.6 , server 3.4.5)
  zookeeper 3.4和3.3的兼容性描述: http://blog.cloudera.com/blog/2011/11/apache-zookeeper-3-4-0-has-been-released/ 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-366100-1-1.html 上篇帖子: zookeeper OOM问题排查 下篇帖子: mac zookeeper伪集群
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表