受《DDIA》中“Request Routing”一节的启发,我提出两种架构以支持mmkv提供分布式服务。

以下称每个提供实际服务的服务器为一个结点(node),结点的集合为一个集群(cluster)。

Client router

no-router-dist.png
每个结点都保存着相同的服务相关的信息(即元数据),客户端可以连接集群中的任一个结点,然后获取初始版本的服务元数据,客户端可以自己决定如何路由请求到指定的结点获取服务。
当集群有新的结点加入或退出,所有结点需要更新元数据并保持一致,然后客户端发送新请求到原来路由的结点时,该结点回应重定向到新的结点,更新客户端的元数据。
另一种可能的做法是结点将新的元数据发送给所有建立连接的客户端要求它们同步更新,但这样做IO开销可能很大,并且如果很多客户端不再发新请求的话,那么很多同步是没必要的,因此不采用。
假设结点个数为N,每个结点互相建立连接,需要建立N(N-1)个连接。通过一致性协议保证各个结点之间的元数据一致,同时也保证集群的容错性和可用性。

Independent router-tier

router_dist.png
在客户端和集群之间增加一个服务器作为路由器(router),客户端和结点不需要维护任何服务的元数据,相对地由路由器维护和管理。具体来说,客户端连接路由器,发送请求获取该请求的对应结点,然后再连接上该结点获取服务内容。
这样的做法由于不需要结点维护元数据,因此结点之间也不需要一致性协议来保证元数据一致。相对地,需要强一致性协议保证路由器的容错性。
正如Client router中提到的客户端元数据更新可能带来的问题,这里也不采用客户端缓存元数据的做法。这样一来,无论如何,每次都得先请求路由器才能确定该请求的对应结点。