DCache 分布式存储系统|Key-Value 缓存模块的建立与使用

做者 | Eatonhtml

导语 | 随着微服务与云的发展,分布式架构的需求变得愈来愈广泛,传统的 SQL 结构化存储方案已经跟不上脚步,因而 NoSQL 出现了。DCache 做为基于 TARS 的分布式 NoSQL 缓存系统,完美支持 TARS 服务。在前一篇文章中,咱们介绍了 DCache 的特性、如何在 TARS 上部署 DCache 并建立一个应用 TestDemo。本文将继续介绍如何建立和使用 DCache 中的 KV 缓存模块。ios

系列文章git

目录

  • 简介
  • 应用场景
  • 建立 KV 缓存模块
  • 获取 DCache 接口文件
  • 建立缓存服务代理
  • 调用缓存模块服务
  • 总结

简介

DCache 是一个基于 TARS 框架开发的分布式 NoSQL 存储系统,支持多种数据结构,包括了 key-value(键值对),k-k-row(多键值),list(列表),set(集合),zset(有序集合)等,知足多种业务需求。github

其中 key-value 是最简单也是最经常使用的类型,咱们只需完成如下步骤便可在服务中使用 key-value 缓存服务api

  1. 建立 KV 缓存模块
  2. 获取 DCache 接口文件
  3. 建立缓存服务代理
  4. 调用缓存模块服务

DCache 中为 KV 提供了插入、替换、删除和批量操做键值等丰富的操做接口,使用上很是方便。本文将基于 TestDemo 介绍如何建立 Key-Value 缓存模块,以及怎么在 TARS 服务中调用该服务来缓存数据。缓存

本文使用的示例能够在 GitHub 仓库 DCacheDemo 中查看。数据结构

应用场景

DCache 的 KV 缓存模块为常规 key-value 缓存应用,一个键 key 对应一个值 value。value 通常为字符串类型。适用于结构简单的数据,经常使用于常规计数,如微博数, 粉丝数等,以下图。架构

对于一些复杂的结构化数据,好比须要为一个 key 存储多个值,一般有两种实现方式。一种是经过序列化存储实现,将多个字段存储在 value 中,须要处理多个字段并发读写的问题。另外一种是经过将 id 和字段做为 key 的方式存储多个键值对实现,好比 Jane_age 存储 Jane 的年龄, Jane_email 存储 Jane 的邮箱,这样 key 中会有大量重复用户 ID。以下图并发

所以通常会使用其它缓存类型来存储结构化数据,好比 DCache 中的 k-k-row。该类型咱们将在下一篇文章详细介绍。框架

建立 KV 缓存模块

与 TARS 中应用与服务之间的关系类似,一个 DCache 应用中可以建立多个缓存模块服务。每一个缓存模块支持一种缓存数据结构,经过在一个应用中建立多个不一样数据结构的缓存模块,可以实现多种数据类型的存储,知足多种需求。本文将介绍如何建立 KV 模块,其余数据类型相关内容将在以后的文章中分享。

首先,在 DCache 页面进入 服务建立 > 建立模块,选择咱们以前建立的应用 TestDemo,模块名要求以应用名开头,这里咱们由于建立的是 KV 模块,咱们命名 TestDemoKV,以下

进入第二步的模块配置,cache 类型 选择 key-value(KVCache),填充备注

第三步服务配置,选好服务 IP 节点,并选择一个 MySQL 实例,在前一篇文章中咱们已经添加过一个 MySQL 实例。若是须要使用新的 MySQL 服务,选中下方的 MySQL 实例信息 输入实例信息便可。以下,点击 下一步

弹出字段配置窗口,保持默认便可,点击 肯定

确认好已配置信息后,点击 安装发布 便可完成发布。

到这里,咱们就能够在其它服务中使用该缓存模块来缓存 Key-Value 数据了。

整体来讲,建立缓存模块的过程分为三步:模块建立、模块配置和服务配置。模块配置时,你们按需选择缓存类型便可。

获取 DCache 接口文件

咱们提到过,DCache 是基于 TARS 开发的,所以使用上和 TARS 服务同样,也是经过 .tars 接口文件来调用对应缓存服务的接口。不一样的是,DCache 的接口文件是固定的,咱们只需复制 DCache/src/TarsComm 下的 CacheShare.tars, ProxyShare.tarsDCache/src/Proxy 下的 Proxy.tars 到本身项目目录下便可。

例如本文 Demo 获取 DCache 接口文件后的项目文件结构以下

DCacheDemo
├── CacheShare.tars
├── ProxyShare.tars
├── Proxy.tars
├── config.conf
├── main.cpp
└── makefile

建立缓存服务代理

当咱们建立了一个应用,它会自动建立一个路由服务和代理服务。好比咱们以前建立的 TestDemo,就会自动建立一个路由服务 TestDemoRouterServer 和一个代理服务 TestDemoProxyServerTestDemo 下每一个缓存模块都是经过代理服务 TestDemoProxyServer 来访问的。

所以,在 TARS 服务或客户端中,咱们只须要建立一个该代理服务的代理对象便可调用 TestDemo 下的缓存模块。

例如,咱们在 main.cpp 中经过以下代码建立 TestDemoProxyServer 的代理对象 prx

// 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;
    }
}

调用 KV 缓存模块服务

经过 TestDemo 代理服务的代理对象,咱们就可以调用 TestDemo 中缓存模块的接口了。本部分将经过简单示例,介绍 key-value 类型缓存模块部分接口的使用。关于其它接口的信息,参见 Proxy 接口指南

接口调用流程与 TARS 服务接口调用流程一致。若是你还不清楚 TARS 服务的调用方式和流程,能够阅读文章 TARS RPC 通讯框架|提供多种远程调用方式

那么接下来,咱们来看看怎么使用 KV 缓存模块。

Key-Value 模块

即键值对模块,这里咱们介绍写接口 setKV 和读接口 getKV,其它操做接口的使用相似。

设置键值对

接口 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);
}

获取键值

接口 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;
}

运行示例

咱们来实际运行一下上面的使用示例。完整的使用示例能够在 GitHub 仓库 DCacheDemo 中获取。

咱们经过 testKV 测试上节提到的各模块读写接口,以下

void testKV(DCache::ProxyPrx prx)
{
    testSetKV("hello", "world", prx);
    testGetKV("hello", prx);
}

接着,在 main 函数中执行

int main(int argc, char *argv[])
{
    ...

        auto prx = comm->stringToProxy<DCache::ProxyPrx>(DCacheTestDemoObj);

        // 调用 DCache 缓存服务
        testKV(prx);
    ...
}

编译构建并运行示例,结果以下

经过上述 DCache 缓存模块的具体使用流程,咱们成功调用了 DCache 的 KV 缓存服务。

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);

接口的使用方式与前面介绍的 setKVgetKV 是相似的,关于接口的具体入参和出参结构能够参考 Proxy 接口指南

总结

本文基于上一篇文章,经过一系列使用示例,介绍了 DCache 中 KV 缓存模块的建立和使用方式。由于 DCache 基于 TARS 开发,缓存服务的使用上基本和 TARS 服务调用无异,开发者可以快速上手。同时 DCache 支持直接链接 DB 进行数据持久化,无需开发者自行实现 DB 链接持久化的相关逻辑,使开发者可以更加专一于业务。

TARS 能够在考虑到易用性和高性能的同时快速构建系统并自动生成代码,帮助开发人员和企业以微服务的方式快速构建本身稳定可靠的分布式应用,从而令开发人员只关注业务逻辑,提升运营效率。多语言、敏捷研发、高可用和高效运营的特性使 TARS 成为企业级产品。

TARS微服务助您数字化转型,欢迎访问:

TARS官网:https://TarsCloud.org

TARS源码:https://github.com/TarsCloud

Linux基金会官方微服务免费课程:https://www.edx.org/course/building-microservice-platforms-with-tars

获取《TARS官方培训电子书》:https://wj.qq.com/s2/7849909/01b0/

或扫码获取:

QR

相关文章
相关标签/搜索