RedisModule剖析 - RedisProtobuf

RedisProtobuf 是一款支持 Protobuf (目前仅支持Version 3) 的 Redis 模块,从而支持了较高级的嵌套数据结构,其设计灵感来自于 RedisJSON

一、简介

二、架构设计

2.1、依赖库

2.2、相关命令

  • pb.type : 获取指定 key 的消息类型;
  • pb.set : 设置指定 key 的消息类型的内容信息,支持新增与变更;
  • pb.get : 获取指定 key 的消息内容,支持 binary 和 json 的返回格式;
  • pb.clear : 清除指定 key 的消息内容,支持指定路径;
  • pb.len : 获取指定 key 的消息长度,支持指定路径;
  • pb.append : 给指定 key 的特定路径中追加数据,目标路径的类型可以为 string/array ;
  • pb.del : 删除指定 key ,或者删除指定 key 中 array/map 中的 value信息;
  • pb.schema : 获取指定消息类型的纲要;
  • pb.merge : 将指定的 value 合并到指定 key 中,支持指定路径(依据于 protobuf 的 mergefrom );
  • pb.import : 异步导入一个 protobuf 文件,需要使用 pb.lastimport 来检查是否导入成功;
  • pb.lastimport : 检查之前一次或多次调用 pb.import 导入文件的结果,无法重试,第二次执行将会返回空;

2.3、数据结构

  • Value 类型 : google::protobuf::Message

2.4、持久化

2.4.1、RDB的持久化

RDB 的存储过程比较简单,直接把 Rust 的数据结构转换为 string 持久化到 RDB 文件中。

void RedisProtobuf::_rdb_save(RedisModuleIO *rdb, void *value) {
try {
assert(rdb != nullptr);

std::string type;
std::string buf;
std::tie(type, buf) = serialize_message(value);

RedisModule_SaveStringBuffer(rdb, type.data(), type.size());

RedisModule_SaveStringBuffer(rdb, buf.data(), buf.size());
} catch (const Error &e) {
RedisModule_LogIOError(rdb, "warning", e.what());
}
}

2.4.2、AOF的持久化

AOF 的存储过程是将原始的数据的通过 pb.set 命令进行存储,从而实现了 AOF 的持久化。

void RedisProtobuf::_aof_rewrite(RedisModuleIO *aof, RedisModuleString *key, void *value) {
try {
assert(aof != nullptr);

if (key == nullptr) {
throw Error("null key to rewrite aof");
}

std::string type;
std::string buf;
std::tie(type, buf) = serialize_message(value);

RedisModule_EmitAOF(aof,
"PB.SET",
"sbb",
key,
type.data(),
type.size(),
buf.data(),
buf.size());
} catch (const Error &e) {
RedisModule_LogIOError(aof, "warning", e.what());
}
}

三、思考

  • 相比于 RedisJson 的性能,该模块的性能如何?
作者: bugwz
链接: https://bugwz.com/2022/10/07/redismodule-redis-protobuf/
声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 咕咕