DCache踩坑记录

DCache踩坑记录2019 年 8 月 3 日 DCache 在 4 月份开源了 它是基于 Tars 微服务框架开发的分布式内存数据库 k v 就赶紧拿来研究了下 经过了一段时间的验证 遇到了很多问题 在此记录一下 注意 本篇笔记写于 2019 年 8 月 文章中出现的问题可能已经修复 但您也可以体验一下第一批拥护者完整的采坑过程 一 权限管理模块问题 DCache 接入权限管理模块 有显示的问题 配置显示不出来 要想在 web 上修改配置 必须使用 TarsWeb dcache alpha 版本的 或者不接入权限管理模块

2019年8月3日

DCache在4月份开源了,它是基于Tars微服务框架开发的分布式内存数据库(k-v),就赶紧拿来研究了下。经过了一段时间的验证,遇到了很多问题,在此记录一下。

注意:

本篇笔记写于2019年8月,文章中出现的问题可能已经修复,但您也可以体验一下第一批拥护者完整的采坑过程。

一、权限管理模块问题

DCache接入权限管理模块,有显示的问题:配置显示不出来。

要想在web上修改配置,必须使用 TarsWeb-dcache-alpha 版本的。

或者不接入权限管理模块。

说明:

从2.4.10版本开始,权限模块和Web已经整合了,不需要再自行安装了。

所以此问题可以忽略。

二、模块设计

在设计上, 一个module对应一张表,后端对应1个DbAcessServer。

三、连接DbAcessServer时的配置问题

module的配置,MKCacheServer.conf:(内容简略)

 
  
此处内容略 ………… BackupDayLog=dumpAndRecover 此处内容略 ………… CoreSizeLimit=-1 DbDayLog=db DBFlag=Y ObjName=DCache.DbAccessServer.DbAccessObj ReadDbFlag=Y MKey=sync_relation_no UKey=ID|NAME sync_relation_no = 0|long|require||0 ID = 1|int|require||0 NAME = 2|string|require||0 SCORE = 3|int|optional|0|0 SEX = 4|string|require|F|0 AGE = 5|int|require||0 GRADE = 6|int|require||0 VKey=SCORE|SEX|AGE|GRADE MKeyMaxBlockCount=20000 ModuleName=myAppMKVtest2 ObjName=DCache.RouterServer.RouterObj PageSize=10000 RouteFile=Route.dat SyncInterval=1 RouterHeartbeatInterval=1000
ShmKey=22331 ShmSize=1G

DbAcessServer的配置:

 
  
# 1-KVCache, 2-MKVCache CacheType = 2 # for KVCache, field info of backend db table. # # KeyNameInDB=userId # ValueNameInDB=userInfo # # backend db config info charset = utf8 dbname = test dbhost = 10.4.121.176 dbport = 3306 dbuser = tars dbpass = tars2015 # table to persist cache entries TableName=mkv_test_2 # db select limit SelectLimit=

当后端需要连接DbAcessServer时,需要注意:

1、配置文件中配置的字段名必须大写

因为当前版本的DbAcessServer从数据库读取字段时,给cacheServer回传的字段都是大写的;如果在创建cacheServer时配置的字段不是大写,会报错:

createEncodeStream field not found:字段名

这段检测的代码逻辑在MKCacheComm.cpp文件的createEncodeStream函数中。

主key字段除外,保证名称一致即可。

2、添加DbAcessServer

如果在已有的cache上添加DbAcessServer,在web管理平台上修改以下3项:

DCache踩坑记录

如果字段中有小写字母,需要将字段修改为大写(主key除外):

同时修改Main/Record/Field的配置,该配置需要在数据库中修改(web上有bug,无法实现回车换行)!

直接修改表中数据

select * from t_config_table where config_id=42275 and item_id=527

config_id为对应的cacheServer的id,在表 t_config_reference中可查到;

item_id=527 即为该项配置:

DCache踩坑记录

 注意:最后一行,必须有换行!

修改结束后,在web控制台上重启服务,或者reload配置。

3、主key注意事项

在k-k-row类型的cache中,mainKey是可以不唯一的!

所以在数据库设计中,该字段不能设置为primaryKey或者是唯一索引。

可以将mainKey和uKey设计成联合索引,唯一。


2019年10月

四、内存问题

1、ShmKey

服务停止或下线时,不会自动清理共享内存、信号量资源,需要人工在后台手动清理

  • CacheServer程序在启动时会根据该server下是否存在SemKey.dat文件来决定是否重新申请共享内存。因此,如需重新申请共享内存,需要清理tarsnode/data/[CacheServer]/data 目录下的SemKey.dat文件。
  • 信号量的key值与共享内存key值时一样的

2、ShmSize

  • 在创建CacheServer时,不可手动设置小于”G”的内存。
  • 服务发布后,可在“配置中心”中,修改内存大小,必须注明单位,如“50K”,“50M”,“2G”。
  • 内存大小修改后,必须后台手动清理共享资源(共享内存、信号量),删除SemKey.dat文件,然后在web页面重启服务。

3、SemKey.dat作用

在主节点异常down机时(共享内存已经被清除了);这时如果再次重启主节点,会失败,日志中报如下错误:

SemKey.dat exist, but shmget 1601 failed, errno = 2,master server assert. MKVCacheServer: MKCacheServer.cpp:915: virtual void MKCacheServer::initialize(): Assertion `false' failed.

从节点的共享内存如果也被清理掉了,且后端未接DbAcess,重启时会报错:

SemKey.dat exist, but shmget 1602 failed, errno = 2,has no backend DB, assert. MKVCacheServer: MKCacheServer.cpp:929: virtual void MKCacheServer::initialize(): Assertion `false' failed.

基于以上逻辑,有如下异常处理机制:

主节点异常down机,共享内存被删除时:

  •   将该cache接入DbAcess
  •   等待有用数据全部同步到db中
  •   清理主节点的SemKey.dat文件,控制台重启主节点

此时,客户端会访问主节点的数据,由于DbAcess的存在,内存中不存在的数据会从db中读取

注意:以上处理方法,需要再做斟酌。

4、pagecache 被大量占用

主机的buffer/cache被大量占用、且不释放(64G内存的主机,61G的buffer/cache)。可以按照如下处理方法:

  • echo 1 > /proc/sys/vm/drop_caches:表示清除pagecache。这一步清理了绝大部分的缓存。
  • echo 2 > /proc/sys/vm/drop_caches:表示清除回收slab分配器中的对象(包括目录项缓存和inode缓存)。slab分配器是内核中管理内存的一种机制,其中很多缓存数据实现都是用的pagecache。
  • echo 3 > /proc/sys/vm/drop_caches:表示清除pagecache和slab分配器中的缓存对象。

五、主备切换不好使

场景:手动停止CacheServer的主节点。

Router日志:

2019-10-09 14:05:29|SwitchThread::doSwitch catch exception: [ServantProxy::invoke timeout:3000,servant:DCache.myAppMKVtest2MKVCacheServer1-1.RouterClientObj,func:helloBaby,adaptertcp -h 10.4.120 .136 -p 19046,reqid:5] 2019-10-09 14:05:32|SwitchThread::doSwitch catch exception: [ServantProxy::invoke timeout:3000,servant:DCache.myAppMKVtest2MKVCacheServer1-1.RouterClientObj,func:helloBaby,adaptertcp -h 10.4.120 .136 -p 19046,reqid:6] 2019-10-09 14:05:32|heartBeatSend to slaveName:DCache.myAppMKVtest2MKVCacheServer1-2 2019-10-09 14:05:32|SwitchThread::doSwitch send heartBeat ok ServerName:DCache.myAppMKVtest2MKVCacheServer1-2 2019-10-09 14:05:32|heartBeatSend to slaveName ok:DCache.myAppMKVtest2MKVCacheServer1-2 2019-10-09 14:05:32|query slaveBinlogdif from slaveName:DCache.myAppMKVtest2MKVCacheServer1-2 2019-10-09 14:05:32|SwitchThread:: slaveBinlogdif diffBinlogTime() > 300 DCache.myAppMKVtest2MKVCacheServer1-2 2019-10-09 14:05:32|removeSwitchModule moduleName : myAppMKVtest2| switch tasks : 0

可能原因:

  1. 主从节点的时钟有问题,误差不能超过200ms。这个原因最常见。
  2. 一种保护机制,当主从节点的binlog文件超过300ms没有同步时,可能存在数据丢失的风险,因此不会触发自动切换。

从代码层面分析,该差异时间的计算,是在RouterHandle::getBinlogdif 中进行的:

difBinlogTime = g_app.gstat()->getBinlogTimeLast() - g_app.gstat()->getBinlogTimeSync();

即最后一次同步的时间点,减去当前同步的时间点。

如果这个差值大于 getSwitchBinLogDiffLimit 的值(默认300毫秒),就会报错:

SwitchThread:: slaveBinlogdif diffBinlogTime() > 300 DCache.myAppMKVtest2MKVCacheServer1-2 

为什么主从节点的时钟误差不能超过200ms?来看下binlog同步频率。

binlog的更新时间,是在BinLogTimeThread::UpdateLastBinLogTime中进行的,由BinLogThread::syncBinLog调用。其中,最后一次同步时间和当前同步时间,是调用了BinLogImp::getLog服务获得的,由DCache::BinLogRsp返回:

tars::Int32 BinLogImp::getLog(const DCache::BinLogReq &req, DCache::BinLogRsp &rsp, tars::TarsCurrentPtr current) 

看了下BinLogThread的代码,同步线程100ms 执行1次,而且这个值是代码里写死的。

所以主从节点的时钟误差不能超过200ms。


总结

最后,总结下需要重点注意的几点:

1、DCache部署模块(表)时,字段名称要大写

2、服务停止或下线时,不会自动清理共享内存、信号量资源,需要人工在后台手动清理

3、要做好时钟同步(主从节点的时钟误差不能超过200ms,否则主备无法自动切换)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/176494.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午9:47
下一篇 2026年3月26日 下午9:48


相关推荐

  • 比较spring cloud和dubbo,各自的优缺点是什么[通俗易懂]

    dubbo由于是二进制的传输,占用带宽会更少springCloud是http协议传输,带宽会比较多,同时使用http协议一般会使用JSON报文,消耗会更大dubbo的开发难度较大,原因是dubbo的jar包依赖问题很多大型工程无法解决springcloud的接口协议约定比较自由且松散,需要有强有力的行政措施来限制接口无序升级dubbo的注册中心可以选择zk,redis等多种,sp…

    2022年4月17日
    86
  • html跳转网页代码_迅雷搜索引擎蜘蛛

    html跳转网页代码_迅雷搜索引擎蜘蛛蜘蛛正常访问用户访问直接跳转,这样的需求相信有很多人都遇到过,也就是:当用户点击进入网站页面的时候,会直接跳转到指定的网页,但是当蜘蛛进来访问时就不会跳转,让蜘蛛可以正常抓取。如果你现在正好需要这样做,那么就直接复制下面的代码放到你的网站页脚里即可!if(window.name!=’ad_app6′){varr=document.referrer;r=r.toLowerCase()…

    2022年8月13日
    11
  • adb下载安装及使用[通俗易懂]

    adb下载安装及使用[通俗易懂]adb介绍:AndroidDebugBridge(安卓调试桥)tools。它就是一个命令行窗口,用于通过电脑端与模拟器或者是设备之间的交互。ADB是一个C/S架构的应用程序,由三部分组成:运行在pc端的adbclient:命令行程序”adb”用于从shell或脚本中运行adb命令。首先,“adb”程序尝试定位主机上的ADB服务器,如果找不到ADB服务器,“adb”程序自动启动一个A…

    2022年4月27日
    71
  • 网页设计音乐播放器_简洁的音乐播放器

    网页设计音乐播放器_简洁的音乐播放器今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。于是乎用h5audio的加上js简单的播放器完工了。演示地点演示html代码如下` music 这个年纪 七月的风 音乐 `然后就是css`*{ margin:0; padding:0; text-decoration:none; list-…

    2022年10月13日
    6
  • 浅谈RHEL7和RHEL6的主要变化

    浅谈RHEL7和RHEL6的主要变化

    2022年4月2日
    52
  • 天堂2四章_天堂2外网设置

    天堂2四章_天堂2外网设置天堂2私服架设技术教程  

    2026年4月16日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号