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/