Redis 是目前 NoSQL 领域的当红炸子鸡,它象一把瑞士军刀,小巧、锋利、实用,特别适合解决一些使用传统关系数据库难以解决的问题。Redis 做为内存数据库,全部的数据所有都存在内存中,特别适合处理少许的热数据。当有巨量数据超过内存大小须要落盘保存时,就须要使用 Redis + KV存储的方案了。redis
本文涉及的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对一一对应;spa
对于其它的容器类型,咱们须要code
对于sorted set,其每一个成员有score和rank两个属性,因此须要:排序
对于全部的Key, 包含一样的前缀,编码格式定义以下:内存
[<namespace>] <key> <type> <element...>
namespace用于支持相似redis中的库概念, 能够为任意字符串, 不限制必须为数字;
key则是一个变长二进制字符串
type用于定义一个简单key-value的类型,此类型隐含代表key的数据结构类型;一个字节
meta信息的key中type固定为KEY_META;具体类型将在value中定义(参考下一节)
除以上三部分外,不一样类型的key可能有附加字段;如Hash的key可能须要附加field字段element
内部Value则比较复杂,编码均以type开始, type取值即上节定义的KeyType字符串
<type> <element...>
后续格式根据各类类型定义不一样.
各种型数据的编码方式以下: ns表明namespace
KeyObject ValueObject String [<ns>] <key> KEY_META KEY_STRING <MetaObject> Hash [<ns>] <key> KEY_META KEY_HASH <MetaObject> [<ns>] <key> KEY_HASH_FIELD <field> KEY_HASH_FIELD <field-value> Set [<ns>] <key> KEY_META KEY_SET <MetaObject> [<ns>] <key> KEY_SET_MEMBER <member> KEY_SET_MEMBER List [<ns>] <key> KEY_META KEY_LIST <MetaObject> [<ns>] <key> KEY_LIST_ELEMENT <index> KEY_LIST_ELEMENT <element-value> Sorted Set [<ns>] <key> KEY_META KEY_ZSET <MetaObject> [<ns>] <key> KEY_ZSET_SCORE <member> KEY_ZSET_SCORE <score> [<ns>] <key> KEY_ZSET_SORT <score> <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/