理解zookeeper的一致性及缺点

  • zookeeper保证
    • 理解zookeeper的顺序一致性
  • zookeeper的缺点
  • 参考链接

zookeeper使用ZAB协议达到了极高的一致性。所以在互联网业务中它经常被选作注册中心、配置中心、注册分布式锁等。

zookeeper保证

根据zookeeper官方文档,zookeeper提供了如下保证:

  • Sequential Consistency - Updates from a client will be applied in the order that they were sent.
  • Atomicity - Updates either succeed or fail. No partial results.
  • Single System Image - A client will see the same view of the service regardless of the server that it connects to. i.e., a client will never see an older view of the system even if the client fails over to a different server with the same session. 如果client首先看到了新数据,再尝试重连到存有旧数据的follower,该follower会拒绝该连接(client的zxid高于follower)
  • Reliability - Once an update has been applied, it will persist from that time forward until a client overwrites the update.
  • Timeliness - The clients view of the system is guaranteed to be up-to-date within a certain time bound.

根据我的实践,认为zookeeper只是一个最终一致性的分布式系统,并且历史上zookeeper还经常爆出违反分布式共识的bug,比如expired ephemeral node reappears after ZK leader change这个,session expired之后,临时节点仍然存在

理解zookeeper的顺序一致性

ZooKeeper Programmer’s Guide提到:

Sometimes developers mistakenly assume one other guarantee that ZooKeeper does not in fact make. This is:
Simultaneously Conistent Cross-Client Views
ZooKeeper does not guarantee that at every instance in time, two different clients will have identical views of ZooKeeper data. Due to factors like network delays, one client may perform an update before another client gets notified of the change. Consider the scenario of two clients, A and B. If client A sets the value of a znode /a from 0 to 1, then tells client B to read /a, client B may read the old value of 0, depending on which server it is connected to. If it is important that Client A and Client B read the same value, Client B should should call the sync() method from the ZooKeeper API method before it performs its read.
So, ZooKeeper by itself doesn’t guarantee that changes occur synchronously across all servers, but ZooKeeper primitives can be used to construct higher level functions that provide useful client synchronization.

就是说zookeeper并不保证每次从其一个server读到的值是最新的,它只保证这个server中的值是顺序更新的,如果其他server节点想要读取最新的值,必须在get之前调用sync()(zoo_async)

zookeeper的缺点

  1. Zab协议自身的限制导致了zookeeper的很多瓶颈,比如,单leader瓶颈,切主时服务不可用、系统存储的内容有限,可扩展性不足等等。

    • 另外zookeeper集群的一致性模型也并没有想象中完美,不提一些违背一致性的bug如ZOOKEEPER-2919,其本身的机制:更新操作都要forward给leader,读操作follower节点可以独立进行,就决定了zookeeper的一致性保证只能做到“Updates from a client will be applied in the order that they were sent”
  2. 身为一个分布式系统,本身就免不了有许多bug。有很多论文调查、研究分布式系统历史上出现的各种bug,我列举了几篇放在参考链接中
  3. zookeeper本身限制也导致了客户端的访问方式、处理事件的方式等等处处掣肘,客户端不管其上层承载的业务模型是怎样的,都要按照zookeeper的filesystem/trigger API去操作。

著名的zookeeper客户端库Curator专门总结了使用Zookeeper的Tech notes,我选择一些重要的翻译如下:

  1. 所有的watcher事件都应该在同一个线程里执行,然后再这个线程里对访问的资源加锁(这个操作应该由zk库在zk线程里自己完成)
  2. 认真对待session生命周期,如果expired就需要重连,如果session已经expired了,所有与这个session相关的操作也应该失败。session和临时节点是绑定的,session expired了临时节点也就没了
  3. zookeeper不适合做消息队列,因为
    • zookeeper有1M的消息大小限制
    • zookeeper的children太多会极大的影响性能
    • znode太大也会影响性能
    • znode太大会导致重启zkserver耗时10-15分钟
    • zookeeper仅使用内存作为存储,所以不能存储太多东西。
  4. 最好单线程操作zk客户端,不要并发,临界、竞态问题太多
  5. Curator session 生命周期管理:
    • CONNECTED:第一次建立连接成功时收到该事件
    • READONLY:标明当前连接是read-only状态
    • SUSPENDED:连接目前断开了(收到KeeperState.Disconnected事件,也就是说curator目前没有连接到任何的zk server),leader选举、分布式锁等操作遇到SUSPENED事件应该暂停上层的业务直到重连成功。Curator官方建议把SUSPENDED事件当作完全的连接断开来处理。意思就是收到SUSPENDED事件的时候就应该当作自己注册的所有临时节点已经掉了。
    • LOST:如下几种情况会进出LOST事件
      • curator收到zkserver发来的EXPIRED事件。
      • curator自己关掉当前zookeeper session
      • 当curator断定当前session被zkserver认为已经expired时设置该事件。在Curator 3.x,Curator会有自己的定时器,如果收到SUSPENDED事件一直没有没有收到重连成功的事件,超时一定时间(2/3 * session_timeout)。curator会认为当前session已经在server侧超时,并进入LOST事件。
    • RECONNECTED:重连成功

对于何时进入LOST状态,curator的建议:

When Curator receives a KeeperState.Disconnected message it changes its state to SUSPENDED (see TN12, errors, etc.). As always, our recommendation is to treat SUSPENDED as a complete connection loss. Exit all locks, leaders, etc. That said, since 3.x, Curator tries to simulate session expiration by starting an internal timer when KeeperState.Disconnected is received. If the timer expires before the connection is repaired, Curator changes its state to LOST and injects a session end into the managed ZooKeeper client connection. The duration of the timer is set to the value of the “negotiated session timeout” by calling ZooKeeper#getSessionTimeout().
The astute reader will realize that setting the timer to the full value of the session timeout may not be the correct value. This is due to the fact that the server closes the connection when 2/3 of a session have already elapsed. Thus, the server may close a session well before Curator’s timer elapses. This is further complicated by the fact that the client has no way of knowing why the connection was closed. There are at least three possible reasons for a client connection to close:

  • The server has not received a heartbeat within 2/3 of a session
  • The server crashed
  • Some kind of general TCP error which causes a connection to fail

In situtation 1, the correct value for Curator’s timer is 1/3 of a session - i.e. Curator should switch to LOST if the connection is not repaired within 1/3 of a session as 2/3 of the session has already lapsed from the server’s point of view. In situations 2 and 3 however, Curator’s timer should be the full value of the session (possibly plus some “slop” value). In truth, there is no way to completely emulate in the client the session timing as managed by the ZooKeeper server. So, again, our recommendation is to treat SUSPENDED as complete connection loss.

curator默认使用100%的session timeout时间作为SUSPENDED到LOST的转换时间,但是用户可以根据需求配置为33%的session timeout以满足上文所说的情况的场景

可见,使用好zookeeper不是一件容易的事,笔者使用zookeeper的过程中也曾遇到以下问题:

  1. zk session 处理

    • 忽略了connecting事件,client与server心跳超时之后没有将选主服务及时下线掉,导致双主脑裂。
    • 多个线程处理zk的连接状态,导致产生了多套zk线程连接zkserver。
    • zk超时时间不合理,导致重连频率太高,打爆zkserver。
    • 所有的zkserver全部重置(zk server全部状态被重置),这种情况下客户端不会受到expired事件,我之前实现的客户端也不会重新去建立zk session。导致之前的zkclient建立的session全部不可用,陷入无限重连而连不上的窘境。
  2. 多线程竞态
    • zk客户端自己的线程do_completion会调用watcher的回调函数,和业务线程产生竞争,导致core dump。
  3. 客户端同步api
    • 同步API没有超时时间,如果zkserver状态不对,发送给zkserver的rpc得不到回应,会导致调用同步zk API的线程阻塞卡死。
    • 供业务使用的api设计不当,导致初始化时调用的同步版本api造成死锁。

参考链接

  1. What Bugs Live in the Cloud? A Study of 3000+ Issues in Cloud Systems
  2. TaxDC: A Taxonomy of Non-Deterministic Concurrency Bugs in Datacenter Distributed Systems
  3. An Analysis of Network-Partitioning Failures in Cloud Systems
  4. 可能是全网把 ZooKeeper 概念讲的最清楚的一篇文章
  5. Zookeeper ZNodes – Characteristics & Example
  6. ZooKeeper Recipes and Solutions
  7. How to do distributed locking长文,里面画的图不错
  8. ZAB协议简介braft介绍zab
  9. Lease与最长宕机时间分析 zk提供选主服务,导致的不可服务的时间
  10. Zab: High-performance broadcast for primary-backup systems
  11. zookeeper Consistency Guarantees
  12. 深入浅析zookeeper的一致性模型及其实现讲解了为什么zookeeper的一致性和其他一致性协议有区别
  13. How ZooKeeper guarantees “Single System Image”?
  14. ZooKeeper: Wait-free coordination for Internet-scale systems yahoo的论文
  15. ZooKeeper FAQ 官方文档告诉你应该如何处理CONNECTION_LOSS,SESSION_EXPIRED等等,真的对zk有所了解的人都会问的问题。。。

理解zookeeper的一致性及缺点相关推荐

  1. 不理解Zookeeper一致性原理,谈何异地多活改造

    来自:DBAplus社群 作者介绍 陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计及基础架构研发工作.曾任百度架构师,负责百度即时通讯产品的架构设计.具有丰富的大规模系统构建和基础 ...

  2. 《从Paxos到zookeeper分布式一致性原理与实践》笔记

    <从Paxos到zookeeper分布式一致性原理与实践>笔记 文章目录 <从Paxos到zookeeper分布式一致性原理与实践>笔记 一.概念 二.一致性协调 2.1 2P ...

  3. 《从Paxos到zookeeper分布式一致性原理与实践》

    <从Paxos到zookeeper分布式一致性原理与实践> 一.概念 ACID: Automaticy.consistency.isolation. Durability CAP: con ...

  4. 《从Paxos到Zookeeper 分布式一致性原理与实践》

    第1章 分布式架构 1.1 从集中式到分布式 1.1.1 集中式的特点 集中式的特点:部署结构简单(因为基于底层性能卓越的大型主机,不需考虑对服务多个节点的部署,也就不用考虑多个节点之间分布式协调问题 ...

  5. 深入浅析zookeeper的一致性模型及其实现

    现在我们来考察一下zookeeper的一致性模型. 常见误区 一开始看到网上有人说zookeeper满足了CAP的CP特性,我一直以为zookeeper至少也是Sequential Consisten ...

  6. Zookeeper分布式一致性原理(四):Zookeeper简介

    zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现数据发布/订阅.负载均衡.命名服务.分布式协调/通知.集群管理.master选举.分布式锁和分布式队列等.Zook ...

  7. 理解 zookeeper

    2019独角兽企业重金招聘Python工程师标准>>> 理解 zookeeper Zookeeper 主要用来解决分布式应用中经常遇到的一些数据管理,如统一命名服务器.状态同步服务. ...

  8. 带你快速理解Zookeeper

    理解Zookeeper 为什么需要Zookeeper? 用一句话概括就是:用起来像单机但是又比单机更可靠 1.集群.可靠 2.当信息还没同步完成时,不对外提供服务 3.同步的时间压缩的更短 主要解决了 ...

  9. Zookeeper的一致性是什么情况?

    Zookeeper的一致性,体现的是什么一致呢? 根据前面讲的zab协议的同步流程,在zookeeper集群内部的数据副本同步,是基于过半提交的策略,意味着它是最终一致性.并不满足强一致的要求. 其实 ...

最新文章

  1. HTML5 Web SQL数据库
  2. git rebase/reset小计
  3. 定义一个Matrix类,实现矩阵的加法和乘法
  4. 用户管理实用命令(第二版)
  5. mysql常用的备份命令有哪些_MySQL常用备份还原命令
  6. Python使用pip安装/卸载包
  7. 【报告分享】激荡2020--吴晓波疫情特别演讲PPT.pdf(附下载链接)
  8. UG命令大全及快捷键的用法用处说明
  9. excel软件php函数,文员常用的excel函数
  10. 密码学之现代密码通俗理解凯撒密码、 栅栏密码、 ROT5/13/18/47、维吉尼亚密码、 培根密码、 仿射密码
  11. 新手在Kail Linux中使用pdfcrack 来破解pdf密码
  12. 关于php网络爬虫phpspider
  13. c语言程序设计第一次在线作业答案,20春地大《C语言程序设计(新)》在线作业一...
  14. 前端实现导入(excel文件)导出(word)文件
  15. macbook proa1708_MacBook Pro 2017 A1708自己更换电池
  16. sim7600ce 拨号上网测试_SIM7600CE应用程序调试流程
  17. 第1篇 初识IPP(Integrated Performance Primitives)
  18. 抓取APP中的素材步骤之一
  19. spire.office,Spire.Office 5.3.7组件的最新版本
  20. html5 replace,js replace函数用法详解

热门文章

  1. linux设置光标位置,linux下光标定位和输出颜色设置
  2. java泛型 例子_关于 Java 泛型的一些有趣的例子
  3. 计算机文化基础知识点文件,计算机文化基础知识点.doc
  4. 外挂学习之路(5)--- 写测试call的注意事项
  5. 用C++面向对象的方式动态加载so
  6. 数据结构与算法 | 直接插入排序、希尔排序
  7. Python中类方法、类实例方法、静态方法,私有属性和私有方法有何区别?
  8. 强烈推荐|我做系统架构的一些原则
  9. 注意!!Redis使用不当真的可能会导致应用卡死
  10. RabbitMQ消息追踪之Firehose