【181110】分布式协调服务的自我修养(zookeeper)

随着互联网技术的发展,大型网站需要的计算能力和存储能力越来越高,网站架构逐渐从集中式转变成分布式系统。

虽然分布式相对于集中式系统有比较多的优势,比如更高更强的计算、存储、处理能力等。但同时也引入了其他一些问题,比如如何在分布式系统中保证数据的一致性和可用性。

在日常中,如果两个员工或用户对某件事产生了分歧,通常我们的做法是找上级,去做数据和信息的同步。

那么对于我们的服务呢,多个节点之间数据不同步如何处理?

在单机发展到集群、分布式服务的过程中,每一件技术或工具都走向了系统化,专一化的道路。举个例子,在单体应用中,如果多个线程想对同一个变量进行修改,我们通常的做法是对要修改的变量或资源加锁。那么对于集群来说,并没有这样的东西,我们应该怎么做?

对于分布式集群来说,这个时候,我们通常需要一个能够在各个服务或节点之间进行协调服务或中间人

架构设计中,没有一个问题不能通过一层抽象层来解决,如果有,那就是两层。

集群管理

我们可以一起看看,协调服务中的佼佼者--ZooKeeper

zookeeper起源

zoo

最初,在Hadoop生态中,会存在很多的服务或组件(比如hive、pig等),每个服务或组件之间进行协调处理是很麻烦的一件事情,急需一种高可用高性能数据强一致性的协调框架。因此雅虎的工程师们创造了这个中间程序,但中间程序的命名却愁死了开发人员,突然想到hadoop中的大多是动物名字,似乎缺乏一个管理员,这个程序的功能有是如此的相似。因此zookeeper诞生。

zookeeper提供了哪些特性,以便于能够很好的完成协调能力的处理呢?

功能与特性

数据存储

zookeeper提供了类似Linux文件系统一样的数据结构。每一个节点对应一个Znode节点,每一个Znode节点都可以存储1MB(默认)的数据。

客户端对zk的操作就是对Znode节点的操作。

zookeeper数据结构
  • Znode:包含ACL权限控制、修改/访问时间、最后一次操作的事务Id(zxid)等等
  • 说有数据存储在内存中,在内存中维护这么一颗树。
  • 每次对Znode节点修改都是保证顺序和原子性的操作。写操作是原子性操作。

举个例子,在注册中心中,可以通过路径"/fsof/服务名1/providers"找到"服务1"的所有提供者。

每一个Znode节点又根据节点的生命周期类型分为4种节点。

zookeeper节点
  • 生命周期:当客户端会话结束的时候,是否清理掉这个会话创建的节点。持久-不清理,临时-清理。
  • 类型:每一个会话,创建单独的节点(例子:正常节点:rudytan,顺序编号节点:rudytan001,rudytan002等等)

监听机制

zookeeper除了提供对Znode节点的处理能力,还提供了对节点的变更进行监听通知的能力。

zookeeper监听机制

监听机制的步骤如下:

  1. 任何session(session1,session2)都可以对自己感兴趣的znode监听。
  2. 当znode通过session1对节点进行了修改。
  3. session1,session2都会收到znode的变更事件通知。

节点常见的事件通知有:

  • session建立成功事件
  • 节点添加
  • 节点删除
  • 节点变更
  • 子节点列表变化

需要特别说明的是:

一次监听事件,只会被触发一次,如果想要监听到znode的第二次变更,需要重新注册监听。

到这里,我们了解到zookeeper提供的能力,那我们在哪些场景可以使用它?如何使用它呢?

应用场景

zookeeper用得比较多的地方可能是,微服务的集群管理与服务注册与发现。

注册中心

注册中心模型
  • 依赖于临时节点
  • 消费者启动的时候,会先去注册中心中全量拉取服务的注册列表。
  • 当某个服务节点有变化的时候,通过监听机制做数据更新。
  • zookeeper挂了,不影响消费者的服务调用。

目前还有个比较流行的服务Eureka也可以做注册中心,他们有什么优势和劣势呢?留个疑问,哈哈哈。

分布式锁

分布式锁
  • 依赖于临时顺序节点
  • 判断当前client的顺序号是否是最小的,如果是获取到锁。
  • 没有获取到锁的节点监听最小节点的删除事件(比如lock_key_001)
  • 锁释放,最小节点删除,剩余节点重新开始获取锁。
  • 重复步骤二到四。

redis和db也能创建分布式锁,哪有什么异同呢?留个疑问,哈哈哈。

分布式锁可以参考我的另一篇文章:分布式锁 https://www.jianshu.com/p/e4174e499798

集群管理与master选举

集群管理与master选举
  • 依赖于临时节点
  • zookeeper保证无法重复创建一个已存在的数据节点,创建成功的client为master。
  • 非master,在已经创建的节点上注册节点删除事件监听。
  • 当master挂掉后,其他集群节点收到节点删除事件,进行重新选举
  • 重复步骤二到四

当然还有其他应用场景,不一一列举了。

有人说,zookeeper可以做分布式配置中心、分布式消息队列,看到这里的小伙伴们,你们觉得合适么?

到这里,可以基本上满足基于zk应用开发的理论知识储备。对原理或有更强求知欲的小伙伴可以继续往下看,接下来聊聊zookeeper如何做到高性能高可用强一致性的。

高性能高可用强一致性保障

高性能-分布式集群

zookeeper集群部署

高性能,我们通常想到的是通过集群部署来突破单机的性能瓶颈。对于zk来说,就是通过部署多个节点共同对外提供服务,来提供读的高性能。

  • Master/Slave模式。
  • 在zookeeper中部署多台节点对外提供服务,客户端可以连接到任意一个节点。
  • 每个节点的数据都是一样的。
  • 节点根据角色分为Leader节点与Learner节点(包括Follower节点与Observer节点)。
  • 集群中,只有一个Leader节点,完成所有的写请求处理。
  • 每次写请求都会生成一个全局的唯一的64位整型的事务ID(可以理解为全局的数据的版本号)。
  • Learner节点可以有很多,每个Leaner可以独自处理读请求,转写请求到Leader节点。
  • 当Leader节点挂掉后,会从Follower节点中通过选举方式选出一个Leader提供对外服务。
  • Follower节点与Observer节点区别在于不参与选举和提议的事务过半处理。
  • 集群通常是按照奇数个节点进行部署(偶然太对容灾没啥影响,浪费机器)。

数据一致性(zab协议-原子广播协议)

通过集群的部署,根据CAP原理,这样,可能导致同一个数据在不同节点上的数据不一致。zookeeper通过zab原子广播协议来保证数据在每一个节点上的一致性。原子广播协议(类似2PC提交协议)大概分为3个步骤。

zab原子广播协议
  • Leader包装写请求,生成唯一zxid,发起提议,广播给所有Follower。
  • Follower收到提议后,写入本地事务日志,根据自身情况,是否同意该事务的提交。
  • Leader收到过半的Follower同意,自己先添加事务。然后对所有的Learner节点发送提交事务请求。

需要说明的是,zookeeper对数据一致性的要求是:

  • 顺序一致性:严格按照事务发起的顺序执行写操作。
  • 原子性:所有事务请求的结果在集群中的所有节点上的应用情况是一致的。
  • 单一视图:客户端访问任何一个节点,看到的数据模型都是一致的。
  • 实时性:保证在极小一段时间客户端最终可以从服务读取最新数据状态(如果要实时,需要客户端调用syn方法)。

可用性-leader选举(zab协议-崩溃恢复协议)

在整个集群中,写请求都集中在一个Leader节点上,如果Leader节点挂了咋办呢?

zab崩溃恢复协议

当集群初始化或Follower无法联系上Leader节点的时候,每个Follower开始进入选举模式。选举步骤如下:

  1. Follower节点第一次投票先投自己,然后将自己的选票广播给剩余的Follower节点。
  2. Follower节点接收到其他的选票。
  3. 选票比较:比较自己的与接收的选票的投票更有。
  4. 如果资金的选票不是最优选票,变更自己的选票,投最优选票的节点。
  5. 统计自己收到的选票,如果某个节点获得了过半的节点的投票。确认该节点为新的Leader节点。
  6. 确认Leader节点后,每个节点变更自己的角色。完成投票选举。

选举原则:谁的数据最新,谁就有优先被选为Leader的资格。

举个例子,假如现在zk集群有5个节点,然后挂掉了2个节点。剩余节点S3,S4,S6开始进行选举,他们的最大事务ID分别是6,2,6。定义投票结构为(投票的节点ID,被投节点ID,被投节点最大事务ID)。

zookeeper选举举例
  1. 初始状态,S3,S4,S5分别投自己,并带上自己的最大事务ID。
  2. S3,S4,S5分别对自己收到的2票与自己的1票做比较。
  3. S5发现自己的是最优投票,不变更投票,S3,S4发现S5的投票是最优解,更改投票。
  4. S3,S4广播自己变更的投票。
  5. 最后大家都确认了S5是Leader,S5节点状态变更为Leader节点,S3,S4变更为Follower节点。

到这里,就是选举的主要过程。

数据的持久化

数据的恢复与持久化
  • zookeeper所有数据都存在内存中。
  • zookeeper会定期将内存dump到磁盘中,形成数据快照
  • zookeeper每次的事务请求,都会先接入到磁盘中,形成事务日志
  • 全量数据 = 数据快照 + 事务日志。

比较

前面也提到过,不同的应用场景似乎有不少替代品,我们就大概做个简单的比较。

注册中心的比较(与Netflix的Eureka方案)

Eureka架构图

通过上面的架构图,可以发现Eureka不同于zk中的节点,Eureka中的节点每一个节点对等。是个AP系统,而不是zk的CP系统。在注册中心的应用场景下,相对于与强数据一致性,更加关心可用性。

分布式锁(与redis、mysql比较)

分布式锁可以参考我的另一篇文章:分布式锁(redis/mysql) https://www.jianshu.com/p/e4174e499798

具体差异比较:

  • Redis:简单,可靠性不高
  • DB:稳定、性能有所不足
  • ZK: 比较高的性能和完整的锁的实现,但实现复杂度高,并发不高。

通过这些比较,我们为什么还需要或在什么场景下使用zookeeper呢。我觉得就一句话:

zookeeper,一种通用的分布式协调服务解决方案。

感悟

最后,说说在整个学习和使用zk过程中的一个感悟吧。

  • 没有银弹,每一种技术或方案都有其优点和缺点。
  • 做一件事情很简单,做好一件事件很难。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容