SOFAStackgit
Scalable Open Financial Architecture Stack 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。github
本文根据 SOFA Meetup#1 北京站 现场分享整理,完整的分享 PPT 获取方式见文章底部。算法
2018 年 4 月, 蚂蚁金服宣布开源 SOFAStack 金融级分布式架构。这一年的时间,感谢社区的信任和支持,目前已经累积超过一万的 Star 数目,超过 30 家企业用户。数据库
2019 年 3 月 24 日,SOFA 在北京举办了首场 Meetup,咱们有幸见到了关心SOFA 的朋友们。后端
这次,咱们宣布开源蚂蚁金服注册中心 SOFARegistry 做为一周年的礼物之一,本文为根据现场分享整理的详细介绍。缓存
SOFARegistry 是蚂蚁金服开源的具备承载海量服务注册和订阅能力的、高可用的服务注册中心,最先源自于淘宝的第一版 ConfigServer,在支付宝/蚂蚁金服的业务发展驱动下,近十年间已经演进至第五代。服务器
GitHub 地址:github.com/alipay/sofa…数据结构
服务发现,并不是新鲜名词,在早期的 SOA 框架和如今主流的微服务框架中,每一个服务实例都须要对外提供服务,同时也须要依赖外部服务。如何找到依赖的服务(即服务定位),最初咱们思考了不少方式,好比直接在 Consumer 上配置所依赖的具体的服务地址列表,或者使用 LVS、F5 以及 DNS(域名指向全部后端服务的 IP)等负载均衡。架构
可是以上方式都有明显的缺点,好比没法动态感知服务提供方节点变动的状况,另外基于负载均衡的话还须要考虑它的瓶颈问题。因此须要借助第三方的组件,即服务注册中心来提供服务注册和订阅服务,在服务提供方服务信息发生变化、或者节点上下线时,能够动态更新消费方的服务地址列表信息,最终解耦服务调用方和服务提供方。负载均衡
服务注册中心的主要能力:
蚂蚁金服的服务注册中心,经历了 5 代技术架构演进,才最终造成了现在足以支撑蚂蚁海量服务注册订阅的,具备高可用、高扩展性和高时效性的架构。
SOFARegistry 的存储模型比较简单,主要基于 KV 存储两类数据,一类是订阅关系,体现为多个订阅方关心的 Topic(或服务键值)和他们的监听器列表,另外一类是同一个 Topic(或服务键值)的发布者列表。基于观察者模式,在服务提供方发生变化时(好比服务提供方的节点上下线),会从订阅关系中寻找相应的订阅者,最终推送最新的服务列表给订阅者。
随着蚂蚁的服务数据量不断增加,咱们将存储改成集群方式,每一个存储节点的数据是同样的,每一次写入都保证全部节点写入成功后才算成功。这种模式的特色是每台服务器都存储了全量的服务数据,在当时数据规模比较小的状况下,尚可接受。
这样的部署结构有两个问题:
若是要实现容量可无限扩展,须要把全部数据按照必定维度进行拆分,并存储到不一样节点,固然还须要尽量地保证数据存储的均匀分布。咱们很天然地想到能够进行 Hash 取余,但简单的取余算法在节点数增减时会影响全局数据的分布,因此最终采用了一致性 Hash 算法(这个算法在业界不少场景已经被大量使用,具体再也不进行介绍)。
每一个服务数据,通过一致性 Hash 算法计算后会存储到某个具体的 Data 上,总体造成环形的结构。理论上基于一致性 Hash 对数据进行分片,集群能够根据数据量进行无限地扩展。
咱们知道单机的 TCP 链接数是有限制的,业务应用不断的增多,为了不单机链接数过多,咱们须要将存储节点与业务应用数量成正比地扩容,而咱们实际上但愿存储节点的数量只跟数据量成正比。因此咱们选择从存储节点上把承载链接职责的能力独立抽离出来成为新的一个角色,称之为 Session 节点,Session 节点负责承载来自业务应用的链接。这么一来,SOFARegistry 就由单个存储角色被分为了 Session 和 Data 两个角色,Session 承载链接,Data 承载数据,而且理论上 Session 和 Data 都支持无限扩展。
如图,客户端直接和 Session 层创建链接,每一个客户端只选择链接其中一个 Session 节点,全部本来直接到达 Data层的链接被收敛到 Session 层。Session 层只进行数据透传,不存储数据。客户端随机链接一台 Session 节点,当遇到 Session 不可用时从新选择新的 Session 节点进行重连便可。
分离出 Session 这一层负责承载链接,引发一个新的问题:数据到最终存储节点 Data 的路径变长了,整个集群结构也变的复杂了,怎么办呢?
咱们知道,服务注册中心的一个主要职责是将服务数据推送到客户端,推送须要依赖订阅关系,而这个订阅关系目前是存储到 Data 节点上。在 Data 上存储订阅关系,可是 Client 并无直接和 Data 链接,那必需要在 Session 上保存映射后才肯定推送目标,这样的映射关系占据了大量存储,而且还会随 Session 节点变化进行大量变动,会引发不少不一致问题。
所以,咱们后来决定,把订阅关系信息(Sub)直接存储在 Session 上,而且经过这个关系 Session 直接承担把数据变化推送给客户端的职责。而对于服务的发布信息(Pub)仍是经过 Session 直接透传最终在 Data 存储节点上进行汇聚,即同一个服务 ID 的数据来自于不一样的客户端和不一样的 Session 最终在 Data 的一个节点存储。
这样划分了 Sub 和 Pub 数据以后,经过订阅关系(Sub)进行推送的过程就有点相似于对服务数据读取的过程,服务发布进行存储的过程有点相似数据写的过程。数据读取的过程,若是有订阅关系就能够肯定推送目标,迁移订阅关系数据到 Session,不会影响整个集群服务数据的状态,而且 Client 节点链接新的 Session 时,也会回放全部订阅关系,Session 就能够无状态的无限扩展。
其实这个读写集群分离的概念,在 Eureka2.0 的设计文档上也有所体现,一般读取的需求比写入的需求要大不少,因此读集群用于支撑大量订阅读请求,写集群重点负责存储。
数据备份,采用逐级缓存数据回放模式,Client 在本地内存里缓存着须要订阅和发布的服务数据,在链接上 Session 后会回放订阅和发布数据给 Session,最终再发布到 Data。
另外一方面,Session 存储着客户端发布的全部 Pub 数据,按期经过数据比对保持和 Data 一致性。
上述提到的数据回放能力,保证了数据从客户端最终能恢复到存储层(Data)。可是存储层(Data)自身也须要保证数据的高可用,由于咱们对存储层(Data)还作了数据多副本的备份机制。以下图:
当有 Data 节点缩容、宕机发生时,备份节点能够当即经过备份数据生效成为主节点,对外提供服务,而且把相应的备份数据再按照新列表计算备份给新的节点 E。
当有 Data 节点扩容时,新增节点进入初始化状态,期间禁止新数据写入,对于读取请求会转发到后续可用的 Data 节点获取数据。在其余节点的备份数据按照新节点信息同步完成后,新扩容的 Data 节点状态变成 Working,开始对外提供服务。
数据备份、以及内部数据的传递,主要经过操做日志同步方式。
持有数据一方的 Data 发起变动通知,须要同步的 Client 进行版本对比,在判断出数据须要更新时,将拉取最新的数据操做日志。
操做日志存储采用堆栈方式,获取日志是经过当前版本号在堆栈内所处位置,把全部版本以后的操做日志同步过来执行。
上述全部数据复制和数据同步都须要经过一致性 Hash 计算,这个计算最基本的输入条件是当前集群的全部 Data节点列表信息。因此如何让集群的每一个节点能感知集群其余节点的状态,成为接下来须要解决的问题。
最初,咱们直接将“Data 地址列表信息” 配置在每一个节点上,但这样不具体动态性,因此又改成经过 DRM(蚂蚁内部的动态配置中心)配置,可是这样仍须要人为维护,没法作到自动感知。
后续又想到这个集群列表经过集群内节点进行选举出主节点,其余节点直接上报给主节点,主节点再进行分发,这样主节点自身状态成为保证这个同步成功的关键,不然要从新选举,这样就没法及时通知这个列表信息。
最后咱们决定独立一个角色进行专职作集群列表信息的注册和发现,称为 MetaServer。Session 和 Data 每一个节点都在 MetaServer 上进行注册,而且经过长链接按期保持心跳,这样能够明确各个集群节点的变化,及时通知各个其余节点。
目前,SOFARegistry 能够支撑以下的数据量:
SOFARegistry 与开源同类产品的比较:
比较 |
SOFARegistry |
Eureka 1.0 |
ZooKeeper |
一致性 |
最终一致 |
最终一致 |
强一致 |
可用性 |
高可用,集群节点可动态扩缩容,数据保持多副本 |
高可用 |
节点选举过程整个集群不可用,没法提供服务 |
可扩展 |
一致性 Hash 数据分片,理论上无限制扩展 |
数据节点相互同步方式保持一致,有上限瓶颈 |
数据强一致,一样存在上限 |
时效性 |
秒级服务发现,经过链接状态进行服务数据变动通知 |
采用长轮询健康检查方式获取节点状态,时效不敏感 |
强一致要求,多写效率低 |
一些新的 Feature 规划和上述过程的开源路径:
以上就是本期分享的全部内容。当前,代码已开源托管在 GitHub 上,欢迎关注,同时也欢迎业界爱好者共同创造更好的 SOFARegistry。
SOFA 开源社区,感谢有你!
公众号:金融级分布式架构(Antfin_SOFA)