用ZooKeeper真的low吗?上千个节点场景配置服务方案大讨论 - 高可用架构系列

Posted 高可用架构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用ZooKeeper真的low吗?上千个节点场景配置服务方案大讨论 - 高可用架构系列相关的知识,希望对你有一定的参考价值。

有人的地方,就有江湖

有江湖的地方,就有纷争


以下是QCon高可用群一次关于ZooKeeper为主的一次激烈的技术讨论,考虑到部分讨论提及数据可能跟业务相关,因此未保留公司名称等非技术信息。想进一步参与以下话题讨论,可留意文章末尾的说明。


为什么说一套系统用了ZooKeeper,这个系统一定很low?


ZooKeeper = low?


提出此观点的架构师介绍其原因如下。


在Docker环境下,通常虚机会比较多,我们发现ZooKeeper不能承受太多节点。我们的游戏平台是一个多租户场景,需要频繁进行创建及删除,在这种情况下如果超过3,000虚拟机,ZooKeeper就不行了。


当ZooKeeper挂了后,meta数据也会跟着丢了。Meta数据和和监控功能在ZooKeeper当初设计时并没有考虑的问题,因此后来我们打算自己造轮子,将这个需求实现。


我也并非说ZooKeeper一无是处,ZooKeeper有它适合使用的场景,比如Hadoop那种场景ZooKeeper就可以工作得很好,但并不是所有场景都适用。Tim说过一句经典的话,Redis是把好锤子,但不能把所有存储的问题都当做钉子。ZooKeeper也是一样,不是所有的配置的问题都适合拿它来解决。


其他一些网友的看法。


Z: 同意ZooKeeper是有很多运维的问题,一个解决方法是自己实现一个single node all in memory的lock service,然后运行在多个机器上,用ZooKeeper当作一个distributed lock来选一个master,这样ZooKeeper上的压力就小多了,而且不会随着集群大小增加而增加。


Y: Kafka里使用ZooKeeper的方式有好几个地方可以借鉴。除了上面说的选一个master处理的方式外,为了避免订阅大量节点,也可以单设置一个变更节点,然后只订阅这个变更节点。


G: Kafka集群依赖于ZooKeeper,但ZooKeeper也是Kafka的瓶颈。



某知名大型互联网公司方案


某知名大型互联网公司的架构师也基本认可上述观点,其新开发的服务框架中不再采用ZooKeeper作为注册中心,主要说明如下


1. 随着部署规模增大,客户端增多,ZooKeeper服务器中节点数量大增,核心ZooKeeper集群5台,每台服务器1,5000左右的长链接,近43万个节点,平均30余万watch。每个上线日,ZooKeeper服务器的流量都能上200mb/s,通过mntr的观察zk_outstanding_requests 经常达到300M以上;

2. 有业务方报告,应用启动后连上ZooKeeper但一直读失败(读数据返回为null),也就是取服务列表失败,一段时间如半小时后自动恢复,查看zk server端日志,只看到一堆session过期的警告,没有其他异常;

3. 由于历史原因,ZooKeeper服务器与其他应用共用,40万+节点中60%是我们的,其他应用也是重度依赖zookeeper,互相之间有影响;

4. ZooKeeper推送的频率、内容,我们自己不能控制,比如一个600 provider,12000 consumer的服务,如果新增一个provider,其实并不是每个consumer都需要通知的,但目前的机制下consumer监听一个目录,每个consumer都会得到一次provider列表推送;还有我们想在推送前根据一定的规则对provider列表做动态过滤排序,这个需求在zookeeper服务端也没法实现。

6. 跨机房容灾方面,一旦出现机房间通信问题,另一个机房的部署的Observer节点,就不可读写了;

7. provider约6万实例,consumer22万实例;


基于以上的原因,新的方案实现也很简单,自己实现了一个服务用来做注册中心的,实现的是服务注册/订阅方面的功能。它负责接收长链接并推送,数据存储在mysql


Q:使用ZooKeeper主要是它实现了强一致性,你这个注册中心是单点的吧?master election用ZooKeeper?注册中心会成为新的瓶颈和故障点?


Q:跨机房容灾方面有什么优化吗?如果网络没有足够的redundency,一旦出现network partiton,那么有一个机房就没办法到quorum了?

A:通过多机房部署,每个机房保证至少2个节点,本机房挂了还可以访问其它机房,并且在客户端本地还有缓存文件。


Q:当配置变化,client以http轮询方式去感知吗?

A:Session过期那个,开始我们设的是很短,后来发现不对,网络一闪断,大量掉节点。现在我们自己实现的服务,半分钟一心跳,几个心跳没收到我才认为下线了。如果provider列表发生变化,我这边服务端会主动推送的,因为用的是TCP长连接。


Q: Client有没有主动发现本地cache与服务端数据不一致的机制?例如当provider列表发生变化且服务端通过TCP长连给client推送失败的场景。

A:有,我们心跳带本地版本号的,如果与服务端不一致的话,会触发服务端再次推送;


另一知名大型互联网公司ZooKeeper运行现状


而另外一知名大公司架构师认为如果consumer数量没有那么多,用ZooKeeper也能较好满足要求。其业务场景的ZooKeepr使用及运行情况如下。


线上的单个ZooKeeper节点平均连接数是6K,watcher是30万,netIO不高,ZooKeeper的机器配置比较差,用的是4G 4CPU 的虚拟机,5个节点,最多的consumer不超过200,平均consumer数量就5,6个左右。


目前线上provider数3万左右实例数,consumer数10万左右,目前运行的没什么问题。3万个,如果每个服务10个实例,也就3,000个服务,全公司的,也没多少。看起来是多了点。 跟公司发展历史及使用场景关系很大。


之前关于ZooKeeper踩坑最多的是在客户端上,最开始用的是netflix的curator(后来贡献给apache,但是我们用的是老的,没升级),遇到网络闪断重连不上,然后死循环一样,升级到apache curator就好了。


后来遇到一个问题是,如果注册watcher太多,发生重连的时候,zk client会自动注册之前的所有watcher,这样会导致一个包的大小超过1M,然后也就重连不上又不断地重连,后来hack了zk client解决了这个问题,这个bug到目前为止zk官方仍然没有修复。


不过这些坑基本上遇到一个可以解决一个,但是目前有一个问题目前也没找到好的解决方案,那就是业务方系统load变高,或者发生长时间gc,导致zk重连甚至session过期。


另外关于zk连接,我们在最底下做了连接共享,因为好多服务都依赖zk,这个也降低了不少连接数。


PS: 讨论中提及的参考资料:(建议通过电脑浏览)

http://www.infoq.com/cn/news/2014/12/zookeeper-service-finding


http://jasonwilder.com/blog/2014/02/04/service-discovery-in-the-cloud/


想进一步补充观点,或想同群专家进一步交流ZooKeeper及高可用的配置服务方案,可回复arch申请进群。



以上是关于用ZooKeeper真的low吗?上千个节点场景配置服务方案大讨论 - 高可用架构系列的主要内容,如果未能解决你的问题,请参考以下文章

zookeeper集群 新手安装指南

Zookeeper 观察者

求求你别在用 for循环遍历list 了,真的太low了!

用分布式锁来防止库存超卖,但是是每秒上千订单的高并发场景,如何对分布式锁进行高并发优化来应对这个场景?

求求你别在用 for循环遍历list 了,真的太low了!

你真的会用 ZooKeeper 吗?