正如之前文章"分布式系统核心三要素"所提到的, 多分区(Sharding) 是分布式系统必不可少的核心特性, 无 Sharding 不分布式. Sharding 之后, 必然会遇到服务发现的问题, 也即服务寻址, 或者路由表.
客户端在访问系统的服务之前, 需要拉取路由表, 根据路由表找到访问点的地址, 然后直接请求节点. 根据"Single Source of Truth"原理, 路由表的信息并不是 Truth, 不可能实时反映集群的 Sharding 分布, 因此, 客户端有可能访问到错误的节点. 这是无法避免的.
因此, 当某个节点收到了在其服务范围之外的请求时, 它有两种策略选择:
- 返回 Redirect, 让客户端重新寻址
- 作为 Proxy, 向正确的节点转发请求, 并在收到响应后返回给客户端
这两个策略各有优劣.
Redirect 可以简化服务节点的结构, 同时, 可以促使客户端及时更新路由表, 避免再次出现寻址错误. 但是, Redirect 会增加客户端的复杂度, 同时增加请求的 RT(Response Time), 因为客户端需要更换节点访问, 多了一次网络来回时间(RTT).
Proxy 会增加服务节点的复杂度, 但同时简化客户端的结构. 而且, 采取 Proxy 方式, 将无法让客户端及时地认识到自己的路由表信息错误, 除非通过带外数据的方式, 改变响应的结构, 增加额外的信息.
流行的多副本 KV 数据库 etcd(根据"分布式系统核心三要素", 因为其没有 Sharding 能力, 所以不算是分布式, 但可以称为"伪"分布式), 采取 Proxy 策略, 所以, follower 节点对外表现为可以处理写请求.