稳定性大幅度提升:SOFARegistry v6 新特性介绍
SOFARegistry 是蚂蚁集团内部在使用的服务注册中心,它支撑起了蚂蚁集团海量规模的业务服务。但随着蚂蚁集团业务规模的日渐庞大,SOFARegistry 在资源、容量、运维等方面也遇到了一些挑战,针对这一系列的挑战,我们对 SOFARegistry 进行了大量的改造,开发了 v6 版本的 SOFARegistry。
背景
1、v5 架构介绍
首先介绍一下我们的注册中心——SOFARegistry 现有的架构设计:采用双层存储架构,外加一个负责内部元数据管理的 Meta 组件;Session 为连接层,用于承载客户端的长连接,接收并转发客户端的注册信息到 Data 上;Data 为数据存储层,采用一致性 Hash 的数据分片方式实现水平扩容,同一个服务的 Publisher 会汇总到同一台 Data 上,同时采用多副本的方式实现高可用;Meta 为注册中心内部的管理组件,用于内部各个节点之间的互相发现。
支持海量数据:采用一致性 Hash 的数据分片方式,每台 DataServer 只存储一部分的分片数据,随数据规模的增长,只要扩容 ;DataServer 服务器即可。 支持海量客户端:连接层的 SessionServer 只负责跟 Client 打交道,SessionServer 之间没有任何通信或数据复制,所以随着业务规模的增长,SessionServer 可以较轻量地扩容,不会对集群造成额外负担。 秒级服务上下线通知:对于服务的上下线变化,SOFARegistry 使用推送机制,快速地实现端到端的传达。同时基于连接 + 心跳的探活设计,使得服务下线能更加及时的被发现。
2、一致性 Hash 数据分片
这边简单介绍一下 v5 版本 Data 做数据分片的方案:SOFARegistry 支持海量数据的存储,并使用了一致性 Hash 作为数据分片方案。每台服务器被虚拟成多个节点落在 Hash 环上,每个数据根据 Hash 算法计算出一个值,落到环上后顺时针命中的第一个虚拟节点,即负责存储该数据的主节点,后续命中的 N (N 为数据副本数)个不同节点作为存储该数据的副本节点。
在虚拟节点足够多的情况下,数据分片在每台节点上是非常分散均匀的,并且增加或减少节点的数量,还是能维持数据的平衡(SOFARegistry 默认虚拟点数为 1000)。
面临的挑战
在蚂蚁集团超大的业务规模下,现有的架构也遇到了很多的挑战。
1、超大规模集群
2、部署站点极多,建站和发布成本高
在蚂蚁集团内部,站点非常之多,各种租户,很多城市的数据中心都需要部署注册中心。同时注册中心本身的发布和运维是一个对整个集群影响非常大的动作,这就造成了注册中心的发布和建站人力成本巨大。
SOFARegistry v6 版本改造
针对现有的挑战,SOFARegistry v6 给出了对应的解决方案
通过应用级服务发现改造,减少注册中心存储的数据量,减少推送数据量。 基于 Slot 分配的数据分片存储,支持无损发布和灰度发布,减少 Data 宕机期间的影响。 nightly build,自动化部署流程,减少运维人力成本。
1、应用级服务发现改造
服务发现分类
(1)服务维度:实例的每一个服务都注册一个 Publisher,调用端使用服务名称寻址 IP 列表。
优点:服务的变更对调用方透明,针对新服务上线和微服务拆分的场景,可以做到调用方无感知。
数据模型改造
com.alipay.testapp1.FooService:1.0@DEFAULT
11.34.200.88:8080?v=4.0&_TIMEOUT=3000&_HOSTNAME=testapp1-85-5595&p1&app_name=testapp1&_SERIALIZETYPE=4&tls=false&mosn_version_none&mosn=true
com.alipay.testapp1.BarService:1.0@DEFAULT
11.34.200.88:8080?v=4.0&_TIMEOUT=3000&_HOSTNAME=testapp1-85-5595&p1&app_name=testapp1&_SERIALIZETYPE=4&tls=false&mosn_version=version_none&mosn=true
从原理上讲,主要是把一个应用中和代码版本相关的参数抽取为一份元数据,比如服务名称、协议、版本等等。这些参数一个应用的大多节点都是一致的,只有在版本进行发布的时候才会存在两份元数据,对于这些重复率很高的元数据,会对元数据本身计算一次 Hash,得到一个 Revision 字符串。其他的参数,比如 IP、端口等等,大多是只和所在节点相关的参数,那么这些多个服务下相同参数都可以汇聚成一个实例级的 Publisher,引用元数据上的 Revision,这样从整个集群来看,原先服务级 Publisher 中大部分数据都可以被抽取为一份元数据,可以节省大量的存储空间。
{
"application": "testapp1",
"revision": "testapp1-594f803b380a41396ed63dca39503542",
"clientVersion": "v1.1.0",
"baseParams": {
"__SERIALIZETYPE":{"values":["4"]},
"app_name":{"values":["testapp1"]},
"_TIMEOUT":{"values":["3000"]},
"tls":{"values":["false"]},
},
"services": {
"com.alipay.testapp1.FooService:1.0@DEFAULT": {
"id": "0",
},
"com.alipay.testapp1.BarService:1.0@DEFAULT": {
"id": "1",
}
}
实例 Publisher
{
"addr": "11.34.200.88:8080",
"rev": "testapp1-594f803b380a41396ed63dca39503542",
"mv": "v1.1.0",
"bps": {
"_HOSTNAME": ["testapp1-85-5595"],
"mosn_version":{"values":["version_none"]},
"mosn":{"values":["true"]},
}
}
如上元数据和 Publisher,结合两份数据,调用方就能还原这个节点发布了哪些接口以及有哪些参数,从而拼接出服务级的 URL。
平滑迁移
在完成绝大多数应用的应用级迁移后,全部的应用都已经到了 v6 版本的注册中心上,但仍然存在很少部分应用因为没有接入 MOSN,然后以服务级订阅发布和注册中心交互,为了确保已经改造完的应用和这部分没有改造的应用能够互相订阅,我们做了一些额外的支持:
服务级订阅端是无法直接订阅应用级发布数据的,所以我们实现了一个应用级 Publisher 转接口级 Publisher 的模块,可以按需转化出指定服务的 Publisher,没有接入 MOSN 的应用可以顺利的订阅到这部分数据,因为只有很少部分应用没有接入 MOSN,所以需要进行转化的服务数目同样也很少。 应用级订阅端在订阅的时候会额外发起一个服务级的订阅,用于订阅没有接入 MOSN 应用的发布数据,由于这部分应用非常少,实际绝大多数的服务级订阅都不会有推送任务。
改造效果
上图是我们压测的数据,对两个注册中心进行完全相同的操作,一个进行应用级发布订阅,一个进行服务级发布订阅,同时监控各种事件的发生频率。我们模拟的测试应用,每个应用发布了 100 个服务,订阅了 200 个服务。应用级改造的优化非常明显:
Pub 注册的次数大幅度下降,下降了两个数量。 Sub 注册小幅度增长,因为如前面提到的那样,会同时发起服务级的 Sub,但大多场景这些额外的订阅是不会有推送的,结合推送次数的下降可以得出实际推送任务下降了几倍的结论。
2、数据分片改造
自定义 Slot 分配算法
主节点和副本节点不能分配在同一个 Data 上; Slot 对应主节点 Data 宕机时,优先提升副本节点为主节点,减少不可服务时间; 新节点先作为副本节点进行数据同步;主要目标在于减少节点变更时尽可能缩短注册中心数据的不可用时长。
数据完整度校验
数据同步架构
Data 和 Session 通过心跳的机制在 Meta 上进行续约,当 Data 发生节点变更的时候,Meta 此时会重新进行分配,生成新的 SlotTable,并通过广播和心跳的方式返回所有的节点,Session 就会用这份 SlotTable 寻址新的 Data 节点。存在一个时刻,集群中存在两份 SlotTable,分裂时间最大(1s)。
Session 上会缓存 Client 的 Pub 和 Sub 数据作为基准数据,在增量发送给 Data 的同时,Slot 的 leader 节点会定时和 Session 进行数据比对,Slot 的 follower 和 leader 也会定时进行数据对比,这样做到整个集群数据能快速达到最终一致,减少异常场景的不可服务时间。
无损发布
无损发布的整体流程是 Data 上的 Slot 逐步迁移,期间仍然对外提供服务。
以图为例,假设要下线的节点是 DataServer-1:将 Data-server 添加到注册中心迁移名单中;再将 Slot-2 对应的 follower(DataServer-2)提升为 Leader;等待 Data 节点达到稳定;继续将 Slot-3 对应的 follower(DataServer-3) 提升为 Leader;按照以上步骤分配掉剩余的 follower Slots;Slot 迁移完毕,Data-server 从 Data 列表中剔除,同时添加为黑名单;从迁移名单中设置为 succeed。
灰度发布
3、新版本性能优化
SOFARegistry 的 v6 版本相比于 v5 版本性能也有较大的提升:压测采用的机器都是 4c8g, Session*8, Data*3。
4、nightly build
结合前面的改造,通过 Slot 分配算法实现无损发布和灰度发布,以及应用级服务发现改造减少数据量。可以使得注册中心的整个发布过程变得更加的自动化。
sofa-registry-chaos
注册中心在无故障期间的推送延迟是否稳定,新版本上线是否造成推送延迟的上涨; 故障发生后数据是否能快速恢复最终一致性; 故障发生期间,容许注册中心数据推送延后一段时间,但不会推少或者推空。
未来规划
SOFARegitry v6 还在内部上线阶段,目前还没有开源,未来会持续增强作为服务注册中心方面的能力,比如多语言,多机房等等,同时会开源周边的配套组件和工具,也会更加贴合目前社区云原生的趋势,支持 Kubernetes, Istio 等等,预计功能的排期:
21/07 SOFARegistry v6 版本开源发布; 21/08 支持多语言客户端和多机房数据互通; 21/09 混沌测试平台 sofa-registry-chaos 开源。
延伸阅读