string
存储方式 key-value,可支持数字,性能高,
用处 微博数,粉丝数
基本命令
set key value
get key
getrange key start end #返回key中字符串值的从start到end的字符
mget key1 key2 key3… #获取一个或多个key的值
setex key seconds value #将值关联到key并且设置key的过期时间(以秒为单位)
setnx key value #当key不存在时设置key的值
decr key #将key存储的数字减一
append key value #如果key是已存在的字符串,则在value末位后追加字符串
底层实现 String底层是动态字符串SDS(simple dynamic string) SDS结构有五种header定义,为了满足不同长度字符串可以使用不同大小的header,节省内存。
- len:字符串真正长度。
- alloc:字符串的最大容量
- flags:标识为,第三位表示类型,其余5位未使用
- buf:字符数组
- encoding可能是int,raw,embstr
- int:可以用long类型整数表示,redis会将键值转long类型存储
- raw:长度大于44字节的字符串,使用SDS保存
- embstr:长度小于等于44字节的字符串,效率高,且数据都保存在一块内存区域
list
双链表实现,可以支持队列机制,或者存储按时间顺序排序的某些信息,支持反向查找和遍历微博的关注列表、粉丝列表、消息列表等
常用命令
LPUSHX key value #将一个值插入到已存在的列表头部
LPUSH key value1 [value2] #将一个或多个值插入到列表头部
LPOP key #移出并获取列表的第一个元素
LLEN key #获取列表长度
list底层链表 早期使用ziplist或者linkedlist,redis3.2版本后list使用quickList
- ziplist:
压缩列表,适用于长度较小的值,是由连续空间组成,保存每个值的长度信息,一次可查找每个值。存储效率高,内存小,但是由于是连续内存,修改需要重新分配内存
- linkedlist:
双向链表,修改效率高,,但是由于需要保护前后指针,占用内存较多。
- quicklist:
3.2版本后,quicklist是一种混合结构,ziplist和linkedlist的混合体,将linkedlist安段切分,每一段使用ziplist紧凑存储,多个ziplist之间使用双向指针串联起来,既满足快速插入删除性能,页不会出现太大的空间冗余。
hash
存储对象数据,可以直接读取或修改特定属性的值,可应用于redis分布式锁
存放用户信息,商品信息
注意:不要全部取整个hash,性能开销比较大,不推荐做复杂查询,会增加维护成本
常用命令
HDEL key field1 [field2] #删除一个或多个哈希表字段
HEXISTS key field #查看哈希表 key 中,指定的字段是否存在。
HGET key field #获取存储在哈希表中指定字段的值。
HGETALL key #获取在哈希表中指定 key 的所有字段和值
HINCRBY key field increment #为哈希表 key 中的指定字段的整数值加上增量 increment 。
HMGET key field1 [field2] #获取所有给定字段的值
HSET key field value #将哈希表 key 中的字段 field 的值设为 value 。
HSETNX key field value #只有在字段 field 不存在时,设置哈希表字段的值。
底层实现 hash底层是dict encoding使用ziplist和hashtable
- ziplist: 当键和值的长度和数量比较少时,默认使用ziplist,hash过程是直接通过遍历得到,数据量小,效率高。
- hashtable 采用hash表提高效率
set
不重复数据的集合,如订阅、关注用户id等信息 存放微博的关注人,粉丝人,快速找到共同好友
常用命令
SADD key member1 [member2] #向集合添加一个或多个成员
SINTER key1 [key2] #返回给定所有集合的交集
SUNION key1 [key2] #返回所有给定集合的并集
底层实现 encoding使用intset和hashtable
-
intset: 集合中的数都是整数时,数据量不超过512个,使用intset,有序不重复连续空间。节省空间,但是是连续空间,所以修改效率不高
-
hashtable value使用null填充。
zset
有序集合,带权重的集合,可以根据权重进行排序或查找和set相⽐,sorted set增加了⼀个权重参数score,使得集合中的元素能够按score进⾏有序排列。
存放直播间的在线用户列表,以及用户送的礼物,弹幕消息等。
常用命令
ZADD key score1 member1 [score2 member2] #向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZREM key member [member ...] #移除有序集合中的一个或多个成员
ZCARD key #获取有序集合的成员数
ZCOUNT key min max #计算在有序集合中指定区间分数的成员数
ZINCRBY key increment member #有序集合中对指定成员的分数加上增量 increment
底层实现 encoding使用ziplist或者skiplist
-
ziplist 连续存放值以及score(排序的标准,double)当元素个数以及长度都比较小时使用
-
skiplist
- 跳表(具有层次结构的链表),可支持范围查询
- 查找和插入的时间复杂度都是log(n)
- 使用一个dict保存每个值对应的score
- 查找时,从开始查找,知道找到大于或者null的然后指向节点的下一层。
- 新增时,为了保证每层的数量能够满足要求,需要随机产生该数的层数,并保证概率。
- 删除时,需要考虑前驱的next节点改变,同时考虑最大level是否变化。
为什么使用跳表skiplist
- 占用的内存开销可控(通知控制概率P)
- 支持范围查询,比如zrange
- 跳表优点时有序,但是查询分值复杂度时O(logn);字典查询分值复杂度为O(1)但是无序
- 虽然采用两个结构但是集合元素成员和分值时共享的,两种结构通过指针指向同一地址,不会浪费内存
string
存储方式 key-value,可支持数字,性能高,
用处 微博数,粉丝数
基本命令
set key value
get key
getrange key start end #返回key中字符串值的从start到end的字符
mget key1 key2 key3… #获取一个或多个key的值
setex key seconds value #将值关联到key并且设置key的过期时间(以秒为单位)
setnx key value #当key不存在时设置key的值
decr key #将key存储的数字减一
append key value #如果key是已存在的字符串,则在value末位后追加字符串
底层实现 String底层是动态字符串SDS(simple dynamic string) SDS结构有五种header定义,为了满足不同长度字符串可以使用不同大小的header,节省内存。
- len:字符串真正长度。
- alloc:字符串的最大容量
- flags:标识为,第三位表示类型,其余5位未使用
- buf:字符数组
- encoding可能是int,raw,embstr
- int:可以用long类型整数表示,redis会将键值转long类型存储
- raw:长度大于44字节的字符串,使用SDS保存
- embstr:长度小于等于44字节的字符串,效率高,且数据都保存在一块内存区域
list
双链表实现,可以支持队列机制,或者存储按时间顺序排序的某些信息,支持反向查找和遍历微博的关注列表、粉丝列表、消息列表等
常用命令
LPUSHX key value #将一个值插入到已存在的列表头部
LPUSH key value1 [value2] #将一个或多个值插入到列表头部
LPOP key #移出并获取列表的第一个元素
LLEN key #获取列表长度
list底层链表 早期使用ziplist或者linkedlist,redis3.2版本后list使用quickList
- ziplist:
压缩列表,适用于长度较小的值,是由连续空间组成,保存每个值的长度信息,一次可查找每个值。存储效率高,内存小,但是由于是连续内存,修改需要重新分配内存
- linkedlist:
双向链表,修改效率高,,但是由于需要保护前后指针,占用内存较多。
- quicklist:
3.2版本后,quicklist是一种混合结构,ziplist和linkedlist的混合体,将linkedlist安段切分,每一段使用ziplist紧凑存储,多个ziplist之间使用双向指针串联起来,既满足快速插入删除性能,页不会出现太大的空间冗余。
hash
存储对象数据,可以直接读取或修改特定属性的值,可应用于redis分布式锁
存放用户信息,商品信息
注意:不要全部取整个hash,性能开销比较大,不推荐做复杂查询,会增加维护成本
常用命令
HDEL key field1 [field2] #删除一个或多个哈希表字段
HEXISTS key field #查看哈希表 key 中,指定的字段是否存在。
HGET key field #获取存储在哈希表中指定字段的值。
HGETALL key #获取在哈希表中指定 key 的所有字段和值
HINCRBY key field increment #为哈希表 key 中的指定字段的整数值加上增量 increment 。
HMGET key field1 [field2] #获取所有给定字段的值
HSET key field value #将哈希表 key 中的字段 field 的值设为 value 。
HSETNX key field value #只有在字段 field 不存在时,设置哈希表字段的值。
底层实现 hash底层是dict encoding使用ziplist和hashtable
- ziplist: 当键和值的长度和数量比较少时,默认使用ziplist,hash过程是直接通过遍历得到,数据量小,效率高。
- hashtable 采用hash表提高效率
set
不重复数据的集合,如订阅、关注用户id等信息 存放微博的关注人,粉丝人,快速找到共同好友
常用命令
SADD key member1 [member2] #向集合添加一个或多个成员
SINTER key1 [key2] #返回给定所有集合的交集
SUNION key1 [key2] #返回所有给定集合的并集
底层实现 encoding使用intset和hashtable
-
intset: 集合中的数都是整数时,数据量不超过512个,使用intset,有序不重复连续空间。节省空间,但是是连续空间,所以修改效率不高
-
hashtable value使用null填充。
zset
有序集合,带权重的集合,可以根据权重进行排序或查找和set相⽐,sorted set增加了⼀个权重参数score,使得集合中的元素能够按score进⾏有序排列。
存放直播间的在线用户列表,以及用户送的礼物,弹幕消息等。
常用命令
ZADD key score1 member1 [score2 member2] #向有序集合添加一个或多个成员,或者更新已存在成员的分数
ZREM key member [member ...] #移除有序集合中的一个或多个成员
ZCARD key #获取有序集合的成员数
ZCOUNT key min max #计算在有序集合中指定区间分数的成员数
ZINCRBY key increment member #有序集合中对指定成员的分数加上增量 increment
底层实现 encoding使用ziplist或者skiplist
-
ziplist 连续存放值以及score(排序的标准,double)当元素个数以及长度都比较小时使用
-
skiplist
- 跳表(具有层次结构的链表),可支持范围查询
- 查找和插入的时间复杂度都是log(n)
- 使用一个dict保存每个值对应的score
- 查找时,从开始查找,知道找到大于或者null的然后指向节点的下一层。
- 新增时,为了保证每层的数量能够满足要求,需要随机产生该数的层数,并保证概率。
- 删除时,需要考虑前驱的next节点改变,同时考虑最大level是否变化。
为什么使用跳表skiplist
- 占用的内存开销可控(通知控制概率P)
- 支持范围查询,比如zrange
- 跳表优点时有序,但是查询分值复杂度时O(logn);字典查询分值复杂度为O(1)但是无序
- 虽然采用两个结构但是集合元素成员和分值时共享的,两种结构通过指针指向同一地址,不会浪费内存
- 本文作者:
- 原文链接:
- 版权声明: 本博客所有文章除特别声明外,均采用 进行许可。转载请署名作者且注明文章出处。