DCache-CacheServer分析(三)

本文详细解读了SyncAllThread(脏数据回写)、HeartBeatThread(心跳上报)和TimerThread(定时任务)的配置参数,涉及内存一致性、心跳间隔、路由同步和自动降级处理,以及一个实际故障案例及解决策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019年12月10日

本文分析了SyncAllThread、HeartBeatThread和TimerThread的关键配置参数和处理流程。

SyncAllThread

功能:回写所有脏数据。

在控制台数据运维指令”syncdata"时启动该线程处理。

文件:

SyncAllThread.h
SyncAllThread.cpp

配置解析

#回写时间(秒),即回写多久以前的数据
SyncTime=300

SyncTime配置成300,意思是回写5分钟以前的“脏”数据到后端(mysql)数据库中。

可以通过修改这个值,来调整内存与后端db的数据一致性频率。

对于一些从关系型db提取数据、且实时性要求较高的系统,如实时大屏,就可以将SyncTime这个参数调低,如SyncTime=1,表示每秒同步一次。

注意:

这个参数在设置时,一定要考虑到数据库的压力,需要在数据库性能和实时性间寻找平衡。

对于那些日报表、月度报表等非实时性应用,就需要根据主机内存的压力情况来设置这个值,以保证(内存)数据不会因过期而丢失。

线程逻辑

1、在控制台数据运维指令”syncdata”时,创建该线程

2、回写SyncTime秒以前的数据

说明:

这个线程不会自动创建,只能由控制台指令触发。


HeartBeatThread

功能:Slave定时上报心跳线程。

线程创建后,调用RouterHandle::getConnectHbAddr(),获取master节点上收集心跳的Servant-ControlAckObj信息;如果是master节点,则禁用上报功能(_enableConHb=false,但该线程还在)。

所在文件:

TimerThread.h
TimerThread.cpp

配置解析

#向Router上报心跳的间隔(毫秒)
RouterHeartbeatInterval=1000

每隔RouterHeartbeatInterval秒,Slave向Router和Master上报心跳。

线程逻辑

1、获取master节点的ControlAckObj对象代理

开始循环:

2、向router服务发送心跳(RouterHandle::getInstance()->heartBeat(),调用router服务的方法_routePrx->heartBeatReport)

3、如果开启了心跳上报功能(_enableConHb==true),即本节点为slave节点,则向master的ControlAckObj对象上报心跳(MKControlAckImp::connectHb)

4、在MKControlAckImp::connectHb中,会增加备机上报心跳的计数(++_slaveHbCount),以供TimeThread判断降级

5、休眠RouterHeartbeatInterval秒后,再次执行2.

说明:

只有Slave会启动这个线程


TimerThread

功能:定时作业线程类。

包括同步路由信息给Router,上报属性信息给Property(用于监控),binlog心跳,上报get命中率,判断是否自动降级等。

相关文件:

TimerThread.h
TimerThread.cpp

配置解析

<Router>
    #同步路由的时间间隔(秒)
    SyncInterval=1
</Router>

<BinLog>
    #active binlog产生的周期(秒)
    HeartbeatInterval=600
</BinLog>

<BinLog>
    #是否记录binlog
    Record=Y
    #是否记录key binlog
    KeyRecord=N
    #binlog日志文件名后缀
    LogFile=binlog
</BinLog>

#模块名
ModuleName=Test

<Cache>
    #内存块个数
    JmemNum=2
    #主机自动降级超时时间(秒),即30s无心跳则自动降级
    DowngradeTimeout=30
</Cache>

每个配置项的功能见注释信息,比较详细了,不赘述。

初始化

1、读取配置

2、创建属性上报对象,涉及到的属性如下:

CountOfDirtyRecords,        平均值
CacheHitRatio,              平均值
CacheMemSize_MB,            平均值
DataMemUsage,               平均值
ProportionOfDirtyRecords,   平均值
ChunkUsedPerRecord,         平均值
MKV_MainkeyMemUsage,        平均值
TotalCountOfRecords,        平均值
CountOfOnlyKey,             平均值
MaxMemUsageOfJmem,          平均值
JmemNDataUsedRatio,         平均值,其中“N”为Jmem的编号  

线程逻辑

1、同步路由

  • 判断是否过了同步路由的周期SyncInterval
  • 如果处于备机恢复状态(g_app.gstat()->isSlaveCreating()),则不同步路由;如果是主节点,则在控制台和日志中输出错误信息:
server changed from SLAVE to MASTER when in data creating status
  • 调用_routerHandle->syncRoute(),同步路由

2、binlog心跳

  • 如果已过binlog心跳的时间间隔HeartbeatInterval,则尝试记录”ACTIVE"binlog
  • 如果Record=Y/y,则将”ACTIVE"binlog记录到本地磁盘binlog文件中;key binlog同理。文件内容如下:

 

内容是:SERA+BinlogLength+” “+”Active”。

3、上报get命中率,CacheHitRatio

4、每隔60s,上报一次

  • 总内存(CacheMemSize_MB)
  • 内存使用率(DataMemUsage)
  • Jmem的使用率(JmemNDataUsedRatio)
  • Jmem的最大使用量(MaxMemUsageOfJmem)
  • CountOfOnlyKey
  • MKV_MainkeyMemUsage
  • 脏数据比率(ProportionOfDirtyRecords)
  • 平均每条记录使用的数据块个数(ChunkUsedPerRecord)
  • 脏数据个数(CountOfDirtyRecords)
  • 总记录数(TotalCountOfRecords)

5、每隔60s,清除1次 迁移目的服务器数据大小限制(cleanDestTransLimit)

6、主机自动降级判断(master节点才会有的逻辑)

  • 当DowngradeTimeout配置大于0、且检测时间已超时,则获取节点的心跳次数(RouterHandle::getInstance()->getSlaveHbCount())
  • 与上一次(DowngradeTimeout秒之前)采集的心跳次数相比较,如果相等,则说明在DowngradeTimeout时间间隔内没有收到备机心跳,可能有异常;
  • 心跳超时处理(handleConnectHbTimeout),向每个router上报心跳;如果上报都失败,则进行降级处理(RouterHandle::getInstance()->masterDowngrade())
  • 将本节点设置为slave节点,然后上报心跳给master(g_app.enableConnectHb(true),这里只是将_enableConHb置位,由HeartBeatThread上报)

7、休眠1s,继续步骤1

案例分享

这里需要说一下,自动降级的判断逻辑并非完美,我就遇到过一种情况,主备没有自动切换,导致业务服务的操作失败:

1、Slave 无法上报心跳给 Master 了

  • 这就导致Master在下一个定时任务周期会进行降级检测:向所有Router发送心跳消息
  • 但是 Master 连接不到Router,就触发自动降级,Master变为 “Slave”状态;

2、对于Router服务而言,Master连接到不到Router了,而Router可以正常连接到Master,这就导致

  • Master上报心跳超时,Router检测到后,尝试触发主备切换;
  • 但是 Router可以正常连接到Master,向Master发送心跳ok,不满足主备切换条件,所以就取消了主备切换操作;导致路由信息没有修改

3、所以,当前的状态为

  • 在Router侧,路由信息没有变化,跟异常之前一样
  • “Master节点” 和 Slave节点 的实际服务状态都为“Slave”
  • 写操作仍会路由到“Master节点”,但是Master记录的自身状态为“Slave”,就拒绝写入。

你可能会有疑问:为什么Slave连接不到Master,Master连接不上Router,而Router却可以连接到Master?

这也是个坑!一般人不会告诉你:这是因为你的注册中心处理线程太少了

当注册中心处理线程不足时,有一些Tars微服务就拉取不到目标服务的地址列表了。如上面提到的情况,查看日志,发现Slave找不到Maste、Master找不到Router,从而导致主从切换失败。

遇到这样的事情也挺背的,恰巧赶在一起了。

解决方案如下:     

1、需要调整Tars注册中心的处理线程数,保证Router模块可以正常上报心跳,成功注册到注册中心,这样一来,CacheServer就可以读取到Router服务的信息了。

理论上,只要注册中心的处理线程足够多,就不会出现上述问题。但实时却总是啪啪打脸...

以防万一:

2、调整 CacheServer 的配置参数,心跳超时时不启用自动降级功能

虽然这样做有风险,但直到目前为止,生产环境没有因此而出现不可用的情况。


总结

本文介绍了SyncAllThread、HeartBeatThread和TimerThread的关键配置参数和处理流程,并分享了一个自动降级失败案例和解决方法,希望后来者可以避开这样的坑。

GlusterFS 是一个开源的分布式文件系统,可以通过不同的 translator 来扩展其功能。dcache translator 是一种用于缓存数据的 translator,可以提高文件系统的读取性能。以下是开启 dcache translator 的步骤: 1. **安装 GlusterFS**:确保你的系统上已经安装了 GlusterFS。如果还没有安装,可以使用以下命令进行安装: ```bash sudo apt-get install glusterfs-server ``` 2. **创建卷**:如果还没有创建 GlusterFS 卷,可以使用以下命令创建一个卷: ```bash sudo gluster volume create <volume_name> replica <number_of_replicas> <brick1> <brick2> ... force ``` 例如: ```bash sudo gluster volume create test-volume replica 2 server1:/data/brick1 server2:/data/brick2 force ``` 3. **启动卷**:创建卷后,需要启动该卷: ```bash sudo gluster volume start <volume_name> ``` 例如: ```bash sudo gluster volume start test-volume ``` 4. **配置 dcache translator**:要开启 dcache translator,需要在卷上添加该 translator。可以使用以下命令: ```bash sudo gluster volume set <volume_name> features.cache-invalidation on sudo gluster volume set <volume_name> performance.cache-size <cache_size> sudo gluster volume set <volume_name> performance.cache-refresh-timeout <timeout> ``` 例如: ```bash sudo gluster volume set test-volume features.cache-invalidation on sudo gluster volume set test-volume performance.cache-size 256MB sudo gluster volume set test-volume performance.cache-refresh-timeout 60 ``` 5. **重启卷**:配置完成后,需要重启卷以应用更改: ```bash sudo gluster volume stop <volume_name> sudo gluster volume start <volume_name> ``` 例如: ```bash sudo gluster volume stop test-volume sudo gluster volume start test-volume ``` 通过以上步骤,你就可以在 GlusterFS 中开启 dcache translator 了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员柒叔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值