简介
SOFARegistry 是蚂蚁集团在出产大规划运用的服务注册中心,经历了多年大促的考验,支撑蚂蚁巨大的服务集群,具有分布式可水平扩容、容量大、推送延迟低、高可用等特色。
蚂蚁出产集群 — SOFARegistry 支撑 1000 万服务发布者、4000 万服务订阅者,在事务应用大规划改变触发千万级别推送量的场景下,推送延迟的 p99 仍然可以保持在 7s 以下。
《认识 SOFARegistry》 这一系列文章将会根据 SOFARegistry 新版别(V6)的代码,讲解注册中心在超大规划集群场景下落地的解析与实践,一起介绍 SOFARegistry 的各项功用,方便事务落地。
布置架构
SOFARegistry 现有的架构设计:采用双层存储架构,外加一个担任内部元数据管理的 Meta 组件。
SOFARegistry 的人物分为 4 个: client、session、data、meta。
人物分工如下:
Client
供给应用接入服务注册中心的基本 API 才能,经过编程方法调用服务注册中心的服务订阅和服务发布才能。
SessionServer | 会话服务器
担任承受 Client 的服务发布和服务订阅请求,并作为一个中间层将写操作转发 DataServer 层。SessionServer 这一层可随事务机器数的规划的增加而扩容。
DataServer | 数据服务器
担任存储具体的服务数据,数据按 dataInfoId 进行分片存储,支撑多副本备份,确保数据高可用。这一层可随服务数据量的规划增加而扩容。
MetaServer | 元数据服务器
担任保护集群 SessionServer 和 DataServer 的共同列表,作为 SOFARegistry 集群内部的地址发现服务,在 SessionServer 或 DataServer 节点改变时可以告诉到整个集群。
凭借双层数据分片的架构,SOFARegistry 具有了支撑海量数据的基石
● 支撑海量数据:每台 DataServer 只存储一部分的分片数据,随数据规划的增加,只需扩容 DataServer 服务器即可。
● 支撑海量客户端:衔接层的 SessionServer 只担任跟 Client 打交道,SessionServer 之间没有任何通讯或数据仿制,所以跟着事务规划的增加,SessionServer 可以较轻量地扩容,不会对集群造成额外负担。
数据结构
作为注册中心的根底功用,SOFARegistry 供给发布订阅的接口:Subscriber、Publisher。
在服务发现场景下,Subscriber 需求经过服务称号从注册中心订阅到多个服务方的地址,进行负载均衡的拜访。
当存在服务方机器宕机时,注册中心告诉一切的订阅方从服务列表中摘除这个 IP 地址,这样就不会再拜访宕机的机器。
下面给出简化后的发布者和订阅者的字段,贴合上述服务发现的需求。
class Subscriber{
String dataId; // 服务称号
String group; // 事务类型,比方RPC、MSG等等
String instanceId; // 租户称号
String zone; // 地点分区,结合scope完结逻辑隔离
ScopeEnum scope; // 订阅规模: zone、dataCenter、global
}
class Publisher{
String dataId;
String group;
String instanceId;
String zone;
List<String> dataList; // 发布的数据, sofarpc 用法中常见url
}
常见用法(JAVA SDK)
发布者
// 构造发布者注册表
PublisherRegistration registration = new PublisherRegistration("com.alipay.test.demo.service:1.0@DEFAULT");
registration.setGroup("TEST_GROUP");
registration.setAppName("TEST_APP");
// 将注册表注册进客户端并发布数据
Publisher publisher = registryClient.register(registration, "10.10.1.1:12200?xx=yy");
// 如需掩盖上次发布的数据可以运用发布者模型重新发布数据
publisher.republish("10.10.1.1:12200?xx=zz");
订阅者
// 创建 SubscriberDataObserver
SubscriberDataObserver subscriberDataObserver = new SubscriberDataObserver() {
@Override
public void handleData(String dataId, UserData userData) {
System.out.println("receive data success, dataId: " + dataId + ", data: " + userData);
}
};
// 构造订阅者注册表,设置订阅维度,ScopeEnum 共有三种级别 zone, dataCenter, global
String dataId = "com.alipay.test.demo.service:1.0@DEFAULT";
SubscriberRegistration registration = new SubscriberRegistration(dataId, subscriberDataObserver);
registration.setGroup("TEST_GROUP");
registration.setAppName("TEST_APP");
registration.setScopeEnum(ScopeEnum.global);
// 将注册表注册进客户端并订阅数据,订阅到的数据会以回调的方法告诉 SubscriberDataObserver
Subscriber subscriber = registryClient.register(registration);
更具体的用法文档参阅官方文档: www.sofastack.tech/projects/so…
特色与优势
这是一张 SOFARegistry 和其他注册中心产品的特性比照图,可以看出相比其他产品,SOFARegistry 在功用特性方面仍是缺乏(未来 SOFARegistry 在特性方面会进行完善)。 SOFARegistry 的首要优势仍是在于支撑超大规划集群,现在比较贴合蚂蚁对服务注册中心容量与性能的要求。
终究共同性
在服务发现场景下,强共同性并不一定是最合适的。服务发现的要求是发布方的改变可以在最快速的广播到整个集群,收敛时长确定的终究共同性同样能满意此要求。根据 CAP 原理,在满意共同性 C 的场景下,AP 只能挑选一个,但作为一个分布式高可用要求的系统,注册中心是不能放弃 AP 的。
SOFARegistry 挑选了 AP 模型,采用内存对数据进行存储,增量调配全量的数据同步方法,使得可以满意超大规划集群服务发现的需求。
支撑海量数据
部分的服务注册中心系统,每台服务器都是存储着全量的服务注册数据,服务器之间依托共同性协议(paxos/raft)完结数据的仿制,或者只确保终究共同性的异步数据仿制。
“每台服务器都存储着全量的服务注册数据”,在一般规划下是没问题的。但是在蚂蚁集团巨大的事务规划下,服务注册的数据总量早就超过了单台服务器的容量瓶颈。
SOFARegistry 对数据进行了分片,每台 DataServer 只存储一部分的分片数据。随数据规划的增加,只需扩容 DataServer 服务器即可应对,这是相对其他服务发现领域的竞品来说最大的特色。
咱们在线上验证了横向扩展才能,集群测验最大扩容到 session370、data60、meta*3。按照一个 data 节点的安全水位支撑 200w pub 一个 pub 大概 1.5K 开销,考虑容忍 data 节点宕机 1/3 仍然有服务才能(需求保存 pub 上涨的 buffer),该集群可支撑 1.2 亿的 pub,假如配置双副本则可支撑 6kw 的 pub。
支撑海量客户端
SOFARegistry 集群内部运用分层的架构,分别为衔接会话层(SessionServer)和数据存储层(DataServer)。SessionServer 功用很朴实,只担任跟 Client 打交道,SessionServer 之间没有任何通讯或数据仿制,所以跟着事务规划(即 Client 数量)的增加,SessionServer 可以很轻量地扩容,不会对集群造成额外负担。
高可用
各个人物都有 FailOver 机制:
- MetaServer 集群布置
内部根据数据库选举,只能存在任意运转中机器,就可以对外服务。
- DataServer 集群布置
根据自研的 slot 分片算法进行数据分片,数据分片具有多个副本,一个主副本和多个备副本。假如 DataServer 宕机,MetaServer 能感知,并告诉一切 DataServer 和 SessionServer,MetaServer 会快速提高备副本的 DataServer 成为主副本,削减宕机影响时长。
- SessionServer 集群布置
任何一台 SessionServer 宕机时,Client 会主动 FailOver 到其他 SessionServer,而且 Client 会拿到最新的 SessionServer 列表,后续不会再衔接这台宕机的 SessionServer。
秒级的服务上下线告诉
关于服务的上下线改变,SOFARegistry 运用推送机制,快速地完结端到端的传达。SOFARegistry 能经过断链事情和心跳快速检测出来服务宕机的状况。
无损运维
SOFARegistry 根据内存存储和分布式的特色,本身在运维的时分必然带来数据搬迁。 经过自研的 slot 分片搬迁算法和数据回放功用,使得 SOFARegistry 完结了本身运维期间仍然可以对外供给服务,服务零丢失。
事务功用
发布订阅
发布订阅是 SOFARegistry 最根底的功用。
按 IP 下线
关于没有服务流量 goaway 和重试功用的场景下,凭借注册中心完结服务流量的 zero down 运维是一个比较重要的需求。
SOFARegistry 供给 HTTP 接口进行指定 IP 的 Publisher 下线,可以在事务代码无侵入的场景下完结在一个机器下线下,管控端先从注册中心下线这个 IP 对应的一切 Publisher。
应用级服务发现
SOFARegistry 内部集成了一个根据数据库的元数据中心,参阅 Dubbo3 的应用级服务发现方案,完结了和 MOSN 合作的应用级服务发现方案,大幅度削减注册中心的数据量与对客户端的推送量,该特性已经在蚂蚁大规划上线,可以降低注册中心数据量一个数量级以上。
数据架构
SOFARegistry 分为多个人物,多个人物之间进行数据同步完结了高可用。
slot 分片
咱们从逻辑大将数据规模划分成 N 个大小相等的 Slot,而且 Slot 数量后续不可再修正。然后,还需求引入“路由表”SlotTable 的概念,SlotTable 担任寄存这每个节点和 N 个 Slot 的映射关系,并确保尽量把一切 Slot 均匀地分配给每个节点。
Session 在进行路由的时分,根据 DataInfoId 的 Hash 值确定数据地点 Slot,再从路由表中拿到数据对应的 Data 节点进行数据拉取,每个 Slot 都会有一个主节点和多个副本节点,然后完结主节点宕机的时分,副本节点能快速提高为主节点。
分配算法的首要逻辑是:
- 主节点和副本节点不能分配在同一个 Data 上;
- Slot 对应主节点 Data 宕机时,优先提高副本节点为主节点,削减不可服务时间;
- 新节点先作为副本节点进行数据同步;
- 首要目标在于削减节点改变时,尽可能缩短注册中心数据的不可用时长。
流程
源码导航
- 接纳 Subscriber
- 接纳 Publisher
- Data 接纳 Session 的数据写入
- Session 接纳 Data 的数据改变告诉
- Session 从 Data 拉取数据
- Session 推送给 Client
- 比照 Session 推送版别和 Data 的数据版别,触发兜底推送
- Data 守时从 Session 批量拉取数据
- Data Follower 定期从 Leader 批量拉取数据
数据共同性
-
client 关于每个 publisher 都会保护一个 version,每次 pub/unpub 都会自增,会带着 version 一起发送到 session
-
session 经过 version 的判别来防止并发场景下高低版别的掩盖问题
-
data 经过 version 的判别来防止并发场景下高低版别的掩盖问题
数据推送
-
session 接纳到 client 的数据写入时,会发送到指定的 data 上
-
session 经过断链事情和心跳来检测 client 的宕机
-
当 data 内发生服务改变(比方承受到了新的 pub),data 会告诉一切的 session 触发对应 dataId 推送
数据同步兜底
-
session 会把 client 注册的 pub 和 sub 都存储在内存中,data 会守时和一切的 session 同步比照数据,确保数据能在短时间内到达终究共同。
-
session 守时比照内存中 sub 的推送完结的版别和 data 上数据的最新判别,判别是否需求触发推送。
-
data 包含多个 slot,具有 follower slot 的 data 会守时和对应的 slot leader 比照同步数据。
本文首要介绍 SOFARegistry 本身的根底功用与优势,以及数据架构的大致介绍。
下一篇将会开端介绍如何开发 SOFARegistry 以及各个代码模块的介绍,欢迎大家继续关注 SOFARegistry ~
本周引荐阅读
降本提效!注册中心在蚂蚁集团的蜕变之路
咱们做出了一个分布式注册中心
稳定性大幅度提高:SOFARegistry v6 新特性介绍
带你走进云原生技术:云原生开放运维体系探究和实践