writeline是什么意思_漫画:什么是 ZooKeeper?

4a547ac6e130bc5fe79803ec5f13c3f1.gif

2165183d136b953b52f62de10c7db473.png

96d9c286637c9509bee1fc34e19127f1.png

—————  第二天  —————

1d74eaa6f6f60fe25eb004c54e319c1d.png

df33bbc2677595f34943c43bde5e95b8.png

c1dbea05ad80a500b5fb860701b93838.png

55e30dc506ef23c9912c17f2616f3993.png

21ad4df5b81e39914a3987bd9a327a20.png

cef60221fd9b3d4eac4d2c67d75c027a.png

cd175ed6e971771a0b9a5ddaf1a2c5cf.png

23cd5fdc453ca28ed27596da87e8943e.png

fa87bb0c539c5dd0dce10637249d8399.png

7fed2d131e170d05e0ab750a6be10be2.png

————————————

f24284732625c8a2c51afa55ab6f65e4.png

a018bea3e6d747d630cc1fd0ab1f25bf.png

f035262edea01d5fa641eee3c421d554.png

be2a643e6115825a60ade3d732ce064b.png

c0c71bd0fdceeffc7b2fa21277b375b5.png

767504be8f79be37c5dbc454d0fcae49.png

4c5650a5c79334b54528372d461e677e.png

59bc8e91d850d2a163e056b7a8606c95.png

ZooKeeper 的数据模型

ZooKeeper 的数据模型是什么样子呢?它很像数据结构当中的树,也很像文件系统的目录。

d2dbd5011d6609113e3de32fad961e9c.png

树是由节点所组成,ZooKeeper 的数据存储也同样是基于节点,这种节点叫做 Znode

但是,不同于树的节点,Znode 的引用方式是路径引用,类似于文件路径:

 / 动物 / 仓鼠

 / 植物 / 荷花

这样的层级结构,让每一个 Znode 节点拥有唯一的路径,就像命名空间一样对不同信息作出清晰的隔离。

421d4aab7cdb1954e8e55cf7baa07be0.png

076a691fd95d5fdbaa6729fa95e17957.png

26f2740fa62c0445b0de62ec784e58cc.png

data:Znode 存储的数据信息。

ACL:记录 Znode 的访问权限,即哪些人或哪些 IP 可以访问本节点。

stat:包含 Znode 的各种元数据,比如事务 ID、版本号、时间戳、大小等等。

child:当前节点的子节点引用,类似于二叉树的左孩子右孩子。

这里需要注意一点,ZooKeeper 是为读多写少的场景所设计。Znode 并不是用来存储大规模业务数据,而是用于存储少量的状态和配置信息,每个节点的数据最大不能超过 1MB。

53e9f3c1cbd37fe751c6a6bca08dec49.png

6557636e18bdd405d76e206f94a855a4.png

20d0ab1ccc9d0d653b1404d9394b43e1.png

ZooKeeper 的基本操作和事件通知

ZooKeeper 包含了哪些基本操作呢?这里列举出比较常用的 API:

create:创建节点

delete:删除节点

exists:判断节点是否存在

getData:获得一个节点的数据

setData:设置一个节点的数据

getChildren:获取节点下的所有子节点

这其中,exists、getData、getChildren 属于读操作。ZooKeeper 客户端在请求读操作的时候,可以选择是否设置 Watch。

Watch 是什么意思呢?

我们可以理解成是注册在特定 Znode 上的触发器。当这个 Znode 发生改变,也就是调用了 create、delete、setData 方法的时候,将会触发 Znode 上注册的对应事件,请求 Watch 的客户端会接收到异步通知。

具体交互过程如下:

1. 客户端调用 getData 方法,Watch 参数是 true。服务端接到请求,返回节点数据,并且在对应的哈希表里插入被 Watch 的 Znode 路径,以及 Watcher 列表。

d6e655c3533671c9394a8882f95dd101.png

2. 当被 Watch 的 Znode 已删除,服务端会查找哈希表,找到该 Znode 对应的所有 Watcher,异步通知客户端,并且删除哈希表中对应的 Key-Value。

dcc185c4ff78b29df41cce0c45b6a700.png

8e3da2b4e635d27c96766fac588766a5.png

ZooKeeper 的一致性

78abafefed1cd9b8023f9d7594371fd4.png

b17ef372c8f2d011501c4cdc02723501.png

ZooKeeper 的集群长成什么样呢?就像下图这样:

5710ee06929053877d9c3c7326eab417.png

ZooKeeper Service 集群是一主多从结构。

更新数据时,首先更新到主节点(这里的节点是指服务器,不是 Znode),再同步到从节点。

在读取数据时,直接读取任意从节点。

为了保证主从节点的数据一致性,ZooKeeper 采用了 ZAB 协议,这种协议非常类似于一致性算法 Paxos 和 Raft。

f37eec1feba213ce05fb376ceaef4e63.png

258e25fd883bfaec064aef65c8cff75d.png

在学习 ZAB 之前,我们需要首先了解 ZAB 协议所定义的三种节点状态:

Looking:选举状态。

Following:Follower 节点(从节点)所处的状态。

Leading:Leader 节点(主节点)所处状态。

我们还需要知道最大 ZXID 的概念:

最大 ZXID 也就是节点本地的最新事务编号,包含 epoch 和计数两部分。epoch 是纪元的意思,相当于 Raft 算法选主时候的 term。

假如 ZooKeeper 当前的主节点挂掉了,集群会进行崩溃恢复。ZAB 的崩溃恢复分成三个阶段:

1. Leader election

选举阶段,此时集群中的节点处于 Looking 状态。它们会各自向其他节点发起投票,投票当中包含自己的服务器 ID 和最新事务 ID(ZXID)。

42b9520339004c40b3edef0cff4d3de0.png

接下来,节点会用自身的 ZXID 和从其他节点接收到的 ZXID 做比较,如果发现别人家的 ZXID 比自己大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大的 ZXID 所属节点。

5290f19af9fe3f6f8077c6b4d794d6d4.png

每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准 Leader,状态变为 Leading。其他节点的状态变为 Following。

613ff374dbdbd0099cd176199758ee5f.png

这就相当于,一群武林高手经过激烈的竞争,选出了武林盟主。

2. Discovery

发现阶段,用于在从节点中发现最新的 ZXID 和事务日志。或许有人会问:既然 Leader 被选为主节点,已经是集群里数据最新的了,为什么还要从节点中寻找最新事务呢?

这是为了防止某些意外情况,比如因网络原因在上一阶段产生多个 Leader 的情况。

所以这一阶段,Leader 集思广益,接收所有 Follower 发来各自的最新 epoch 值。Leader 从中选出最大的 epoch,基于此值加 1,生成新的 epoch 分发给各个 Follower。

各个 Follower 收到全新的 epoch 后,返回 ACK 给 Leader,带上各自最大的 ZXID 和历史事务日志。Leader 选出最大的 ZXID,并更新自身历史日志。

3. Synchronization

同步阶段,把 Leader 刚才收集得到的最新历史事务日志,同步给集群中所有的 Follower。只有当半数 Follower 同步成功,这个准 Leader 才能成为正式的 Leader。

自此,故障恢复正式完成。

08591326d42d2bd9d71a155e9db7f1cd.png

9a4a25438c1106061868040481240738.png

什么是 Broadcast 呢?简单来说,就是 Zookeeper 常规情况下更新数据的时候,由 Leader 广播到所有的 Follower。其过程如下:

1. 客户端发出写入数据请求给任意Follower。

2. Follower 把写入数据请求转发给 Leader。

3. Leader 采用二阶段提交方式,先发送 Propose 广播给 Follower。

4. Follower 接到 Propose 消息,写入日志成功后,返回 ACK 消息给 Leader。

5. Leader 接到半数以上 ACK 消息,返回成功给客户端,并且广播 Commit 请求给 Follower。

53e8113bcdc3960d0f70fc700b2293ec.png

ZAB 协议既不是强一致性,也不是弱一致性,而是处于两者之间的单调一致性。它依靠事务 ID 和版本号,保证了数据的更新和读取是有序的。

2606d147f249724d93f2150a17df2f09.png

ZooKeeper 的应用

2b603ed404a2e054c53fa2e09182c860.png

9c8b20236372c50a9b6a9ee4cc83eeca.png

1. 分布式锁

这是雅虎研究员设计 ZooKeeper 的初衷。利用 ZooKeeper 的临时顺序节点,可以轻松实现分布式锁。

2. 服务注册和发现

利用 Znode 和 Watcher,可以实现分布式服务的注册和发现。最著名的应用就是阿里的分布式 RPC 框架 Dubbo。

3. 共享配置和状态信息

Redis 的分布式解决方案 Codis,就利用了 ZooKeeper 来存放数据路由表和 codis-proxy 节点的元信息。同时 codis-config 发起的命令都会通过 ZooKeeper 同步到各个存活的 codis-proxy。

此外,Kafka、HBase、Hadoop 也都依靠 ZooKeeper 同步节点信息,实现高可用。

0ae23cc4eec694584c472c7f0240c006.png

9994f13d3da6c1bdae574afbe58aafab.png

补充:

ZAB 协议相对比较复杂,小灰对此也只是浅层次的理解,有兴趣的小伙伴们可以去官方社区进行进一步学习。

本漫画纯属娱乐,还请大家尽量珍惜当下的工作,切勿模仿小灰的行为哦。

声明:本文为作者投稿,首发于个人公众号程序员小灰,版权归其所有。


 热 文 推 荐 

☞ 董明珠给格力员工加薪 10 亿;张小龙回应微信 7.0 界面变丑;库克怒怼高通 | 极客头条

☞ 微软在一步一步把 Windows 10 玩出碎片化?

☞ 编程时千万要记下一切!

☞ 君士坦丁堡硬分叉姗姗来迟,以太坊2.0还要等多久?

☞ 2018,这一年的腾讯优图,我们总结一下!

☞ 特斯拉“撞死”机器人,是炒作还是事故?

☞ 程序员的年度未解之谜:加班背锅的是我,得优秀员工的却是他

☞ 趣挨踢 | 关于遗留代码的那些事儿

print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");print("点个好看吧!");printf("点个好看吧!\n");
cout <"点个好看吧!" <Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");alert("点个好看吧!")echo "点个好看吧!"

c1404973eea3af2f1f4e1d6daefc79ae.gif点击“阅读原文”,打开 CSDN App 阅读更贴心!

f96bc9882e061f1bed200ed8d3a28d5f.png 喜欢就点击“好看”吧!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值