DCache-CacheServer分析(五)

2020年12月10日

DCache支持全量恢复和增量恢复(类似于redis的RDB和AOF)。

本文介绍CacheServer恢复线程(SlaveCreateThread)的功能以及工作方式。

功能描述

从dump文件和binlog文件中恢复数据到内存,用于将数据快速恢复到对应节点的共享内存中

dump文件和binlog文件的生成详见 DCache-CacheServer分析(四)

相关文件:

SlaveCreateThread.h
SlaveCreateThread.cpp

触发方式

数据恢复时,需要手动调用 BackUpObj 的服务,这时会初始化该线程并启动,调用的接口如下:

tars::Int32 BackUpImp::restore(const std::string & mirrorPath, const vector<std::string> & binlogPath, tars::Int32 lastTime, tars::Bool normal, std::string &errmsg, tars::TarsCurrentPtr current)

参数解释详见MKBackUp.tars

注意: 这个操作必须在故障(从)节点执行,原因见下方分析。

配置解析

配置文件中与之相关的配置项如下:

#备份恢复操作日志的按天日志文件名后缀
BackupDayLog=dumpAndRecover

处理逻辑分析

初始化

通过如下函数进行初始化:

int SlaveCreateThread::init(const string &mirrorPath, const vector<string> &binlogPath, time_t recoverTime, bool normal, const string &sConf)
参数作用

mirrorPath

mirror文件绝对路径
binlogPathbinlog文件绝对路径
recoverTime恢复到该时间点,unix时间戳,精度:秒。
normal

是否强制恢复。正常的恢复流程在加载完镜像和binlog后,会再从主机同步一条binlog;强制恢复流程,则是加载完镜像和binlog后,就认为恢复完成

注意recoverTime 不能是未来的时间

线程处理流程

  • 创建临时文件 SlaveCreating.dat(data路径下),为空文件;
  • 等待另外3个线程将现有活动处理完毕,包括BinlogThread(binlog同步)、BinlogTimeThread(binlog进度)和TimerThread(心跳上报、同步路由等);
  • 加载镜像文件(mirrorPath):
  • int SlaveCreateThread::restoreFromDumpMirrorFile()
  • 加载镜像成功后开始加载按小时的binlog
  • int SlaveCreateThread::restoreFromHourBinLogFile()
  • 是否是正常恢复。
    • 正常的恢复流程是:在加载完镜像和binlog后,会再从主节点同步binlog(调用主节点的MKBinLogImp::getLog服务)
    • 而强制恢复流程,则是加载完镜像和binlog后,就认为恢复完成
  • 保存binlog的指针位置到文件 sync_point.data
  • 最后,无论成功还是失败,都会删除临时文件 SlaveCreating.dat

SlaveCreating.dat作用

该文件存在,说明该节点正处于数据恢复状态。
这里需要注意,数据恢复操作一定要在从节点上进行。如果(由于误操作)这个文件出现在主节点,DCache的自我保护机制会禁止CacheServer启动,并报如下错误:

server can not changed from SLAVE to MASTER when in creating data status

这是为了保护主节点数据避免因误操作而被覆盖。

如何使用(重要!!!)

故障恢复可能会在3个场景中使用:

  1. 主节点异常
  2. 从节点异常
  3. 主从节点都发生异常

在上述情况出现时,如果想快速恢复内存数据,就需要执行这个恢复过程。

执行

恢复时,需要将全量备份的镜像文件和增量的binlog放到故障节点上,然后调用故障节点的 BackupObj->restore 方法(指定镜像文件和binglog文件路径)进行恢复。

格外注意:

故障节点恢复之后,它的角色必须是Slave

大多数情况下,故障节点恢复后都会自动切换成了Slave状态。

DCache提供了数据保护机制,当调用主节点的恢复服务时,不会有任何效果,在日志中会有提示:

server changed from SLAVE to MASTER, slave try to create data failed

下面以模块table主从部署为例,初始状态如下:

主机CacheServer模块名(某一个表)角色
AtableMMaster
BtableSSlave

主节点异常

模拟场景:

由于某种原因导致主节点tableM所在主机A忽然宕机。

启用自动切换

为了保证服务的可用性,一般情况下我们都会设置“主从自动切换”。当出现异常时会自动触发。那么,之前的从节点tableS的状态从Slave切换成Master,变成了主节点。

节点M恢复时,会先到Router中获取自身的角色。正常情况下Router列表已经将主从关系更改了,此时tableM被标记为Slave。状态如下:

主机CacheServer模块名(某一个表)角色
AtableMSlave
BtableSMaster

此时,由tableS继续对外提供读写服务。

由于tableM所在的主机A刚刚恢复,它的共享内存中是空的。这种情况下我们可以什么都不做,等tableM的内存数据慢慢从tableS的binlog里追上来。但是如果此时tableS的主机B也发生了宕机,服务就彻底中断了,会对业务造成影响。

处理流程:

为了避免此类问题发生,就需要快速恢复内存数据。将dump下来的镜像文件和按小时的binlog放在主机A上,然后直接寻址调用tableM的BackupObj->restore方法。

未启用自动切换

这种情况下由 tableS(状态为Slave)提供只读服务,不可写,会对业务有一定的影响。当主机A恢复后,tableM会被自动拉起、以Master身份继续提供读写服务。

但此时由于内存中没数据,读操作会出现“缓存击穿”的现象(前提是tableM配置了DBFlag=Y和ReadDbFlag = Y),会对后端的mysql造成压力。

因此,保险起见,在tableM恢复之后,需要人工在控制台上点击“手动切换”,然后参考“启用自动切换”章节里面的处理流程。

从节点异常

这种情况下不会发生切换。从节点共享内存被破坏、数据丢失,但是由于主节点还存活,不影响读写。

我们可以选择无视,也可以保险一点按照“启用自动切换”章节里面的处理流程进行处理。

主从节点同时异常

这种情况比较少见,但是也不能完全排除,需要准备应急预案。按照如下步骤处理:

  1. 2个节点都恢复后,先到从节点上按照“处理流程”恢复数据;
  2. 然后到控制台上手动切换主从节点(此步骤需要考虑这个表的tps以及配置的binlog同步时间差,否则可能丢数据);
  3. 再到另一个节点(切换了,此时是从节点)上,按照“处理流程”恢复数据。

说明:

上述步骤1、2,“从节点恢复数据后切换为主节点”,是为了避免可能出现的“缓存击穿”现象。


总结

在数据备份、恢复方面,DCache为我们提供了较为完备的解决方案。可以通过手动调用dump和restore来完成数据的全量备份与恢复。

  • 选择主-从集群部署时,有较低概率2个节点同时宕机,可以根据业务需要选择性恢复某些模块的从节点数据;
  • 主-从-异地镜像部署时,有极低的概率3个节点同时宕机。这时候完全不需要考虑数据恢复问题,让故障节点慢慢追数据即可。因为当其中一个节点宕机了,一般情况下都会及时介入解决,保证DCache至少同时有2个节点在线。因此,极力推荐3节点部署

内存库的数据恢复需要考虑到很多细节,更需要大量的时间和实践来验证。DCache在这方面做得很不错,考虑到了在数据恢复过程中所有可能出现的问题,我们可以放心使用。但在项目实践中,也发现了一些缺点:

  1. 个人分析DCache的设计初衷,就是“以内存数据为基准”,没有提供反向更新(从数据库更新到内存)的工具,需要自行开发。我们在项目中自研了数据加载工具,实现从mysql将表数据全量或单条加载到内存库中。
  2. 数据恢复不能自动执行,而且是Moudule(表)级的,一次操作只能针对某一个Moudule的备份、恢复。需要自行编写批量处理脚本。
  3. 主从切换时有数据丢失的风险,需要根据系统压力灵活调整参数配置(如主备机binlog差异的阈值 SwitchBinLogDiffLimit,详见《主备切换》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员柒叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值