redis学习之六对象
这段时间打算梳理下redis相关的知识点,先从redis底层的数据结构与redisObject对象开始吧。
在展开之前我们需要先对redis的设计原则有一个大概的认识:
- 存储效率(memory efficiency),在追求存储效率这一原则的前提下,redis才会有上面这些数据结构,并且会在某些场景下会交替使用这些数据结构,可以想象的到redis会在数据压缩、避免内存碎片方面下功夫。
- 快速响应(fast response),一般来说,单台redis可达到4W左右的QPS。因为数据是存在内存所以不会出现磁盘IO(这也是redis不必使用多线程的一个原因),而redis的性能瓶颈主要是内存大小与网络带宽。正是有了底层这些特殊的数据结构支撑,才会有极快的贵响应。
- string
- list
- hash
- set
- sorted set
- dict
- sds
- ziplist
- quicklist
- skiplist
- list:在同时满足下面两种情况下会使用ziplist:一是所有字符串长度小于64字节;二是元素数量小于512,不满足任一条件就会使用linkedlist(双端链表)。
- hash:在同时满足下面两种情况下会使用ziplist:一是所有键值对的键和值的字符串长度都小于64字节;二是键值对数量小于512个;不满足任意一个都使用hashtable编码。
- set:在同时满足下面两种情况下会使用intset:一是所有元素都是整数值;二是元素个数小于等于512个;不满足任意一条都将使用hashtable编码。
- zset:在同时满足下面两种情况下会使用ziplist:一是所有元素长度小于64字节;二是元素个数小于128个;不满足任意一条件将使用skiplist编码。
- 可以在执行命令之前,根据对象的类型来判断一个对象是否可以执行给定命令。
- 可以针对不同的使用场景切换使用合适的数据结构。
- redisObject对象实现了基于引用计数的内存回收机制方便管理内存,同时在引用计数的基础上实现的对象共享机制也利于节约内存。
typedef struct redisObject {
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层实现数据结构的指针
void *ptr;
//...
} robj;
type属性记录了对象的类型,其对应的值如下:
类型常量 | 对象的名称 |
---|---|
REDIS_STRING | 字符串对象 |
REDIS_LIST | 列表对象 |
REDIS_HASH | 哈希对象 |
REDIS_SET | 集合对象 |
REDIS_ZSET | 有序集合对象 |
对象的ptr属性指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定,encoding记录着对象所使用的编码,可以是下面的值:
编码常量 | 编码对应底层的数据结构 |
---|---|
REDIS_ENCODING_INT | long类型的整数 |
REDIS_ENCODING_EMBSTR | embstr编码的简单动态字符串 |
REDIS_ENCODING_RAW | 简单动态字符串 |
REDIS_ENCODING_HT | 字典 |
REDIS_ENCODING_LINKEDLIST | 双端链表 |
REDIS_ENCODING_ZIPLIST | 压缩列表 |
REDIS_ENCODING_INTSET | 整数集合 |
REDIS_ENCODING_SKIPLIST | 跳跃表 |
总结:通过encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大的提升了灵活性与效率,redis可以根据不同的使用场景来选择特定对象不同的的编码,从而提升对应场景下的使用效率。
参考的文章有:
黄健宏的《Redis设计与实现》一书
张铁蕾关于redis的文章
推荐阅读
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习
- 【韩语学习】(韩语随堂笔记整理)
- 焦点学习田源分享第267天《来访》