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>#是否记录binlogRecord=Y#是否记录key binlogKeyRecord=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的关键配置参数和处理流程,并分享了一个自动降级失败案例和解决方法,希望后来者可以避开这样的坑。

DCache-CacheServer分析(三)相关推荐

  1. 三年级学生计算机学情分析,三年级上学期学生学情分析

    010在线为您甄选多篇描写三年级上学期学生学情分析,三年级上学期学生学情分析精选,三年级上学期学生学情分析大全,有议论,叙事 ,想象等形式.文章字数有400字.600字.800字....缓存时间: 2 ...

  2. 计算机组装与维修案例分析,设备故障维修案例分析三则

    设备故障维修案例分析三则 本文列举较具有代表性的故障维修的三个案例,以此阐述在医疗设备维修中对各方面知识综合运用的能力以及对设备故障诊断分析过 (本文共2页) 阅读全文>> 针对通信设备故 ...

  3. linux 查看握手时间,实战:tcpdump抓包分析三次握手四次挥手

    本文档以实战的形式介绍tcpdump抓包分析三次握手四次挥手的过程. 执行tcpdump命令 tcpdump -n -i ens32 host 192.168.10.10 and 42.186.113 ...

  4. Android 系统(42)---Android7.0 PowerManagerService亮灭屏分析(三)

    Android7.0 PowerManagerService亮灭屏分析(三) 在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了. 在D ...

  5. Nouveau源码分析(三):NVIDIA设备初始化之nouveau_drm_probe

    Nouveau源码分析(三) 向DRM注册了Nouveau驱动之后,内核中的PCI模块就会扫描所有没有对应驱动的设备,然后和nouveau_drm_pci_table对照. 对于匹配的设备,PCI模块 ...

  6. Nouveau源代码分析(三):NVIDIA设备初始化之nouveau_drm_probe

    Nouveau源代码分析(三) 向DRM注冊了Nouveau驱动之后,内核中的PCI模块就会扫描全部没有相应驱动的设备,然后和nouveau_drm_pci_table对比. 对于匹配的设备,PCI模 ...

  7. 【投屏】Scrcpy源码分析三(Client篇-投屏阶段)

    Scrcpy源码分析系列 [投屏]Scrcpy源码分析一(编译篇) [投屏]Scrcpy源码分析二(Client篇-连接阶段) [投屏]Scrcpy源码分析三(Client篇-投屏阶段) [投屏]Sc ...

  8. Spring源码分析(三)

    Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...

  9. 群体进化,群体结构分析之STRUCTURE分析三款软件比较

    STRUCTURE分析三款软件比较 三篇高引用文章 2005-STRUCTURE[1] 把选k值写的很清楚 2020/5/16 引用13119 这篇文章发表的时候二代测序还没兴起,ssr等的标记数量有 ...

  10. 运营人常备的8个营销模型一、SWOT分析二、PEST分析三、3C

    运营人常备的8个营销模型 一.SWOT分析 二.PEST分析 三.3C战略模型 四.STP理论 五.波特五力模型 六.波士顿矩阵 七.GE矩阵 八.商业模式画布 内容如下: 一.SWOT分析 1.st ...

最新文章

  1. Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性
  2. 织梦php首页老是自动恢复,dede首页网址自动加上index.html问题解决方法
  3. Excel ,三步 快速实现应用一个公式到一列或一行中
  4. Linux-Bind-DNS服务器配置实例
  5. 最难学编程语言排汗榜
  6. ASP.NET Core Middleware
  7. MongoDB(二):MongoDB的安装
  8. python调用cmd命令释放端口_Python——cmd调用(os.system阻塞处理)(多条命令执行)...
  9. caffe.net matlab,windows-matlab环境下,生成的caffe模型无法运行
  10. android 命名空间解析,Android Bluetooth、Android AdapterView等命名空间-Android中文API文档...
  11. pgAdmin3 连接GreenPlum数据库假死解决
  12. three.js入门——写个小车
  13. jdk7与jdk8 如何相互切换
  14. matlab三相仿真电路实验视频,三相逆变电路MATLAB仿真
  15. JConsole详解
  16. unity 打包一直停留在 detecting current sdk tools version
  17. 360P 480P 720P 1080P 1080i 说明
  18. python手机编程软件-手机上Python编程的软件分享
  19. uva490解题报告
  20. 电气工程系毕业设计大全单片机精品设计合集参考案例地址

热门文章

  1. 在onelogin中使用OpenId Connect Authentication Flow
  2. 服务器环境配置发布网站
  3. 网站设置为可信任站点
  4. 佳能Canon FAX-L150 打印机驱动
  5. 建筑工程试验检测管理数字化解决方案
  6. 什么是导航与位置服务器,GPS导航和GPS定位仪与GPS定位器的区别在哪?
  7. Python俄罗斯方块
  8. 每月全球数据存储十大新闻(2020.9.1-9.30),精彩的9月
  9. 云上贵州•大数据国际年会将于7月11日在贵州召开
  10. ABP学习实践(五)--引入Swagger对API接口进行管理