zookeeper

Zookeeper简介

Zookeeper最早起源于Yahoo 的Hadoop项目,作为分布式计算和存储平台,需要解决一致性的场景非常多,因此他们开发了Zookeeper这么一个组件,专门用来协调解决一致性问题。

那什么才是一致性呢?数据一致性其实最早是数据库系统中的概念。我们可以简单的把一致性理解为正确性或者完整性,那么数据一致性通常指关联数据之间的逻辑关系是否正确和完整。比如你删除某个被其他表引用的表时,你是删除不了的,这个就是关系的一致性保证的。而在分布式系统中,数据一致性往往指的是由于数据的复制,不同数据节点中的数据内容是否完整并且相同。

​比如在集中式系统中,有一些关键的配置信息,可以直接保存在服务器的内存中,但是在分布式系统中,如何保存这些配置信息,又如何保证所有机器上的配置信息都保持一致,又如何保证修改一个配置能够把这次修改同步到所有机器中呢?

再举个数据库主从例子,比如你的服务请求太大了,一台数据库已经无法支撑这么大量的请求,你又一个办法就是把数据复制到多个数据库上,这样可以分担请求压力,实现采用负载均衡技术就可以实现请求压力的分散。但是问题来了,如何保证每一个数据库都有相同的数据呢?现在一般主流解决方案都是数据库主从模式,一个主库做写,另外多个从库做读使用,这也意味着上层业务属于读多写少的业务。那一个数据写入之后,就必须把数据复制到其他从库上。这样其他读请求才可以看到。

根据读请求看到新写入数据的时机,我们又把这种一致性模型分成强一致性,弱一致性和最终一致性。
- 强一致性:就是更新之后的数据,读请求立即可以见到。
- 要做到这个意味着,你的数据必须更新到从库之后,写才打算执行成功,才能返回。当然也不一定是非要等到所有的从库都更新完,可以更新一半以上写操作就算成功并返回,此时读操作就不能简单只读某一个从库了,得同时读一半以上的从库,根据鸽巢原理,这样必定能读到一个最新的数据,我们可以给数据更新加版本号,读出来的所有数据看那个版本最新,就取哪一个。
- 弱一致性:就是更新之后的数据,读请求不能立即看到。
- 系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。但会尽可能保证在某个时间级别(比如秒级别)之后,可以让数据达到一致性状态。
- 最终一致性:更新数据之后走,不保证更新数据立即课件,也不会保证多久可见,但一定在某个时间会可见。
- 弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响

实际上一致性模型并不是这么简单的三大类,他有很多应用场景和细分类别。都是根据不同需求和应用场景来划分的。分布式系统一致性分类,你知道几种?. 本文不再赘述这些一致性模型,超出了范围。

Zookeeper的重要特性

Zookeeper 提供的最常用的两个基本特性就是基于内存的文件系统操作和事件通知机制,而且这些增删改操作都是原语性质的(对所有的客户端来说)。

Zookeeper 文件系统

数据以目录树的结构存储在内存之中,使得Zookeeper处理数据更快,可以保证高吞吐量和低延迟,但同时数据存储的瓶颈也是内存容量,因此Zookeeper 不能存储海量数据,只能存储少量或者中等规模的数据。目录树节点的存储数据上限是1M.

Zookeeper 文件目录节点znode类型

  1. PERSISTENT-持久化目录节点
    客户端与zookeeper断开连接后,该节点依旧存在
  2. PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
    客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
  3. EPHEMERAL-临时目录节点
    客户端与zookeeper断开连接后,该节点被删除
  4. EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
    客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

Zookeeper 事件通知机制

client端会对某个znode建立一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,然后client可以根据znode变化来做出业务上的改变等。 比如某个锁(具有某种标识的节点)被释放了,其他客户端就可以被通知来获取锁。

Zookeeper的广泛应用场景

  1. 命名服务
  2. 配置管理
  3. 集群管理
  4. 分布式锁
  5. 队列管理

分布式系统中数据一致性和多处理器cache一致性对比