diff --git a/docs/benchmark.md b/docs/benchmark.md new file mode 100644 index 0000000..e4b6a53 --- /dev/null +++ b/docs/benchmark.md @@ -0,0 +1,23 @@ +## 测试背景和目标 +了解DCache两种数据类型的读写性能,以及对于机器的压力情况(包括CPU、IO、网络)。 + +## 测试环境 +#### 软件环境 +> 1. 基于Tars(2019年4月最新版本) +> 2. 单进程服务,Cache是纯内存类型(即后端不带DB) + +#### 硬件环境 +> 1. CPU 48核(Intel(R) Xeon(R) CPU E5-2670 v3 @2.30GHz),内存128G,万兆网卡 +> 2. 测试客户端与服务端同机房 + +## 测试方法 +有两个客户端并发访问DCache的接口(不经过Proxy,直接访问cache),其中每个客户端开启10个进程,每个进程开启20个线程,共有400个线程并发调用DCache的读写接口(先测写接口,再测读接口);DCache服务端开启6个网络线程和12个工作线程。在压测过程中记录机器的各项性能指标。 + +## 测试结果 + +数据类型 | 读/写 | 数据长度(Byte) | CPU | 网卡(Mbit/s) | TPS(w/s) +---|---|---|---|---|--- +k-v | 读 | 100 | 1400% | 800 | 66 +k-v | 写 | 100 | 800% | 450 | 18.5 +k-k-row | 读 | 100 | 1600% | 900 | 45 +k-k-row | 写 | 100 | 950% | 430 | 16 \ No newline at end of file diff --git a/docs/dbaccess.md b/docs/dbaccess.md new file mode 100644 index 0000000..cdb10ff --- /dev/null +++ b/docs/dbaccess.md @@ -0,0 +1,95 @@ +dbaccess是Cache访问持久化服务的代理服务,持久化服务可以是MySQL、SQL Server, PostgreSQL等数据库,针对不同的持久化存储,开发者需要开发不同的dbaccess服务。本篇文档的目标读者是需要实现内存数据持久化存储的相关人员。 + +Cache通过以下两种方式实现数据持久化: +> 1. 定期将脏数据写入db中 +> 2. 在内存不足时,根据lru算法将最‘冷’数据写入到db中 + +下面以使用MySQL作为持久化存储为例,展示如何开发、部署DbAccess,以及配置DCache开启持久化功能。 + +> * [提供MySQL DB实例和数据表](#1) +> * [开发一个基于tars的dbaccess服务](#2) +> * [相关配置](#3) +> * [部署dbaccess服务](#4) + +## 1. 提供MySQL DB实例和数据表 + +**step1: 提供MySQL DB实例** + +如果没有,请参考官方文档安装。 + +**step2:建表** + +一个模块对应一张表。 + +假设你有一个key-value模块,其中key是身份ID,value是地址信息,那么建表时就要创建3个字段:person_ID,person_Address,sDCacheExpireTime,其中字段“sDCacheExpireTime”是DCache要求增加的一个额外字段,表示过期时间。 + + +假设你有一个k-k-row模块,其中主key是身份ID,联合key是课程ID,value是成绩,那么建表时就要指定4个字段:person_ID,course_ID,score,sDCacheExpireTime,其中字段“sDCacheExpireTime”是DCache要求增加的一个额外字段,表示过期时间。 + + +## 2. 开发一个基于tars的dbaccess服务 + +dbaccess服务是DCache访问MySQL的代理,在dbaccess服务中通过访问MySQL从而实现数据的持久化。要求阅读本节的读者已经掌握开发一个tars服务的基本流程。 + +在DCache的源码中已经提供了一个简洁版的[dbaccess服务](https://github.com/Tencent/DCache/tree/master/src/DbAccess/example),读者可参考并完善(接口声明文件[DbAccess.tars](https://github.com/Tencent/DCache/blob/master/src/DbAccess/example/DbAccess.tars)请勿修改,DbAccess服务必须实现该文件中的接口),然后编译生成发布包。 + + + + +## 3. 相关配置 + +发布dbaccess服务前,需要作一些相应的配置,修改配置后需重启服务才能生效。 + +#### 3.1. 配置dbaccess服务 +dbaccess服务的配置可参考库中的[DbAccess.conf文件](https://github.com/Tencent/DCache/blob/master/src/DbAccess/example/DbAccess.conf),主要包括MySQL实例的用户名,密码和端口等信息。 + +#### 3.2. 配置Cache服务 + +配置Cache服务分两种场景:**新建模块**接入dbaccess和**已有模块**接入dbaccess。 + +##### 3.2.1 新模块接入dbaccess服务 +在新建模块时,应用场景选择“cache + 持久化”,并填写相应的Obj信息,如下图所示: + +![新模块接入dbaccess](images/newModuleWithDbaccess.png) + +ObjName可以通过点击“管理Servant”获取,如下图所示: + +![获取Obj信息](images/getDbaccessObj.png) + + +##### 3.2.2 已有模块接入dbaccess服务 + +修改Cache模块的Main/DbAccess 配置项: + +``` +1. DBFlag = Y, +2. ReadDbFlag = Y, +3. ObjName = 已部署的DbAccess服务的obj信息,例如StoreData.dbaccess.DbAccessObj +``` + + +##### 3.2.3 其他配置项 +以下几个配置(包括但不限于)和数据持久化相关 + +``` +1. Main/Cache = Y/N // 当容量达到阈值时,是否允许自动淘汰旧的数据 +2. Main/Cache = 5 // 每次淘汰数据的时间间隔(秒) +3. Main/Cache = 1 // 回写脏数据的线程数,线程越大,回写越快,DB压力越大 +4. Main/Cache = 300 // 回写时间(秒),即回写多久以前的数据,时间越大,保留脏数据越多 +5. Main/Cache = 100 // 回写操作的时间间隔(秒),即频率 +``` + + + +## 4. 部署dbaccess服务 +生成dbaccess服务的发布包和做好相关配置后,就可以在tars管理平台部署该服务了。 + +**step1:** 服务部署 + +![部署dbaccess服务](images/deployDbaccess.png) + +**step2:** 发布服务 + +![发布dbaccess服务](images/releaseDbaccess.png) + +上传在[开发一个基于tars的dbaccess服务](#2)生成的发布包。 \ No newline at end of file diff --git a/docs/images/deployDbaccess.png b/docs/images/deployDbaccess.png new file mode 100644 index 0000000..e5d827a Binary files /dev/null and b/docs/images/deployDbaccess.png differ diff --git a/docs/images/getDbaccessObj.png b/docs/images/getDbaccessObj.png new file mode 100644 index 0000000..18c5aa5 Binary files /dev/null and b/docs/images/getDbaccessObj.png differ diff --git a/docs/images/newModuleWithDbaccess.png b/docs/images/newModuleWithDbaccess.png new file mode 100644 index 0000000..0023aeb Binary files /dev/null and b/docs/images/newModuleWithDbaccess.png differ diff --git a/docs/images/releaseDbaccess.png b/docs/images/releaseDbaccess.png new file mode 100644 index 0000000..4111c1a Binary files /dev/null and b/docs/images/releaseDbaccess.png differ diff --git a/src/KVCacheServer/BackUp.tars b/src/KVCacheServer/BackUp.tars index 369acf7..c84e9d1 100644 --- a/src/KVCacheServer/BackUp.tars +++ b/src/KVCacheServer/BackUp.tars @@ -17,8 +17,8 @@ interface BackUp { /* * dump内存数据到指定路径文件 - * dumpPath: 存放镜像文件的绝对路径,如果为空则dump到默认路径 - * mirrorName: 镜像名 + * dumpPath: 存放镜像文件的绝对路径,如果为空则dump到默认路径:/data/dcache/dump_binlog/ + * mirrorName: 镜像文件名, 如果为空则使用组名和当前时间生成文件名,例如:TestModuleKVGroup1_dump_binlog_20190701120101.log.gz */ int dump(string dumpPath, string mirrorName, out string errmsg); diff --git a/src/KVCacheServer/BackUpImp.cpp b/src/KVCacheServer/BackUpImp.cpp index 907cbc8..c295bfd 100644 --- a/src/KVCacheServer/BackUpImp.cpp +++ b/src/KVCacheServer/BackUpImp.cpp @@ -34,6 +34,7 @@ tars::Int32 BackUpImp::dump(const std::string &dumpPath, const std::string &mirr return 0; } g_app.dumpThread()->start(); + return 0; } catch (const TarsException & ex) { diff --git a/src/KVCacheServer/DumpThread.cpp b/src/KVCacheServer/DumpThread.cpp index 177f0ce..39849fb 100644 --- a/src/KVCacheServer/DumpThread.cpp +++ b/src/KVCacheServer/DumpThread.cpp @@ -40,6 +40,23 @@ int DumpThread::init(const string &dumpPath, const string &mirrorName, const str _dumpPath = "/data/dcache/dump_binlog/"; //使用默认dump路径 FDLOG(_dumpDayLog) << "[DumpThread::init] dumpPath:" << dumpPath << " is not absolute path, use default path: /data/dcache/dump_binlog/" << endl; } + else + { + _dumpPath = dumpPath; + } + + if (mirrorName.empty()) + { + // using default mirror name + _mirrorName = g_app.gstat()->groupName() + string("_dump_binlog_") + TC_Common::now2str() + string(".log.gz"); + FDLOG(_dumpDayLog) << "[DumpThread::init] mirrorName is empty, use default mirror name: groupname_dump_binlog_nowtime.log.gz" << endl; + } + else + { + _mirrorName = mirrorName; + } + + FDLOG(_dumpDayLog) << "[DumpThread::init] finish" << endl; return 0; } diff --git a/src/MKVCacheServer/DumpThread.cpp b/src/MKVCacheServer/DumpThread.cpp index 69b4bb1..7b1f200 100644 --- a/src/MKVCacheServer/DumpThread.cpp +++ b/src/MKVCacheServer/DumpThread.cpp @@ -34,14 +34,28 @@ int DumpThread::init(const string &dumpPath, const string &mirrorName, const str _config = sConf; _tcConf.parseFile(_config); + _dumpDayLog = _tcConf.get("/Main/", "dumpAndRecover"); + if (!TC_File::isAbsolute(dumpPath)) { _dumpPath = "/data/dcache/dump_binlog/"; //使用默认dump路径 FDLOG(_dumpDayLog) << "[DumpThread::init] dumpPath:" << dumpPath << " is not absolute path, use default path: /data/dcache/dump_binlog/" << endl; } + else + { + _dumpPath = dumpPath; + } - _dumpPath = dumpPath; - _mirrorName = mirrorName; + if (mirrorName.empty()) + { + // using default mirror name + _mirrorName = g_app.gstat()->groupName() + string("_dump_binlog_") + TC_Common::now2str() + string(".log.gz"); + FDLOG(_dumpDayLog) << "[DumpThread::init] mirrorName is empty, use default mirror name: groupname_dump_binlog_nowtime.log.gz" << endl; + } + else + { + _mirrorName = mirrorName; + } FDLOG(_dumpDayLog) << "[DumpThread::init] finish" << endl; diff --git a/src/MKVCacheServer/MKBackUp.tars b/src/MKVCacheServer/MKBackUp.tars index b53da34..eb4b11a 100644 --- a/src/MKVCacheServer/MKBackUp.tars +++ b/src/MKVCacheServer/MKBackUp.tars @@ -17,8 +17,8 @@ interface MKBackUp { /* * dump内存数据到指定路径文件 - * dumpPath: 存放镜像文件的绝对路径,如果为空则dump到默认路径 - * mirrorName: 镜像名 + * dumpPath: 存放镜像文件的绝对路径,如果为空则dump到默认路径:/data/dcache/dump_binlog/ + * mirrorName: 镜像文件名, 如果为空则使用组名和当前时间生成文件名,例如:TestModuleMKVGroup1_dump_binlog_20190701120101.log.gz */ int dump(string dumpPath, string mirrorName, out string errmsg); diff --git a/test/Proxy/RouterTableTest.cpp b/test/Proxy/RouterTableTest.cpp index 6b88b60..5363764 100644 --- a/test/Proxy/RouterTableTest.cpp +++ b/test/Proxy/RouterTableTest.cpp @@ -216,6 +216,8 @@ string getRandString() "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; + + srand(time(0)); string randString = ""; size_t randLen = rand() % 100;