【转载】对 Zookeeper 的一些分析


1. zookeeper 不是为高可用性设计的
  • 因为要跨机房容灾,不少系统其实是须要跨机房部署的。出于性价比的考虑咱们一般会让多个机房同时工做,而不会搭建 N 倍的冗余。也就是说单个机房确定撑不住全流量(你能设想谷歌在全球只剩下一个机房在干活吗)。因为 zookeeper 集群只能有一个 master ,所以一旦机房之间链接出现故障,zookeeper master 就只能照顾一个机房,其余机房运行的业务模块因为没有 master 都只能停掉。因而全部流量集中到有 master 的那个机房,因而系统 crash 。
  • 即便是在同一个机房里面,因为网段的不一样,在调整机房交换机的时候偶尔也会发生网段隔离的状况。实际上机房每月基本上都会发生短暂的网络隔离之类的子网段调整。在那个时刻 zookeeper 将处于不可用状态。若是整个业务系统基于 zookeeper(好比要求每一个业务请求都先去 zookeeper 获取业务系统的master 地址),则系统的可用性将很是脆弱。
  • 因为 zookeeper 对于网络隔离的极度敏感,致使 zookeeper 对于网络的任何风吹草动都会作出激烈反应。这使得 zookeeper 的‘不可用’时间比较多,咱们不能让 zookeeper 的‘不可用’,变成系统的不可用。

2. zookeeper 的选举过程速度很慢

  • 这是一个很难从理论分析上看到的弱点,可是你一旦遇到就会痛不欲生。
  • 前面咱们已经说过,网络实际上经常是会出现隔离等不完整状态的,而 zookeeper 对那种状况很是敏感。一旦出现网络隔离,zookeeper 就要发起选举流程。
  • zookeeper 的选举流程一般耗时 30 到 120 秒,期间 zookeeper 因为没有 master,都是不可用的。
  • 对于网络里面偶尔出现的,好比半秒一秒的网络隔离,zookeeper 会因为选举过程,而把不可用时间放大几十倍。

3. zookeeper 的性能是有限的

  • 典型的 zookeeper 的 tps 大概是一万多,没法覆盖系统内部天天动辄几十亿次的调用。所以每次请求都去zookeeper 获取业务系统 master 信息是不可能的。
  • 所以 zookeeper 的 client 必须本身缓存业务系统的 master 地址。
  • 所以 zookeeper 提供的‘强一致性’其实是不可用的。若是咱们须要强一致性,还须要其余机制来进行保障:好比用自动化脚本把业务系统的 old master 给 kill 掉,可是那会有不少陷阱(这里先不展开这个议题,读者能够本身想一想会有哪些陷阱)。

4.zookeeper 没法进行有效的权限控制

  • zookeeper 的权限控制很是薄弱。
  • 在大型的复杂系统里面,使用 zookeeper 必须本身再额外的开发一套权限控制系统,经过那套权限控制系统再访问 zookeeper 。
  • 额外的权限控制系统不但增长了系统复杂性和维护成本,并且下降了系统的整体性能。

5.即便有了 zookeeper 也很难避免业务系统的数据不一致

  • 前面已经讨论过了,因为 zookeeper 的性能限制,咱们没法让每次系统内部调用都走 zookeeper,所以总有某些时刻,业务系统会存在两个 master(业务系统 client 那边缓存的业务系统 master 信息是定时从zookeeper 更新的,所以会有更新不一样步的问题)。
  • 若是要在业务系统 client 的 master 信息不一直的状况下,仍要保持系统的数据一致性,惟一的方法是“先 kill 掉老 master,再在 zookeeper 上更新 master 信息”。可是在是否要 kill current master 这个问题上,程序是没法彻底自动决定的(由于网络隔离的时候 zookeeper 已经不可用了,自动脚本没有全局信息,无论怎么作均可能是错的,什么都不作也多是错的。当网络故障的时候,只有运维人员才有全局信息,程序是没法接电话得知其余机房的状况的)。所以系统没法自动的保障数据一致性,必需要人工介入。而人工介入的典型时间是半个小时以上,咱们不能让系统这么长时间不可用。所以咱们必须在某个方向上进行妥协,最多见的妥协方式是放弃‘强一致性’,而接受‘最终一致性’。
  • 若是咱们须要人工介入才能保证‘可靠的强一致性’,那么 zookeeper 的价值就大打折扣。

6.咱们能作什么

  • 咱们或者选择人工介入的强一致性,或者选择程序自动化进行的弱一致性。须要进行取舍。
  • 最终一致性甚至未必是程序来作的,有时候人工修正数据反而在灵活、可靠、低成本上有优点。这须要权衡。
  • 不要迷信 zookeeper,有时候不妨考虑一下主备数据库。数据库自带权限控制,用起来比 zookeeper 方便多了。
  • zookeeper 比较有价值的东西也许是内容变化的时候,能够阻塞回调的方式通知全部在线的 client 实时更新信息,但这个功能用处不大。由于 php 这样的模块你很难说它是在线仍是离线,每次都是新发起的。一旦这个功能没法支持 php,就没法覆盖整个系统,那么就没法保证强一致性了。


PS:以上只是我的对 zookeeper 的一些认识,欢迎讨论和指正。
相关文章
相关标签/搜索