Redis与KV存储(RocksDB)融合之编码方式
Redis与KV存储(RocksDB)融合之编码方式
简介
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对一一对应;
对于其它的容器类型,我们需要
- 一个KV来存储其整个Key的元信息(比如List的成员个数,过期时间等);
- 每一个成员需要一个KV来保存成员的名称和值;
对于sorted set,其每个成员有score和rank两个属性,所以需要:
- 一个KV保存整个Key的元信息
- 每一个成员需要一个KV保存 score信息
- 每一个成员需要一个KV保存每个成员对应 rank 信息
Key的编码格式
对于所有的Key, 包含同样的前缀,编码格式定义如下:
[<namespace>] <key> <type> <element...>
namespace用于支持类似redis中的库概念, 可以为任意字符串, 不限制必须为数字;
key则是一个变长二进制字符串
type用于定义一个简单key-value的类型,此类型隐含表明key的数据结构类型;一个字节
meta信息的key中type固定为KEY_META;具体类型将在value中定义(参考下一节)
除以上三部分外,不同类型的key可能有附加字段;如Hash的key可能需要附加field字段
Value的编码格式
内部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
ZSet编码实例
这里以最复杂的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/
Redis与KV存储(RocksDB)融合之编码方式的更多相关文章
- 高性能kv存储之Redis、Redis Cluster、Pika:如何应对4000亿的日访问量?
一.背景介绍 随着360公司业务发展,业务使用kv存储的需求越来越大.为了应对kv存储需求爆发式的增长和多使用场景的需求,360web平台部致力于打造一个全方位,适用于多场景需求的kv解决方案.目前, ...
- NoSQL生态系统——类似Bigtable列存储,或者Dynamo的key存储(kv存储如BDB,结构化存储如redis,文档存储如mongoDB)
摘自:http://www.ituring.com.cn/article/4002# NoSQL系统的数据操作接口应该是非SQL类型的.但在NoSQL社区,NoSQL被赋予了更具有包容性的含义,其意为 ...
- 编写你的第一个 Java 版 Raft 分布式 KV 存储
前言 本文旨在讲述如何使用 Java 语言实现基于 Raft 算法的,分布式的,KV 结构的存储项目.该项目的背景是为了深入理解 Raft 算法,从而深刻理解分布式环境下数据强一致性该如何实现:该项目 ...
- Redis数据结构(一)-Redis的数据存储及String类型的实现
1 引言 Redis作为基于内存的非关系型的K-V数据库.因读写响应快速.原子操作.提供了多种数据类型String.List.Hash.Set.Sorted Set.在项目中有着广泛的使用,今天我们来 ...
- 基于淘宝开源Tair分布式KV存储引擎的整合部署
一.前言 Tair支撑了淘宝几乎所有系统的缓存信息(Tair = Taobao Pair,Pair即Key-Value键值对),内置了三个存储引擎:mdb(默认,类似于Memcache).rdb(类似 ...
- redis 3.2 新数据结构:quicklist、String的embstr与raw编码方式分界点
Redis3.2.0引入了新的quicklist的数据结构做了list的底层存储方案.废弃了原来的两个配置参数, list-max-ziplist-entries list-max-ziplist-v ...
- 服务注册发现consul之四: 分布式锁之四:基于Consul的KV存储和分布式信号量实现分布式锁
一.基于key/value实现 我们在构建分布式系统的时候,经常需要控制对共享资源的互斥访问.这个时候我们就涉及到分布式锁(也称为全局锁)的实现,基于目前的各种工具,我们已经有了大量的实现方式,比如: ...
- Redis的五种数据结构的内部编码
type命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串).hash(哈希). list(列表).set(集合).zset(有序集合),但这些只是Redis对外的数据结构. 实 ...
- 谈谈KV存储集群的设计要点
版权声明:本文由廖念波原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/150 来源:腾云阁 https://www.qclo ...
随机推荐
- 06. Web大前端时代之:HTML5+CSS3入门系列~HTML5 画布
Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 我们先看看画布的魅力: 初始画布 canvas默认是宽3 ...
- JavaScript权威设计--JavaScript变量,作用域,声明提前(简要学习笔记四)
1.宿主对象与宿主环境 宿主对象:由ECMAScript实现的宿主环境提供的对象,可以理解为:浏览器提供的对象.所有的BOM和DOM都是宿主对象. 宿主环境:一般宿主环境由外壳程序创建与维护,只要 ...
- ASP.NET OWIN OAuth:refresh token的持久化
在前一篇博文中,我们初步地了解了refresh token的用途——它是用于刷新access token的一种token,并且用简单的示例代码体验了一下获取refresh token并且用它刷新acc ...
- Python标准模块--threading
1 模块简介 threading模块在Python1.5.2中首次引入,是低级thread模块的一个增强版.threading模块让线程使用起来更加容易,允许程序同一时间运行多个操作. 不过请注意,P ...
- ES6之module
该博客原文地址:http://www.cnblogs.com/giggle/p/5572118.html 一.module概述 JavaScript一直没有模块体系,但是伴随着ES6的到来,modul ...
- webpack配置别名alias出现的错误匹配
@(webpack) webpack是一款功能强大的前端构建工具,不仅仅是针对js,它也可通过各种loader来构建相关的less,html,image等各种资源,将webpack配合流程制定工具gu ...
- Docker for Windows使用简介
在上一篇文章中,通过演练指导的方式,介绍了在Docker中运行ASP.NET Core Web API应用程序的过程.本文将介绍Docker for Windows的使用. 先决条件 前两周时间,Do ...
- c#面向对象基础技能——学习笔记(五)委托技术在开发中的应用
委托 delegate 1.是一种全新的面向对象语言的特性: 2.开发事件驱动程序变得非常简单: 3.简化多线程难度. 理解委托:可以理解成一个方法的指针.(接收的变量是方法) 步骤: 1.声明委托, ...
- 新手,Visual Studio 2015 配置Boost库,如何编译和选择,遇到无法打开文件“libboost_thread-vc140-mt-gd-1_63.lib“的解决办法
1,到官网下载最新的boost,www.boost.org 这里我下载的1-63版本. 2,安装,解压后运行bootstrap.bat文件.稍等一小会就OK. 3,编译boost库.注意一定要使用VS ...
- 数据结构:基于list实现二元表达式(python版)
#!/usr/bin/env python # -*- coding:utf-8 -*- def make_sum(a, b): return ['+', a, b] def make_prod(a, ...