在之前的一篇文章中有提到,我们作了一些ZooKeeper
上的资源管理实践。
其中,涉及到的ZooKeeper资源访问和配额控制,都需要高版本的ZooKeeper
才能支持,例如硬规则Quota
需要3.7.0
版本,Quota Metrics to Prometheus
需要3.8.0
版本。
But,我们的ZK版本是3.4.9
。
因此,我们需要对ZooKeeper
进行升级。
ZK使用场景
目前我们对于ZK的使用场景很多,包含服务注册与发现、数据同步与一致性保证、分布式锁等。
但是总体来看,可以分为两大类:
-
跨服务协同,涉及服务间的数据同步和一致性需求,例如
Dubbo
,存在Provider和Consumer,不是在同一个服务里; -
单服务跨节点协同,往往是单服务分布式部署所带来的数据一致性需求,例如ElasticJobs、分布式锁、ID生成等。
ZK升级策略
对于不同类型的使用场景,我们可以采用不同的策略。
影响范围
-
跨服务协同,主要以Dubbo为主,框架成熟稳定,其本身不会带来ZK资源问题,同时该适用场景涉及所有业务及基础服务的注册及发现,影响面较大。因此,对于这部分适用场景~不建议升级~,以稳定为主。
-
单服务跨节点协同,这类场景更多是限制在单个服务内的,升级的影响范围可用,且可以不用做数据迁移。因此,我们直接创建一个新的ZK节点,将这部分使用场景~直接迁移到新版本ZK~。
目标版本
由于我们的ZK管理规则需要使用到硬规则Quota
及Quota Metrics
,所以计划升级到最新的3.8.1
版本。
升级方案
综上所述,我们需要创建一个3.8.1
版本的新ZooKeeper
集群,并将单服务跨节点协同场景下的业务服务迁移到新的ZK集群上。
那么,在这个过程就会有非常多的因素需要考虑,其中最主要的就是兼容性以及性能评估。
升级兼容性
在考虑ZK兼容性时,我们主要从三个维度来考虑。
- ZK Server兼容性;
- ZK Client兼容性;
- Apache Curator兼容性。
这里你可能会有疑问,考虑Server、Client兼容性时合理的,那么Apache Curator又是什么?为什么要考虑Apache Curator的兼容性呢?
1 |
|
综上所诉,Curator
是ZK Client的高级封装API,并提供了通用内容的封装和扩展。
在我们的业务服务及部分依赖框架中,都是通过Curator
来操作ZK的,我们并不确定低版本Curator是否兼容高版本ZK Server,所以也需要考虑其兼容性。
Curator 版本: org.apache.curaotr:curator-client:2.10.0/2.12.0 org.apache.curaotr:curator-framework:2.10.0/2.12.0 org.apache.curaotr:curator-recipes:2.10.0/2.12.0
ZK Client 版本: org.apache.zookeeper:zookeeper:3.4.8
ZK Server 版本: Apache ZooKeeper:3.4.8
当Server需要升级到3.8.1时,不确定Curator 2.12是否兼容3.8.1的Server。
那么,我们一个个来看看他们的兼容性。
Server及Client兼容性
ZK官方提供了过往版本的Release Note,并且默认对前两个大版本的Server、Client进行兼容性测试,以最新两个版本的Release Note为例,我们来看看具体内容。
1 |
|
1 |
|
其中,3.7、3.8都对过往2~3个大版本Server、Client的升级兼容性做了测试。
- Server层面完全兼容,无需额外操作可直接升级。
- Client层面旧接口完全兼容,新特性使用需要升级Client。
由于我们的ZK从旧版本升级到新版本,不涉及新特性的使用,其向下兼容的特性无需我们做额外的工作。
但是,我们的版本升级跨度比较大,所以还是对常见的Client操作进行了测试,包含ZNode基础操作、Client监听事件、ZNode子节点监听事件、ACL、quota、事务等,初步判断旧版本Client可以兼容新版本Server。
Apache Curator兼容性
Apache Curator包含多个模块,以不同的制品发布,每个模块也提供不同的内容。
GroupID/Org | ArtifactID/Name | Description |
---|---|---|
org.apache.curator | curator-recipes | ZooKeeper 分布式协调服务的所有配方。 |
org.apache.curator | curator-async | 包含 O/R 建模、迁移等许多功能的异步 DSL。 |
org.apache.curator | curator-framework | Curator Framework 高级 API。它是建立在客户端之上并应该会自动引入客户端。 |
org.apache.curator | curator-client | Curator Client,它取代了 ZK 分发中的 ZooKeeper Class。 |
org.apache.curator | curator-test | 包含 TestingServer、TestingCluster 和其他几个有用的测试工具。 |
org.apache.curator | curator-examples | 各种 Curator 特性使用示例。 |
org.apache.curator | curator-x-discovery | 基于 Curator Framework 构建的服务发现实现。 |
org.apache.curator | curator-x-discovery-server | 一个 RESTful 服务器,可以与 Curator Discovery 一起使用。 |
我们主要使用的是Curator Client、Curator Framework,所以需要针对这两个模块进行兼容性测试。
在测试方案上,我们通过改写两个模块的测试用例,将原有的2.10.0版本中测试用例里的Mock ZooKeeper Server
改为直连3.8.1的ZK Server,并调试验证这批官方测试用例在3.8.1 Server上是否能正常执行,以此来判断其兼容性。
最终运行情况如下:
除部分需要验证ZK集群功能的用例失败外,其他测试用例均运行通过,证明Curator 2.10.0版本是兼容ZK Server 3.8.1的。
性能测试
在我们的使用场景里,ZK的使用场景并不多,但是都比较重要,用于服务注册发现、数据一致性等,整体线上负载并不高。
从收发包可以看出,基本都是心跳包为主。
但是介于我们之前出现过节点数突增及大节点的问题,所以也计划对新的3.8.1
进行压测,评估影响。
压测工具 - YCSB
在ZK的官方文档中,在Tools模块推荐了对应的Benchmark工具 - YCSB
,其提供了比较完整的压测能力,比如造数、发压、基础数据统计分析能力等。
- Workload
在发压能力上,它提供了预定义的工作负载Workload
,不同的负载属性不同。
类型 | 说明 |
---|---|
Workload A | Update heavy workload, 50/50 reads and writes |
Workload B | Read mostly workload, 95/5 reads/write mix |
Workload C | Read only, 100% read |
Workload D | Read latest workload, the most recently inserted records are the most popular |
Workload E | Short ranges, short ranges of records are queried, instead of individual records |
Workload F | Read-modify-write, client will read a record, modify it, and write back the changes |
除了预定义的工作负载外,也支持通过参数、插件进行自定义,可以根据需要进行设置。
- Core properties
在参数上,也提供了比较丰富的支持,可以自定义造数模型及数量、发压配置和数据统计、测量类型等。
基础环境及架构
我们线上的ZK集群很小,单个集群3~5节点,单节点配置4C16GB,从ZK Client 到 ZK Server之间的链路也比较简单。
我们的线上环境部署在阿里云上,在中间有一层SLB负载均衡,缓解了客户端连接的压力,实际到单个ZK节点的连接数在1100~1200左右。
基础场景测试
单节点直连场景,在ZK推荐节点大小(不超过1K)的场景下,单ZK Server
的节点读OPS可达至少15000,但是此时性能也开始出现下降,平均响应时间及99线均快速上涨。
大节点操作场景测试
在ZK Node较大的场景下,可以看到首先出现问题的是网络和磁盘,内网SLB流量达到瓶颈,磁盘由于频繁的大节点更新,datalog快速膨胀,磁盘被打满。
因此,是需要关注或限制大节点使用的,同时对于频繁写/更新的场景,需要关注磁盘及网络IO状态。
百万节点操作场景测试
在节点超过百万后,对ZK整体的性能并没有什么影响,这也是由于ZK本质上是一个KV存储。
节点批量删除
网上有很多文章都说了ZK这个参数上的坑,这次也实际遇到了,由于删除
总结
综上所述,我们将ZooKeeper从3.4.9升级到3.8.1版本,升级策略是通过将部分合适的业务场景直接迁移到新ZK上,避免了数据迁移,同时我们也做了基于Client、Server以及Apache Curator的兼容性测试,判断完全兼容可进行迁移。
目前我们已经完成部分服务的迁移试点,未发现新的问题。