ZooKeeper 在阿里巴巴的服务形态演进历程
早在 2008 年,阿里巴巴基于 ZooKeeper 的开源实现和淘宝的电商业务,设计 Taokeeper 这款分布式协调软件,彼时恰逢淘宝启动服务化改造,那时候,也诞生了各类分布式中间件,例如
HSF/ConfigServer/VIPServer 等。
10 年后的 2019 年,阿里巴巴实施全站上云战役,所有的产品都需要升级到公有云架构,MSE 就是在那个时候诞生的,上线后便兼容了主流的 ZooKeeper 版本。
整个过程经历了以下 3 个阶段:
第一个阶段:08 年的 1.0 版本,主要支持集团有分布式协调需求的应用,那时候所有的业务都是混着用,有 1000 多个应用,最终大概手动运维着 150+个共享集群。随着时间的推移,业务都在做微服务拆分,共享集群的容量爆炸式增长,这样带来的问题就是:业务混部,爆炸半径大,稳定性存在着很大的风险;日常的运维,例如机器置换等,牵一发而动全身,如果配置出问题,影响所有业务。
第二个阶段:为了解决阶段一的问题,我们将 ZooKeeper 演进到 2.0 版本。那时候正直容器化刚刚兴起,在仔细研究过容器化的改造方案后,我们在性能和运维能够同时满足要求的情况下,进行了大量的改造,业务进行拆分、集群迁移、按最小稳定单元去运维一个集群,这样我们终于可以睡个安稳觉了,拆分完后,依托于 K8s 的规模化运维能力,这些问题都得到了很好的解决,由此实现了独享模式集群、资源隔离,SLA 得到了提升,能到达 99.9%。
第三个阶段:上云提供公共云服务,也就演进到了 3.0。这个版本重点打造了开源增强,例如,基于 Dragonwell 进行构建、JVM 参数调优、集成了 Prometheus、部署形态多 AZ 强制平均打散、支持动态配置 、平滑扩缩容等改造,在性能、免运维、可观测、高可用和安全等方面做了诸多提升,SLA 能够到达 99.95%。
ZooKeeper 在技术场景上的最佳实践
接下来,给大家介绍下 ZooKeeper 的最佳实践场景,归为了 3 类,分别是:
微服务领域-注册中心
ZooKeeper 在微服务场景里面,主要是用作注册中心,利用了 ZooKeeper 的注册/订阅模式,可以看下 Dubbo 在 ZooKeeper 里面的数据结构:
在 Provider 启动时,会向 ZooKeeper 固定路径 providers 下面创建一个临时节点, 在这个节点里面存入本机的服务信息,例如,应用名,IP 和端口等,Consumer 启动的时候 ,监听对应服务下 Providers 的所有子节点,ZooKeeper 会把所有子节点信息主动通知到 Consumer,Consumer 此时就拿到所有 Provider 的地址列表信息了,Provider 注册到 ZooKeeper 上面的临时节点,它的生命周期和 Provider 与ZooKeeper 之间建立的长链接时一致的,除非 Provider 主动下线,当 Provider 宕机或者主动下线,这个临时节点就会被删除,那么订阅这个服务的 Consumer 们,会通过 Watch 监听到事件,更新一下地址列表,把它摘除调。
在这里有 2 个注意的点:
大数据领域-HA 高可用
在大数据领域,Flink/Hadoop/Hbase/Kafka 等系统都默认的把 ZooKeeper 当作分布式协调的组件,在这里面,ZooKeeper 利用自己的特性,帮助它们解决了非常多的分布式问题,其中最主要的就是利用 ZooKeeper 做了 HA(Highly Available)方案,提高集群可用性,一般有两个或两个以上的节点,且分为活动节(Active)点及备用节点(standby)。
下方图例中有 2 个 Server,组成 HA 模式,在 Server 启动的时候,往 ZooKeeper 写入一个约定好的路径下临时节点,由于 ZooKeeper 只允许 1 个写成功,谁先写成功,谁就作为 Active, 并且由 ZooKeeper 通知到集群中其他节点,其他节点则状态改成 standby 状态。
当 Active 节点宕机的时候,ZooKeeper 将节点状态通知下去,其他的 standby 节点立刻往该节点里面写数据,写成功了,就接替成为 Active。
整个流程大概就是这样,这里要注意一个点,就是在 络异常情况下,主备节点切换不那么实时,可能会出现脑裂,也就是存在 2 个主节点的情况,这种情况的话,可以客户端在切换的时候,可以尝试等一等,状态稳定之后,再切换。
自研系统的分布式协调场景
在自研分布式系统的时候,必然会遇到许多分布式协调的问题,ZooKeeper 就像一个万能的工具箱。
针对不同的场景,基于 ZooKeeper 的特性,都能组合成一个解决方案;在写分布式系统的时候,经常需要用到的有这几个功能:
我们的系统需要选举出来 1 个 Maseter 来执行任务;例如 ScheduleX 就是利用 ZooKeeper 做到这个的,Schedulex 的 Worker 节点有非常多,一些任务是非幂等的,只能由一个进程执行,这时候就需要从众多的 Worker 中选一个 master 来,实现的方式主要有 2 种:
在分布式环境中,程序都分布独立的节点中,分布式锁是控制分布式系统之间同步访问共享资源的一种方式,下面介绍下 Zookeeper 如何实现分布式锁,分布式锁主要有 2 种类型:
1、排他锁(Exclusive Locks):称为独占锁,获取到这个锁后,其他的进程都不允许读写
实现的原理也很简单,利用 ZooKeeper 一个具体路径下只能创建一个节点的特性,约定谁创建成功了,就抢到了锁,同时其他节点要监听这个变化,临时节点删除了,可以被通知到去抢(Create),这个和 Master 选举里面抢占 Master 节点,是一样的做法:
2、共享锁(Shared Locks):又称为读锁,多个进程可以同时获取这把锁,进行读操作,但是如果要写操作,必须没有读操作了,且自己是第一个获取到写操作类型锁的
实现的方式如图示;读的时候,创建一个 R 的临时顺序节点,如果比他小的节点里面没有 W 节点,那么写入成功,可以读,如果要写,则判断所有 R 的节点中,自己是否最小的即可。
分布式队列最常见的 FIFO(First Input First Output )先入先出队列模型,先进入队列的请求操作先完成后,才会开始处理后面的请求:
Zookeeper 实现 FIFO 队列,和共享锁实现类似,类似于一个全写的共享锁模型:
1、获取/Queue 节点下的所有子节点,获取队列中的所有元素
2、确定自己的节点序号在所有子节点中的顺序
3、如果自己的序号不是最小,那么就需要等待,同时向比自己序号小的最后一个节点注册 Watcher 监听
4、接收到 Watcher 通知后,重复第一个步骤
使用 ZooKeeper 作为配置中心,利用的也是 ZooKeeper 的注册/订阅模式,这里有个注意点,ZooKeeper 不适用于存储太大的数据,一般不超过 1M,否则容易出现性能问题。
MSE 提供的 ZooKeeper 企业服务
MSE 和 ZooKeeper 的关系
微服务引擎(Micro Service Engine,简称 MSE)是一个面向业界主流开源微服务生态的一站式微服务平台,微服务生态的所有服务都能够在这个平台上面被集成,它提供的引擎都是独立托管的,目的就是为了给大家提供高性能、高可用、高集成、安全的服务,目前,MSE 提供了如下模块:
ZooKeeper 和 Nacos 一样,提供注册配置中心功能,但是 ZooKeeper 还提供了分布式协调的能力,应用在大数据领域。
MSE 提供的 ZooKeeper 企业服务分为基础版和专业版两种,前者适用于开发测试环境和简单的生产环境,后者在性能、可观测、高可用方便做了诸多提升,接下来,我们将介绍专业版,相比自建的优势。
比自建的 ZooKeeper 更稳定和高可用
上面介绍的是架构设计上面,对高可用的一个保障。
在研发过程,我们有一套完备的稳定性保障体系:从研发阶段,到最后的变更上线,都有对应的规范制度,例如变更三板斧,在变更时,必须要满足可观测/可回滚/可灰度的情况下才能上线,否则会被打回;在运行时,我们有一系列的巡检组建,配置一致性检查,后面也会不断的完善,巡检出问题,立马需要解决。
MSE 也把故障演练做到了常态化,针对常见的故障场景,例如 络中断,CoreDNS 宕机、ECS 宕机等,都定期在跑着;在线上预警这块,我们也做到了主动探测,及时发现,安排值班人员 24 小时处理,我们有一套 1/5/10 的应急流程,要求在 1 分钟内发现问题,5 分钟解决,10 分钟恢复。
以上的这些,最终都是为了保障 MSE 的稳定高可用,MSE 线上最大规模的一个集群,支持着 40w+的长链接,稳定运行了 3 年的时间,没有出现过故障,SLA 达到 99.95%。
免运维,提供了丰富的控制台功能
如果是自建 ZooKeeper 的话,需要做哪些事:
而 MSE 提供的 ZooKeeper 企业服务,则将以上问题通过产品化的方式解决了:
需要一个 ZooKeeper 集群的时候,一键购买,3 分钟开箱即用,出现容量问题时,一键平滑扩缩容,还提供了重置数据、参数白屏化设置等功能,在可观测这块,也提供了常用的核心默认指标大盘,与之相配套的就是 警了。使用 ZooKeeper 企业服务,省心、省力,提高企业 IT ROI。
可观测性增强
ZooKeeper 专业版的第三个优势,可观测性的增强:
性能提升
写入性能优化提升 20%,数据可靠性达 99.9999999%(即 9 个 9)。
ZooKeeper 的写入性能, 和磁盘性能有很大的关系,必须要把数据写入到磁盘的事务日志成功后,才算写成功,为了提升写性能,我们采用了阿里云 ESSD 高性能云盘,最大 IOPS 能够达到 5W,最大吞吐量 350M/S,数据的可靠性 99.9999999%(即 9 个 9),整个写入 TPS 性能能够提升约 20%。
基于 Dragonwell 进行构建,读取性能提升 1 倍
我们集成了阿里高性能 JDK,开启了里面的协程优化能力,并对 ZooKeeper 的读写任务队列做了锁力度的优化,在高并发处理的场景下,读性能相比开源能够提升 1 倍左右的性能。
GC 时间降低 80%,大幅减少 Full GC 的情况
ZooKeeper 是时延敏感型的应用,GC 的时间和次数,会影响 ZooKeeper 的处理吞吐量,因此我们针对这种情况,做了 JVM 参数的调优,堆的设置根据不同的配置动态设置,同时提前做了资源碎片的回收,避免出现 FullGC,整体优化下来,GC 时间降低 80%,同时尽可能的避免了 FullGC。
基于 MSE,构建 Dubbo+Zookeeper 微服务
操作之前,需要购买一个 ZooKeeper,可以选择按量付费,不需要是可以释放,如果长期使用,可以选择包年包月:
在选择 络访问方式的时候,以下几种情况:
1、如果你只是使用 VPC 络使用,你就选择专有 络,选上交换机和专业 络,其他不用动(这里注意:不要去选择公 带宽)
2、如果你只是要公 访问,选择公 络,再选上对应的带宽即可;
3、如果需要公 ,同时也需要 VPC 络访问,那么你选择专有 络,同时在公 带宽处,选择你需要的公 带宽,这样就会创建 2 个接入点了;
购买之后,大概 5 分钟左右,ZooKeeper 集群就创建成功了,大家记住访问方式, 等会 Dubbo 配置文件里面需要配置这个地址:
环境准备好了,就准备 Provider/Consumer 的配置了。欲了解详细的操作步骤,可观看直播视频进行了解:
https://yqh.aliyun.com/live/detail/28603
原文链接:
http://click.aliyun.com/m/1000345145/
声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!