目录
2.2.2 编译文件中的错误(我于20210303下载时是错的,不知后续何时安排修复)
0.学习链接
腾讯技术工程CSDN-腾讯开源 DCache,分布式 NoSQL 存储系统-谈及为什么在有Redis等时还用DCache
TARS基金会CSDN-DCache 分布式存储系统|安装部署与应用创建
TARS基金会CSDN-DCache 分布式存储系统|Key-Value 缓存模块的创建与使用
TARS基金会CSDN-DCache 分布式存储系统|K-K-Row 缓存模块的创建与使用
1.初识DCache
DCache 是一个基于 TARS 框架开发的分布式 NoSQL 存储系统,支持多种数据结构,包括了 key-value(键值
对),k-k-row(多键值),list(列表),set(集合),zset(有序集合)等,满足多种业务需求。
其中 key-value 是最简单也是最常用的类型,我们只需完成以下步骤即可在服务中使用 key-value 缓存服务
DCache 是一个基于 TARS 框架开发的分布式 NoSQL 存储系统,数据采用内存存储,同时支持连接后端DB实现
数据持久化,结合了NoSQL和SQL 的优势,具备以下特点
高性能存储引擎,支持 key-value(键值对),k-k-row(多键值),list(列表),set(集合),zset
(有序集合)等多种数据结构;
采用集群模式,实现高扩展性和高可用性,支持异地镜像,就近接入;
支持通过 TARS 名字服务访问,支持同步、异步、单向 RPC 调用方式;
高效运维平台,在线完成服务部署、扩缩容、迁移,以及服务配置,服务调用质量监控;
业务无须和直接和 MySQL 交互, DCache 会自动缓写 DB.
创建 KV 缓存模块
获取 DCache 接口文件
创建缓存服务代理
调用缓存模块服务
DCache 中为 KV 提供了插入、替换、删除和批量操作键值等丰富的操作接口,使用上非常方便.
本文将基于TestDemo 介绍如何创建Key-Value缓存模块,以及怎么在TARS服务中调用该服务来缓存数
据.
本文用例代码:
https://github.com/ETZhangSX/DCacheDemo
2.安装 DCache
2.1 环境依赖
DCache 基于 TARS 开发,因此编译安装之前,需要先安装 TARS 框架.
2.2 编译构建步骤
2.2.1 编译过程
1.下载源码
git clone https://github.com/Tencent/DCache.git
2.进入DCache目录,执行以下命令进行编译构建
mkdir build
cd build
cmake ..
make
make release
make tar
执行完之后即可生成 DCache 中各服务的发布包.
注意:
可以用make -j4,make -j6,make -j8,make -j16等加速编译,另外机器的内存最好也尽可能的大,
6G-8G大概就可以了.
2.2.2 编译文件中的错误(我于20210303下载时是错的,不知后续何时安排修复)
vim /home/muten/module/TARS/TarsFramework/DCache/test/KVCacheServer/CMakeLists.txt
vim /home/muten/module/TARS/TarsFramework/DCache/test/Proxy/CMakeLists.txt
vim /home/muten/module/TARS/TarsFramework/DCache/test/Router/CMakeLists.txt
修改这三个文件,链接的时候加上dl和pthread
2.3 部署
2.3.1 部署步骤
使用DCache中的自动部署脚本
cd /home/muten/module/TARS/TarsFramework/DCache/build
../deploy/install.sh + 12个入参,入参列表为:
(1)$TARS_MYSQL_IP
(2)$TARS_MYSQL_PORT
(3)$TARS_MYSQL_USER
(4)$TARS_MYSQL_PASSWORD
(5)$DCACHE_MYSQL_IP
(6)$DCACHE_MYSQL_PORT
(7)$DCACHE_MYSQL_USER
(8)$DCACHE_MYSQL_PASSWORD
(9)$CREATE
(10)$WEB_HOST
(11)$WEB_TOKEN
(12)$NODE_IP
各参数释义如下(共12个参数):
(1)TARS_MYSQL_IP: TARS 数据库的 IP;
(2)TARS_MYSQL_PORT: TARS 数据库的端口;
(3)TARS_MYSQL_USER: TARS 数据库的用户名;
(4)TARS_MYSQL_PASSWORD: TARS 数据库的密码;
(5)DCACHE_MYSQL_IP: DCache 数据库的 IP;
(6)DCACHE_MYSQL_PORT: DCache 数据库的端口;
(7)DCACHE_MYSQL_USER: DCache 数据库的用户名;
(8)DCACHE_MYSQL_PASSWORD: DCache 数据库的密码;
(9)CREATE: 是否重新创建 DCache 的数据库,为 true 则重新创建;如果已经创建,例如需要升级原有 DCache,可以设置为 false,避免重新创建;
(10)WEB_HOST: TarsWeb 平台地址;
(11)WEB_TOKEN: TarsWeb 平台 Token (需要进入web平台, 用户中心上, 创建一个 Token);
(12)NODE_IP: 公共服务部署节点 IP, 部署完成后, 你可以在 TarsWeb 平台扩容到多台节点机上。
../deploy/install.sh
(1)192.168.1.123
(2)3306
(3)tarsAdmin
(4)Tars@2019
(5)192.168.1.124
(6)3306
(7)root
(8)123456
(9)true
(10)192.168.1.123:3000
(11)abcdefg1randomtoken12345
(12)192.168.1.123
../deploy/install.sh 192.168.1.123 3306 tarsAdmin Tars@2019 192.168.1.124 3306 root 123456 true 192.168.1.123:3000 abcdefg1randomtoken12345 192.168.1.123
我的第一次安装的时候执行的语句:
cd /home/muten/module/TARS/TarsFramework/DCache/build
../deploy/install.sh 192.168.118.138 3306 root 123456 192.168.118.138 3306 root 123456 true 192.168.118.138:3000 abcdefg1randomtoken12345 192.168.118.138
注意:
TARS与DCache的数据库可以相同,但如果在正式环境中使用,建议分开使用,为DCache建立独立的数据库.
2.3.2 成功部署之后的截图
3.创建DCache应用
3.1 新增地区
通过【DCache】【服务创建】【新增地区】来新增地区信息.
需要先添加一个地区,用于标识我们创建的DCache应用.
点击顶部的服务创建,点击下方Tab栏中的地区,点击新增地区,填写地区和标签,例如深圳,标签sz,如下
3.2 创建DCache应用
点击Tab栏中的 创建应用,填写应用名,并选择一个IDC地区,点击"创建应用".
比如我们创建一个TestDemo应用,地区选择"深圳",如下
3.3 创建router及proxy服务
在【Router配置信息】中,选择【服务IP】,并填写【MySQL实例信息】;【Proxy配置信息】中,
选择【代理服务的服务IP】,点击 【创建 router、proxy 服务】完成应用创建.
3.4 安装发布
3.5 检查发布内容
4.目录说明
GITHUB上对目录的说明链接:
5.应用场景
5.1 常规的简单应用场景
DCache的KV缓存模块为常规key-value缓存应用,一个键 key 对应一个值 value。value一般为字符串
类型.适用于结构简单的数据,常用于常规计数,如微博数, 粉丝数等,如下图.
5.2 复杂的应用场景
对于一些复杂的结构化数据,比如需要为一个 key 存储多个值,通常有两种实现方式:
(1)通过序列化存储实现,将多个字段存储在value中,需要处理多个字段并发读写的问题.
(2)通过将id和字段作为key的方式存储多个键值对实现,比如Jane_age存储Jane的年龄,
Jane_email 存储 Jane 的邮箱,这样key中会有大量重复用户ID. 如下图:
因此一般会使用其它缓存类型来存储结构化数据,比如DCache中的k-k-row.
6.创建KV缓存模块
与TARS中应用与服务之间的关系相似,一个DCache应用中能够创建多个缓存模块服务.每个缓存模块支持一种
缓存数据结构,通过在一个应用中创建多个不同数据结构的缓存模块,能够实现多种数据类型的存储,满足多种
需求.本节说明的是创建KV模块,其他数据类型的模块在后续章节中可以说到.
6.1 创建模块
6.2 模块配置
6.2.1 模块配置
6.2.2 cache类型和应用场景的配置细节展示
6.3 服务配置
6.3.1 填写服务配置信息
选好服务 IP 节点,并选择一个MySQL实例,在前一篇文章中我们已经添加过一个MySQL实例.
如果需要使用新的MySQL服务,选中下方的MySQL实例信息 输入实例信息即可.
如下,点击下一步
6.3.2 弹窗保持默认,点击确定
6.4 安装发布
到这里,我们就可以在其它服务中使用该缓存模块来缓存 Key-Value 数据了.
7.获取DCache接口文件
7.1 DCache接口文件的简单介绍
DCache是基于TARS开发的,因此使用上和TARS服务一样,也是通过.tars接口文件来调用对应缓存服务的接口.
不同的是,DCache 的接口文件是固定的,我们只需复制DCache/src/TarsComm下的CacheShare.tars,
ProxyShare.tars和DCache/src/Proxy下的Proxy.tars到自己项目目录下即可.
(代码路径:https://github.com/ETZhangSX/DCacheDemo-感谢TARS基金会和Eaton)
例如本文Demo获取DCache接口文件后的项目文件结构如下图:
7.2 此处我用到的命令
find / -name ProxyShare.tars
find / -name CacheShare.tars
find / -name Proxy.tars
ls -lrt /home/muten/module/TARS/TarsFramework/DCache/src/TarsComm/ProxyShare.tars
ls -lrt /home/muten/module/TARS/TarsFramework/DCache/src/TarsComm/CacheShare.tars
ls -lrt /home/muten/module/TARS/TarsFramework/DCache/src/Proxy/Proxy.tars
cd /home/muten/module/TARS/TarsFramework/DCache/test/
git clone https://github.com/ETZhangSX/DCacheDemo.git
8.创建缓存服务代理
8.1 创建一个应用到底做了什么?
当我们创建了一个应用,它会自动创建一个路由服务和代理服务.比如我们之前创建的 TestDemo,
就会自动创建一个路由服务TestDemoRouterServer和一个代理服务TestDemoProxyServer.
TestDemo下每个缓存模块都是通过代理服务TestDemoProxyServer来访问的.
因此,在TARS 服务或客户端中,我们只需要创建一个该代理服务的代理对象即可调用TestDemo下的缓存模块.
例如,我们在main.cpp中通过如下代码创建TestDemoProxyServer的代理对象prx.
8.2 代码示例
// main.cpp
#include <iostream>
#include <map>
#include "servant/Communicator.h"
#include "servant/ServantProxy.h"
#include "Proxy.h"
using namespace std;
using namespace tars;
// TestDemo 代理服务对象名
static string DCacheTestDemoObj = "DCache.TestDemoProxyServer.ProxyObj";
// 缓存模块名
static string ModuleTestDemoKV = "TestDemoKV";
int main(int argc, char *argv[])
{
CommunicatorPtr comm = new Communicator();
try
{
TC_Config conf;
// 解析配置文件
conf.parseFile("config.conf");
// 加载配置
comm->setProperty(conf);
// 生成代理
auto prx = comm->stringToProxy<DCache::ProxyPrx>(DCacheTestDemoObj);
// TODO: 调用 DCache 缓存服务
}
catch (exception &e)
{
cerr << "error: " << e.what() << endl;
}
catch (...)
{
cerr << "Unknown Error" << endl;
}
}
9.调用 KV 缓存模块服务
9.1 引入说明
通过TestDemo代理服务的代理对象,我们就能够调用TestDemo中缓存模块的接口了。
本部分将通过简单示例,本节仅仅介绍key-value类型缓存模块部分接口的使用.
接口调用流程与TARS服务接口调用流程一致.
9.2节给出所有缓存模块部分接口文档链接.
9.2节给出TARS 服务的调用方式和流程的查阅链接.
9.2 友情查阅链接
所有缓存模块部分接口文档链接:Proxy接口描述文档
TARS-RPC提供的多种调用方式:TARS-RPC提供的多种调用方式
9.3 KV的SET与GET接口
9.3.1 SET-设置键值
接口setKV能够设置键值对.
定义如下:
int setKV(const SetKVReq &req)
其中结构SetKVReq及其嵌套结构SSetKeyValue的定义如下:
struct SetKVReq
{
1 require string moduleName; // 模块名
2 require SSetKeyValue data;
};
struct SSetKeyValue
{
1 require string keyItem; // 键
2 require string value; // 值
3 require byte version = 0; // 数据版本,缺省为0
4 require bool dirty = true; // 是否设置为脏数据,缺省为true
5 require int expireTimeSecond = 0; // 过期时间,缺省为0,表示永不过期
};
moduleName 指缓存模块名,通过它来找到具体调用的模块,键值对信息则存储在data中.
使用时先构造键值对数据,然后构造请求结构体,最后发起调用,如下:
void testSetKV(const string &key, const string &value, DCache::ProxyPrx prx)
{
// 构造键值对
DCache::SSetKeyValue setReq;
setReq.keyItem = key;
setReq.value = value;
// 构造请求
DCache::SetKVReq setRsp;
setRsp.moduleName = ModuleTestDemoKV;
setRsp.data = setReq;
prx->setKV(setRsp);
}
9.3.2 GET-读取键值
getKV能够读取键值.
定义如下:
int getKV(const GetKVReq &req, GetKVRsp &rsp)
其中请求消息结构GetKVReq和返回消息结构GetKVRsp的定义如下:
struct GetKVReq
{
1 require string moduleName; // 模块名
2 require string keyItem; // 键
3 require string idcSpecified = ""; // idc区域
};
struct GetKVRsp
{
1 require string value; // 值
2 require byte ver; // 数据版本号
3 require int expireTime = 0; // 过期时间
};
使用示例:
void testGetKV(const string &key, DCache::ProxyPrx prx)
{
// 构建请求
DCache::GetKVReq getReq;
getReq.moduleName = ModuleTestDemoKV;
getReq.keyItem = key;
// 返回数据结构体
DCache::GetKVRsp getRsp;
prx->getKV(getReq, getRsp);
cout << getRsp.value << endl;
}
9.4 运行实例可以查阅GITHUB中下载的代码
回到本文7.2节中的代码路径.
通过上述DCache缓存模块的具体使用流程,我们成功调用了DCache的KV缓存服务.
9.5 其他KV缓存模块服务接口
除了setKV,getKV,DCache中还提供了丰富的KV操作接口,包括插入(insertKV), 删除(delKV), 更新
(updateKV) 等,如下:
// 根据 key 检测 value 是否存于 hash
int checkKey(CheckKeyReq req, out CheckKeyRsp rsp);
// 根据 key 查询 value
int getKV(GetKVReq req, out GetKVRsp rsp);
// 批量查询
int getKVBatch(GetKVBatchReq req, out GetKVBatchRsp rsp);
// 获取 cache 中所有的 key,不包含落地 DB 的 key
int getAllKeys(GetAllKeysReq req, out GetAllKeysRsp rsp);
// 单条写入
int setKV(SetKVReq req);
// 批量写入
int setKVBatch(SetKVBatchReq req, out SetKVBatchRsp rsp);
// key 不存在则插入一条记录,key 已存在则失败
int insertKV(SetKVReq req);
// 更新记录
int updateKV(UpdateKVReq req, out UpdateKVRsp rsp);
// 删除 key 对应的值,只删除 Cache 的数据,不删 DB 数据
int eraseKV(RemoveKVReq req);
// 批量 erase
int eraseKVBatch(RemoveKVBatchReq req, out RemoveKVBatchRsp rsp);
// 删除 key 对应的值,包括 DB 里的数据
int delKV(RemoveKVReq req);
// 批量删除
int delKVBatch(RemoveKVBatchReq req, out RemoveKVBatchRsp rsp);
接口的使用方式与前面介绍的 setKV 和 getKV 是类似的,关于接口的具体入参和出参结构可以参考9.2节
给出的所有缓存模块部分接口文档链接.