Redis 是目前 NoSQL 领域的当红炸子鸡,它象一把瑞士军刀,小巧、锋利、实用,特别适合解决一些使用传统关系数据库难以解决的问题。Redis 作为内存数据库, 所有的数据全部都存在内存中,特别适合处理少量的热数据。当有巨量数据超过内存大小需要落盘保存时,就需要使用 Redis + KV 存储的方案了。
本文涉及的 Ardb 就是一个完全兼容 Redis 协议的 NoSQL 的存储服务。其存储基于现有成熟的 KV 存储引擎实现,理论上任何类似 B-Tree/LSM Tree 实现的 KV 存储实现均可作为 Ardb 的底层存储实现,目前 Ardb 支持 LevelDB/RocksDB/LMDB.
本文以 Ardb 为例,介绍 Redis 与 KV 存储之间融合时编解码层的实现。
Redis 与 KV 存储的融合方案中, 编解码层是一个很重要的环节。通过编解码层,我们可以屏蔽了各种 kv 存储实现的不同,可以在任意一个简单的 kv 存储引擎上,封装实现 Redis 中 string,hash,list,set,sorted set 等复杂类型的数据结构。
对于 String 类型,很显然可以与 KV 存储中的一个 KV 对一一对应;
对于其它的容器类型,我们需要
对于 sorted set,其每个成员有 score 和 rank 两个属性,所以需要:
对于所有的 Key, 包含同样的前缀,编码格式定义如下:
- [] <type> <element...>
namespace 用于支持类似 redis 中的库概念, 可以为任意字符串, 不限制必须为数字;
key 则是一个变长二进制字符串
type 用于定义一个简单 key-value 的类型,此类型隐含表明 key 的数据结构类型; 一个字节
meta 信息的 key 中 type 固定为 KEY_META;具体类型将在 value 中定义(参考下一节)
除以上三部分外,不同类型的 key 可能有附加字段;如 Hash 的 key 可能需要附加 field 字段
内部 Value 则比较复杂,编码均以 type 开始, type 取值即上节定义的 KeyType
- <type> <element...>
后续格式根据各种类型定义不同.
各类型数据的编码方式如下: ns 代表 namespace
- KeyObject ValueObject
- String [] KEY_META KEY_STRING
- Hash [] KEY_META KEY_HASH
- [] KEY_HASH_FIELD KEY_HASH_FIELD
- Set [] KEY_META KEY_SET
- [] KEY_SET_MEMBER <member> KEY_SET_MEMBER
- List [] KEY_META KEY_LIST
- [] KEY_LIST_ELEMENT KEY_LIST_ELEMENT
- Sorted Set [] KEY_META KEY_ZSET
- [] KEY_ZSET_SCORE <member> KEY_ZSET_SCORE
- [] KEY_ZSET_SORT <member> KEY_ZSET_SORT
这里以最复杂的 Sorted Set 来做实例。假设有个 Sorted Set 为 A: {member=frist, score=1}, {member=second, score=2}。其在 Ardb 中的存储方式如下:
Key A 的存储编码为:
- // 伪代码中的|代表域的分割,不代表实际存储为"|"。实际序列化的时候每个域是按照特定位置序列化的.
- 键为:ns|1|A(1代表是KEY_META元信息类型)
- 值为:元信息编码(redis数据类型/zset,过期时间,成员个数,最大最小score等)
成员 first 的 score 信息存储编码为:
- 键为:ns|11|A|first (11代表类型为KEY_ZSET_SCORE)
- 值为:11|1 (11代表类型KEY_ZSET_SCORE,1为该成员first的score)
成员 first 的 rank 信息存储编码为:
- 键为:ns|10|A|1|first (10代表类型为KEY_ZSET_SORT, 1为score)
- 值为:10 (代表类型KEY_ZSET_SORT,无意义。rocksdb中自动按key大小排序,所以很容易算出rank,不需要存储和更新)
成员 second 的 score 信息存储编码略。
当用户使用 zcard A 命令时,直接访问 namespace_1_A 即可得到元信息中该有序集合的数目;
当用户使用 zscore A first 时,直接访问 namespace_A_first 即可得到 first 成员的 score;
当用户使用 zrank A first 时,先用 zscore 得到 score, 再查找 namespace_10_A_1_first 的序号;
具体的存储方式代码如下:
阅读全文请点击:http://click.aliyun.com/m/8714/
来源: