开篇
这篇文章是基于SOFA Meetup合肥站的分享总结,次要针对于注册核心的定位以及性能介绍,通过对蚂蚁注册核心发展史的剖析,率领大家理解,蚂蚁的注册核心是如何一步一步演变为当初的规模和个性的。
更多深刻的技术细节,欢送大家退出到SOFA和SOFARegistry的社区中,探寻后果。
注册核心是什么
服务发现 & 服务注册
注册核心简略来说,是为了解决分布式场景下,服务之间相互发现的问题。
如下图所示,服务A想要调用服务B的时候,须要晓得B的地址在哪里,如何解决这个问题?
一般来说,分为两个点:
- 服务发现能够有一个中心化的组件或者说是存储,它承载了所有服务的地址,同时提供进去一个可供查问和订阅的能力,服务的生产方能够通过和这个中心化的存储交互,获取服务提供方的地址列表。
服务注册:同样是上文中中心化的组件,然而,这个时候的服务信息能够有两种措施
- 服务连贯注册核心,同时上报本身的服务以及元数据(也是明天本文讲述的重点)
- 有一个集中的管制面(control plane)将用户定义的服务和IP的映射写入注册核心,例如AWS的CloudMap
调用流程
如上图所示,就是目前一种支流的注册核心模式,SOFARegistry和Nacos都是这种模式。
- 服务A,服务B通过SDK或者REST将本身的服务信息上报给注册核心
- 服务A须要调用服务B的时候,就对注册核心发动申请,拉取和服务B相干的服务IP列表以及信息
- 在获取到服务B的列表之后,就能够通过本身定义的负载平衡算法拜访服务B
心跳
心跳是注册核心用于解决服务不可用时,及时拉出服务升高影响的默认形式,如下图所示
- 服务B的一个节点断网或是hang住,引发心跳超时;或是宕机、断链间接引发心跳失败
- 注册核心把问题节点从本身的存储中拉出(这里拉出依据具体实现:有的是间接删除,有的是标记为不衰弱)
- 服务A收到注册核心的告诉,获取到服务B最新的列表
DUBBO 注册核心
上面通过DUBBO的例子,咱们来看一下注册核心是如何应用的,以及流程
首先,DUBBO在2.7和3.0中的配置略有不同,然而都是简略易懂的,这里都放上来
DUBBO-2.7
DUBBO-3.0
在RPC客户端只须要配置一个注册核心的地址即可,地址中蕴含了根底三元素
- protocol(协定类型)比方,zookeeper
- host
- port
基于此,dubbo的注册流程如下图所示
- 服务的生产方通过DUBBO客户端向注册核心(Registry)发动注册行为(register)
- 服务的生产方通过DUBBO客户端订阅信息(subscribe)
- 注册核心通过告诉的形式,下发服务列表给服务生产方
注册核心的实质
通过前文的解说,以及DUBBO组件的具体例子,咱们大略能够演绎注册核心的实质
“存储” + “可运维”
- 一方面,注册核心须要存储能力去记录服务的信息,比方利用列表
- 另一方面,注册核心在实际过程中,须要提供必须的运维伎俩,比方敞开某一服务流量
蚂蚁注册核心编年史
史前时代
史前时代的蚂蚁是相当长远的架构,过后所有的服务部署在同一台物理机上或者JVM上,服务之间不存在有跨机器调用的场景,这里略过不表
硬负载时代
起初,为了解决利用之间的耦合带来的部署难,运维难问题,咱们对服务进行了拆分,拆分后的服务,遇到了一个问题,就是如何解决服务之间的调用关系,这个时候,蚂蚁用了两种硬负载 F5 或是 LVS。
通过简略的4层代理,咱们能够把服务部署在代理的前面,服务与服务之间通过代理相互拜访,达到了跨机调用的目标
第一代注册核心 -- 硬负载到软负载的演变
通过硬负载拜访的形式,一方面解决了服务之间相互调用的问题,部署架构也简略易懂;另一方面,在业务快速增长之后,却带来了肯定的问题:
- 单点的问题(所有调用都走F5的话,F5一旦挂了,很多服务会不可用)
- 容量问题(F5承载的流量太高,自身会到一个性能瓶颈)
这个时候,蚂蚁引进了阿里团体的一款产品叫ConfigServer,作为注册核心进行应用,这个注册核心的架构就和结尾提到的架构很像了,服务之间能够通过IP间接拜访,而升高了对负载平衡产品的强依赖,缩小了单点危险。
第二代注册核心 -- ScaleUp?ScaleOut?It's a problem
然而,问题还在继续,那就是注册核心,自身是一个单点,那么,他就会持续遇到上文中所说的两个问题
- 单点危险(注册核心自身是单机利用)
- 容量瓶颈(单台注册核心的连接数和存储数据的容量是无限的)
解决的形式有两种
- scale-up(淘宝):通过减少机器的配置,来加强容量以及扛链接能力;同时,通过主-备这样的架构,来保障可用性
- scale-out(蚂蚁):通过分片机制,将数据和链接均匀分布在多个节点上,做到程度拓展;通过分片之后的备份,做到高可用
蚂蚁和淘宝走了两条不同的路,也推动了蚂蚁前面演进出一套独立的生态系统
蚂蚁的演进架构如下,产生了两种不同的利用节点
- session节点,专门用来抗链接应用,自身无状态能够疾速扩大,单机对资源的占用很小
- data节点,专门用来存储数据,通过分片的形式升高单个节点的存储量,管制资源占用
第五代注册核心 -- Meta节点的诞生
下面的架构曾经很合乎目前支流的分布式架构了,然而在运维过程中,产生了一系列问题,比方
- 所有data都是分布式的,data之间的服务发现须要通过启动时给定一个配置文件,这样就和规范运维脱钩
- data节点的高低线须要去及时批改配置文件,否则集群重启会受到影响
- 分布式存储一致性问题,每次迭代公布,须要锁定paas平台,避免节点变动带来的不统一
所有这些问题的产生,咱们发现能够引入一个元数据管理核心(Meta)节点来,解决对data和session治理的问题,data和session通过4层负载或是7层负载对meta拜访即可.
比照业界的解决方案,都有相似的模型,比方HDFS的Name Node、Kafka依赖于ZK,Oceanbase依赖于RootServer 或者 配置核心Apollo依赖于Euraka。
Meta节点的呈现,缓解了手工运维注册核心的瓶颈,然而,仍然没有从根本上解决问题,那么问题在哪里?详见下文剖析。
第六代注册核心 -- 面向运维的注册核心
上文说道,Meta节点的呈现,承接了Data以及Session之间服务发现的问题,然而,丛云未测来讲,还是有很多问题解决不了,比方
- Data节点的公布在数据量大的前提下,仍然是个痛点
- Session节点的新加节点上,可能很久都没有流量
等等,对于这些问题,在SOFARegistry5.x的根底上,咱们疾速迭代了6.0版本,次要是面向运维的注册核心。
Data节点公布难的问题,说到底是一个影响范畴的问题,如何管制繁多data节点公布或者挂掉对数据的影响面,是解决问题的根源,这里咱们采纳了两个措施
- 改良数据存储算法(consistent-hash -> hash-slot)
- 利用级服务发现
存储算法的演进
之前咱们应用了一致性hash的算法,如下图所示,每一个节点承载一部分数据,通过是存储进行hash运算,算出存储内容的hash值,再计算出hash值落在哪一个data所负责的存储区间,来存储数据。
当data节点宕机或者重启时,由下一个data节点接管宕机节点的数据以及数据的拜访反对。
这样依赖,数据迁徙的粒度只能以单个data节点所存储的数据为单位,在数据量较大(单节点8G)的状况下,对数据的重建有肯定的影响,而且,在data间断宕机的状况下,可能存在数据失落或是不统一的场景。
改良后的算法,咱们参考了Redis Cluster的算法机制,应用hash slot进行数据分片
这样,在data公布过程中,能够控制数据的迁徙以slot为单位(单个data节点多个slot,可配置)
同时,为了解决迁徙或是宕机期间,数据写入不统一的场景,咱们引入了数据回放的弥补机制,data在promotion为slot的master之后,会被动地去和所有的session实现一次数据比对/校验,增量同步新增数据
利用级服务发现
利用级服务发现是为了解决数据存储量大的问题,因为篇幅起因,这里略过不表
开源
SOFARegistry从我的项目晚期就开始了开源的过程,与目前支流的注册核心的比照如下
咱们认为,注册核心首先须要解决的是可用性的问题,所以,在分布式一致性的问题上,咱们抉择了AP的模型,这点也和支流的注册核心,例如Euraka以及Nacos保持一致的观点。
其次,在性能方面,基于长连贯的SOFARegistry领有更短的推送提早,相较于Nacos1.0的推送时延更短(Nacos1.0基于Long Polling的模型,Nacos2.0也应用了长连贯的模型)
在协定方面,SOFARegistry应用了蚂蚁开源协定栈:BOLT协定(相似于HTTP2.0)的流式协定,更加轻量级,同时协定自身的全双工模式:无阻塞,大大晋升了资源利用率。
Feature | Consul | Zookeeper | Etcd | Eureka | Nacos | SOFARegistry |
---|---|---|---|---|---|---|
服务健康检查 | 定期healthcheck (http/tcp/script/docker) | 定期心跳放弃会话(session) + TTL | 定期refresh(http)+TTL | 定期心跳+TTL;反对自定义healthCheck | 定期链接心跳+断链 | 定期连贯心跳 + 断链敏感 |
多数据中心 | 反对 | - | - | - | 反对 | 反对 |
Kv存储服务 | 反对 | 反对 | 反对 | - | 反对 | 反对 |
一致性 | raft | ZAB | raft | 最终一致性 | 最终统一(注册核心) Raft(配置核心) | 最终一致性 |
cap | cp | cp | cp | ap | ap+cp | ap |
应用接口(多语言能力) | 反对http和dns | 客户端 | http/grpc | 客户端/http | 客户端(多语言) http | 客户端(java) |
watch反对 | 全量/反对long polling | 反对 | 反对long polling | 不反对(client定期fetch) | 反对 | 反对(服务端推送) |
平安 | acl/https | acl | https反对 | - | https | acl |
spring cloud集成 | 反对 | 反对 | 反对 | 反对 | 反对 | 反对 |
和大家所熟知的Nacos比照,咱们在金融级和分布式(存储量级)上具备很大劣势,易用性和云原生方面,目前还在追赶
欢送退出咱们
一个人能够走得很快,但一群人能够走的更远
SOFARegistry是一个开源我的项目,也是开源社区SOFA重要的一环,咱们心愿用社区的力量推动SOFARegistry的后退,而不是只有蚂蚁的工程师去开发。咱们在往年也启动了两个我的项目,用于反对更多的开发者参加进来:
- Trun-Key Project (开箱即用打算):https://github.com/sofastack/sofa-registry/projects/5
- Deep-Dive Project(深入浅出打算):https://github.com/sofastack/sofa-registry/projects/4
打算目前还处在初期阶段,欢送大家退出进来,能够帮忙咱们解决一个issue,或是写一篇文档,都能够更好地帮忙社区,帮忙本人去成长。
本周举荐浏览
- RFC8998+BabaSSL---让国密驶向更远的星辰大海
- 还在为多集群治理懊恼吗?OCM来啦!
- MOSN 子项目 Layotto:开启服务网格+利用运行时新篇章
- 开启云原生 MOSN 新篇章 — 交融 Envoy 和 GoLang 生态
更多文章请扫码关注“金融级分布式架构”公众号