Redis数据类型及实现

先列举:java

五大类型:String、List、Hash、Set、Sorted Set、redis

其它: pubsub(应该算独立功能吧?)、HyperLogLog(2.8.9+)、Geo(3.2+)、Stream(redis5+)数据库

* * * redisObject * * *

redis中实现了不少自定义数据结构,但redis并无直接使用这些结构来构建k-v系统,而是使用这些结构建立了一个对象系统;这个对象系统包含了上面咱们列举的字符串对象、列表对象、哈希对象、集合对象等等;服务器

注:本文假定阅读者对于redis底层数据结构及实现有必定了解数据结构

注:底层数据结构包括: 简单动态字符串SDS、链表linkedlist、跳跃表skiplist、压缩列表ziplist、整数集合等等函数

使用对象的优势性能

  • 执行命令前,方便根据对象类型判断一个对象是否可执行给定的命令;
  • 针对不一样的使用场景,为对象设置多种不一样的数据结构实现,以优化性能;
  • redis的对象系统还实现了基于引用计数技术的内存回收机制;
  • 经过引用计数,还实现了对象共享机制;
  • redis的对象带有访问时间记录信息,可用于计算数据库键的空转时长,以辅助实现maxmemory;

redisObject学习

  • type:类型
    • REDIS_STRING: string
    • REDIS_LIST: list
    • REDIS_HASH: hash
    • REDIS_SET: set
    • REDIS_ZSET: zset
  • encoding:编码,即底层数据结构的类型;
    • REDIS_ENCODING_INT:int = long型整数
    • REDIS_ENCODING_EMBSTR:embstr = embstr编码的SDS
    • REDIS_ENCODING_RAW:raw = SDS
    • REDIS_ENCODING_HT:hashtable = 字典(哈希表)
    • REDIS_ENCODING_LINKEDLIST:linkedlist = 链表
    • REDIS_ENCODING_ZIPLIST:ziplist = 压缩列表
    • REDIS_ENCODING_INTSET:intset = 整数集合
    • REDIS_ENCODING_SKIPLIST:skiplist = 跳跃表
  • ptr:指向底层数据结构实现的指针;

说明: redis是一个键值对系统,它的键老是字符串对象,值为上述类型中声明的对象类型(新版本有扩充),使用type命令可查看数据库键的类型,实际就是数据库键对应的值的类型;优化


-------- 快乐的分割线-------下面介绍五大类型 ----------------ui


String 字符串

redisObject的type为REDIS_STRING,用type命令查询,显示string,编码表示底层数据结构:

  • int: 若是一个字符串对像保存的是整数值,且该值可用long类型来表示,那么该对象会将整数值保存在ptr属性中(void*转换为long),并将encoding设置为int
  • raw:字符串值(含浮点型),且长度大于32Byte(默认),那字符串对象将使用一个SDS来保存这个值,并将encoding设置为raw
  • embstr:字符串值(含浮点型),且长度小于等于32字节,则使用embstr编码的方式来保存

注1:embstr是一种专门保存短字符串的优化编码,与raw同样使用redisObject+sdshdr结构,区别是,raw调用两次内存分配函数来分别建立redisObject结构和sdshdr结构,而embstr则调用一次内存分配函数来分配一块连续的内存空间,该空间依次包含这两种结构

注2:浮点型数据,在redis也是作为字符串对象保存的,保存或者计算时会有一个类型转换的过程

List 列表

能够用ziplistlinkedlist表示,后来用quicklist(3.2+)

  • ziplist: 知足如下条件时使用压缩列表作为list的底层实现:
    • 全部元素字符串长度都小于64Byte(默认值)
    • 元素数量小于512
  • linkedlist: 不知足使用ziplist的条件时,使用linkedlist
  • quicklist: redis3.2开始支持的数据结构,是一个由ziplist组成的双端列表,链表的每个节点都是一个ziplist,貌似3.2以后,list只用quicklist结构实现

list-max-ziplist-size:每一个ziplist(即quicklist的节点)大小,默认-2,此值可正可负,其中正数表示每一个压缩列表中存放的最大元素个数,若是是负数,表示按字节数来限定元素个数:

  • -1 每一个节点的ziplist字节大小不能超过4kb
  • -2 每一个节点的ziplist字节大小不能超过8kb(默认值)
  • -3 每一个节点的ziplist字节大小不能超过16kb
  • -4 每一个节点的ziplist字节大小不能超过32kb
  • -5 每一个节点的ziplist字节大小不能超过64kb

Hash 哈希

编码为ziplisthashtable

  • ziplist 用两个ziplist节点分别表示键和值,添加键值对时,先将键节点推入到表尾,再将值节点推入到表尾,所以键值对老是紧挨着且先加入的在表头方向; 知足以下条件时使用ziplist作底层实现:
    • 全部键值对的键和值字符串的长度所有小于64Byte(默认值,配置项:hash-max-ziplist-value
    • 键值对数量小于512(默认值,配置项:hash-max-ziplist-entries
  • hashtable 不知足使用ziplist的条件时,将使用hashtable作为底层结构

Set 集合

集合对象的编码能够是intset或者hashtable

  • intset 知足如下条件时用做集合的底层实现:
    • 集合对象保存的全部元素值都是整数值
    • 元素数量不超过512(默认值,配置项:set-max-intset-entries
  • hashtable 不适用intset时,使用hashtable作为底层实现,使用hashtable时,只使用键,值为Null,相似于java的HashSet

Sorted Set 有序集合

有序集合的编码能够是ziplistskiplist

  • ziplist:使用ziplist实现时,每一个有序集合元素使用挨在一块儿的两个ziplistNode表示,第一个表示元素成员member,第二个表示分值score;ziplist中的集合元素按分值从小到大排列,小的靠近表头方向,大的靠近表尾方向;知足以下条件时使用:
    • 元素数量小于128(默认值,配置项:zset-max-ziplist-entries
    • 全部元素成员的长度小于64(默认值,配置项:zset-max-ziplist-value
  • skiplist 使用zset结构作为底层实现,每一个zset同时包含一个字典dict和一个跳跃表skiplist:
    • skiplist :按分值从小到大保存了有序集合的元素,保证有序,提升范围型操做性能
    • dict :字典则是为每一个元素建立了成员到分值的映射,提供快速查找性能

:编码为skiplist时,跳跃表和字典会共享成员及分值,内存中只占一分,由于不存在内存浪费;


----- 快乐的分割线 -------- 下面其它类型,还没好好研究完---------


pubsub 发布/订阅

发布/订阅彷佛是一项独立功能,不能算一种数据类型,不过从使用上差很少,估且也算在这儿吧;

redis的发布/订阅功能分为两类:频道的发布/订阅及模式的发布/订阅;redis的服务器在redis内部用redisServer结构表示,而发布订阅的实现,依赖于redisServer中的两个属性:

  • 频道(channel) pubsub_channels字典,字典的键表示被订阅的频道,而值是一个链表,存储了全部订阅该频道的客户端;
    • 订阅:定位到频道的订阅链表,在表尾添加一个含订阅客户端的节点
    • 退订:定位到频道的订阅链表,遍历,找到含退订客户端的节点,删除
    • 发布:定位到频道的订阅链表,遍历,依次发消息
  • 模式(patter) pubsub_patterns 链表,每一个节点都包含一个pubsubPattern结构,该结构中存储了订阅模式的客户端和订阅的模式;
    • 订阅:建立一个pubsubPattern结构,添加到pubsub_patterns 链表尾
    • 退订:遍历pubsub_patterns,找到含要退订的模式和客户端的节点,删除
    • 发布:遍历pubsub_patterns,向模式匹配的客户发消息

注:订阅将阻塞线程,应该在独立线程独立客户端中使用;

HyperLogLog

使用type查询一个HyperLogLog类型的值,是string,彷佛,是基于string结构实现的HyperLogLog功能?待探究

Geo

Stream

还没有研究,且目前5.0版本中,做者不建议在生产环境中使用stream,因此学习后再补充


-------- 快乐的分割线------- 知识扩展 ----------------

相关文章
相关标签/搜索