本文介绍CacheServer路由信息的同步流程,以及与客户端、ProxyServer、RouterServer是如何协作的。
概述
功能
- CacheServer在启动时从RouterServer中拉取路由表;
- 工具类,与RouterServer交互,定时进行路由信息的同步以及心跳的上报;
源码文件
// 工具类,与RouterServer交互,更新路由信息
RouterHandle.h
RouterHandle.cpp
//给RouterServer提供接口,在主备切换和数据迁移时会用到
RouterClientImp.h
RouterClientImp.cpp
配置解析
#模块名
ModuleName=Test
#RouterServer的obj名称
ObjName=DCache.TestRouterServer.RouterObj
#路由分页大小
PageSize=10000
#保存在本地的路由表文件名
RouteFile=Route.dat
#同步路由的时间间隔(秒)
SyncInterval=1
#数据迁移时传输数据进行压缩
transferCompress=Y
- ModuleName,当前模块名,可以理解为“数据库实例”;
- ObjName,在Tars环境中,客户端或Proxy可以通过对象名间接寻址访问路由服务RouterServer;
- SyncInterval,在TimerThread读取了该配置,控制路由同步间隔;
- PageSize,在扩缩容数据迁移时会用到该参数,每次只迁移PageSize页到目标节点上;
- RouteFile,该文件保存了该模块的路由信息。当RouterServer路由表发生变化时,CacheServer会更新本地路由表和RouteFile文件;
说明:上述配置信息会写到DCache库中的t_config_table表内。
t_config_item表存储的是规格数据,包含CacheServer所有的配置项。
t_config_table表存储的是实例数据,描述每个CacheServer的具体配置。
路由同步流程
路由信息的获取、更新和存储涉及到多个服务,比较复杂。为便于理解,画了一个简要的流程图:

分为3个主要流程:
- CacheServer的路由同步流程
- ProxyServer的路由同步流程
- 客户端访问DCache时,路由的作用
CacheServer的路由同步流程
启动时同步
见图中蓝色指示线(CacheServer-启动)。
- CacheServer在启动时,会调用RouterServer的接口,拉取路由表,然后在本地的内存和文件中保存。
- 其他线程在获取路由信息时,优先从本地内存中获取。
- 如果RouterServer宕机了,CacheServer就会以本地文件中记录的路由信息为准,进行相应操作。
定时同步
见图中绿色指示线(CacheServer-TimerThread)。
- CacheServer在启动时,会启动TimerThread线程,该线程定时从RouterServer中同步路由信息到本地。
- 同步时会先校验路由版本,当版本不同时才会拉取完整的路由表到本地的内存和文件中。
ProxyServer的路由同步流程
处理方式同CacheServer:
- 在服务启动时(ProxyServer::initRouter方法中)调用RouterServer的接口拉取路由表(图中未画出);
- 同时启动TimerThread线程,定时从RouterServer中同步路由信息到本地(图中ProxyServer-TimerThread,红色指示线)。
客户端访问DCache时的路由流程
客户端的访问流程见图中深黄色指示线。
在分布式环境中,DCache的客户端都会通过ProxyServer访问内存库的数据。ProxyServer除了提供统一访问层的负载均衡能力外,也提供了数据路由的功能。这里数据路由的能力是通过与RouterServer定时同步路由表来实现的。
- 客户端要进行增删改查时,会调用Proxy相应的接口,这里以插入操作为例;
- Proxy会检测本地路由表,确认请求的Key所在的后端Master-Module(即模块的主节点)的对象名;
- Proxy调用目标对象Master-Module的插入接口,尝试写入数据;
- Master-Module在写数据到内存之前,先到本地路由表中检测该Key是否在自己所负责的范围内;如果在,就直接写入数据,并返回写的结果;
- 如果Key不在Master-Module所负责的范围,会告知Proxy重新到Router中拉取路由;之后重复步骤2。
总结
本文介绍了CacheServer路由信息的同步流程,以及与客户端、ProxyServer、RouterServer的协作流程,便于大家理解。
通过本文的分析可以看到,设计者的思路还是非常严谨的,在很多细节上做的也很到位,例如:
- ProxyServer、RouterServer和CacheServer在本地都有自己的路由表,以RouterServer的为准,定时(时间很短)同步。这种设计极大减轻了路由服务的压力,路由服务不再是系统的瓶颈;同时也提升了读写数据的效率,绝大多数情况下ProxyServer可以直接从本地内存中获取路由表,而不需要通过服务调用获取路由信息;
- 路由表的“二级缓存”设计。如在ProxyServer中,本地内存中有路由表,磁盘文件中也保存了一份。这种设计在一定程度上保证了DCache的高可用:在极端情况下,即使RouterServer都不可用(常见的不可用原因是 ProxyServer和CacheServer太多导致RouterServer压力太大),ProxyServer也可以通过磁盘文件中记录的路由信息,正常提供读写服务;
想了解更多优秀特性,大家还需要深入理解源码呀!