一、前言
一年一更的彩虹桥系列又来了,在前面两期我们分享了在稳定性和性能2个层面的一些演进&优化思路。近期我们针对彩虹桥 Proxy 负载均衡层面的架构做了一次升级,目前新架构已经部署完成,生产环境正在逐步升级中,借此机会更新一下彩虹桥架构演进之路系列的第三篇。
二、背景
彩虹桥目前依赖 SLB 做负载均衡和节点发现,随着业务发展流量越来越高,SLB 带宽瓶颈逐渐暴露,虽然在半年前做过一次双 SLB 改造临时解决了带宽瓶颈,但运维成本也随之变高。除了带宽瓶颈外,SLB 无法支持同区优先访问,导致难以适配双活架构。所以准备去除彩虹桥对 SLB 的强依赖,自建彩虹桥元数据中心,提供负载均衡和节点发现等能力,同时支持同区访问等能力来更好的适配双活架构。下面会详细介绍一下彩虹桥元数据中心以及 SDK 相关能力的相关细节。
三、核心名称解释
四、现有架构回顾
在开始介绍彩虹桥元数据中心之前,我们先来回顾一下彩虹桥目前架构,以及存在的一些痛点。
现有架构
主要痛点
五、自建元数据中心&SDK 增强
图片元数据中心独立部署
架构详解
Metadata 数据库
节点启动时
node_info weight config_version cluster_name ? address ?
节点运行时
node_info beat_version beat_version cluster_name ? address ?
节点下线
MetaCenter( Heimdall)
初始化心跳版本号:记录所有 metadata 数据库每个节点最新 beat_version 和初始化心跳丢失次数到内存
定时查询节点信息(3s 一次),筛选可用节点并写入到内存中,提供 OpenAPI 给 SDK 调用,每个库均执行以下操作,最终会得到每个库的可用节点列表,最后把多个 list 求并集,得到最终的可用列表,写入到内存中。
查出所有列表数据后,对比内存中的 beat_version 与数据库中的 beat_version,如不相同则更新内存,如果相同说明对应节点心跳有丢失,如果丢失次数超过阈值,则剔除此节点。
节点列表中除了 ip、端口信息外,还有权重,启用状态属性, 这些属性都属于控制流变更,如果出现2边数据库不一致场景,以 config_version 最大的为准。
如果本次计算时有节点列表变化,会下发一个变更事件到 ARK(value 为时间戳-秒),SDK 在收到次配置变更后会立刻到 MetaCenter 拉取一次节点列表,以弥补定时轮训的延时。
MetaCenter 提供的 OpenAPI 是通过计算后存入内存的数据,为了可以人工干预节点列表,需要支持开关一键切换至人工配置的节点列表数据。
SDK( Rainbow)
另外 SDK 支持一键动态切换至走老架构方式(4层 SLB)
管理后台
修改状态会去所有 metadata 数据库执行,只有一个库成功就返回成功,如所有库都修改失败,则返回失败。
node_info enabled config_version ip ? port ?
容灾能力
表格中的是否有影响和故障恢复时间均指 SDK-Proxy 的访问链路,Proxy-DB 链路不在范围内。
参考以下时间线,可在30s左右完成恢复。
一些思考
Q:为什么不用 sylas(得物注册中心产品)做注册中心,而是要自建元数据中心做服务发现?
彩虹桥和 sylas 均为 P0 级别服务,对稳定性要求极高,在架构设计之初需要充分考虑到互相依赖可能带来的级联故障,在与注册中心相关同学沟通后,决定自建彩虹桥元数据中心,实现自闭环。
Q:为什么不是传统的基于 Raft 协议的三节点来实现服务发现,而是用多套数据源做 merge?
Raft 是工程上使用较为广泛的强一致性、去中心化、高可用的共识算法,在分布式系统中,适用于高一致性、容错性要求高的场景。但 Raft 协议需要维护领导者选举和日志复制等机制,性能开销较大,其次 Raft 协议相对复杂,在开发、维护、排障等方面会非常困难,反之采用多数据源求并集的方式更简单,同时也具备单节点故障、整个可用区故障以及跨区网络中断等多种复杂故障下的容灾能力。
Q:如何在 SLB 切换到新架构的过程中保障稳定性?
可灰度:支持单个上游节点粒度的灰度
可回滚:支持一键动态切换至 SLB 架构
可观测:大量埋点数据可实时进行观测,有问题可快速回滚。
六、总结
自建元数据中心后,将给彩虹桥带来一系列收益: