3.1 服务发现、心跳管理模块重构
3.1.1 原有架构
可以看到在原有架构,业务 RANK 和 BS 实例都是直连 ETCD,随着业务接入数量的增加逐渐暴露出一些问题:
读流量放大。同业务的不同 RANK 实例会各自访问 ETCD 获取相同的路由拓扑,导致读流量放大,对于 RANK 实例数多的业务放大现象愈发明显。
写流量放大。每个分片含有多个副本,在进行更新时,一轮周期内同一个分片会被写入多次,导致写流量放大,对于副本数多的分片写竞争愈发激烈。
升级改造困难。路由筛选策略、心跳上报策略均内嵌在 sched-lib 中,进行升级需要给每个业务 RANK/BS 上线,人力成本巨大。
为了解决上述问题,我们对心跳管理和服务发现模块进行了微服务拆分,新增心跳服务 (以下简称 HS) 和名字服务 (以下简称 NS) 避免了业务实例直连 ETCD,同时引入了 Prometheus,对心跳上报状态和路由获取状态等信息进行监控和可视化展示。
展开剩余67%3.1.2 NS (NamingService) 设计
我们对 NS 的定位是作为 ETCD 的 cache,采用 Read-Through 的模式,对全量业务的 RANK 提供拓扑信息查询,RANK 不再直接访问 ETCD:
NS 本身设计为一个无状态服务, RANK 可以访问任意一台 NS 获取拓扑,NS 实例之间拓扑路由保证最终一致性,NS 在拓扑变更时返回拓扑信息 + MD5 (拓扑)+ 更新时间戳,未变更时仅返回 MD5 和时间戳, RANK 基于 MD5 和时间戳自行判断是否需要更新。
拓扑更新策略下沉到 NS 中,RANK 获取到的拓扑即为直接可用拓扑,针对不同业务提供不同的控制策略并且后续升级改造只需上线 NS,成本大幅降低。
单机房 3 台 NS 实例即可支撑全部业务拓扑查询,重构前后 ETCD 读流量比例为 M:3,M 为平均每个业务 RANK 实例数,假设 N 取 30,则读流量下降 90%。
3.1.3 HS (HeartbeatService) 设计
HS 负责收集 BS 实例本身的心跳以及实例消费的分片的心跳,周期性聚合写入 ETCD,并且向 BS 实例返回其最新的消费分片信息:
HS 采用无主节点设计,也支持任意水平扩展。同一个业务的不同 BS 实例通过一致性 hash 方式请求同一台 HS 实例,便于 HS 进行分片维度的信息聚合,这样在大部分时间,每个分片无论有多少个副本一个周期内只会被写入一次,实例本身的心跳采用批量更新形式,写竞争大幅降低。
BS 在上报心跳的同时会从 HS 的 response 中获取自身消费的最新分片信息,如果分片信息变化,则清理老分片数据,消费新分片数据,后续只上报新分片状态信息。
单机房 3 台 NS 实例即可支撑全部业务心跳更新,重构前后 ETCD 写流量比例为 N:1,N 为平均每个分片副本数,假设 N 取 5,则写流量下降 80%。
发布于:湖南省富利来优配提示:文章来自网络,不代表本站观点。