博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis 对象
阅读量:7034 次
发布时间:2019-06-28

本文共 3257 字,大约阅读时间需要 10 分钟。

hot3.png

    Redis并没有直接使用SDS、双端链表、字典、压缩列表、整数集合等这些数据结构,而是基于这些数据结构创建了一个对象系统,这个对象系统包含字符串对象(String)、列表对象(List)、哈希对象(Hash)、集合对象(Set)和有序集合对象(SortedSet)这5种类型,每种对象都用到了至少一种数据结构。

    这种设计的好处是将我们真实使用的对象提到了底层数据结构层级之上,让我们可以对同一个对象类型有不同的实现,然后根据不同的场景使用不同的数据结构实现,优化使用效率。

    除此之外,Redis对象系统还实现了基于引用计数范式的内存回收机制(即每个对象还有一个引用计数字段,每当有其他对象引用便计数加1,当引用计数为0时,表示没有其他对象引用这个对象,即可以回收,这种访问有个明显缺点,即存在相互引用情况导致对象不能被回收),回收不再使用对象的内存;另外,Redis还通过引用计数方式实现了对象共享机制,这一机制可以在适当条件下,通过让多个数据库键共享同一个对象节约内存。

    最后,Redis对象带有访问时间记录信息,可以用于计算数据库键的空转时长,在服务器启用了maxmemory功能并且回收内存的算法为volatile-lru或者allkeys-lru的情况下,当内存超过maxmemory设置的阀值,空转时长较大的那些键可能会优先被服务器回收。具体可以查看配置文件maxmemory和maxmemory-policy选项的说明介绍。

redis.h/redisObject源码

typedef struct redisObject {  // 类型  unsigned type:4;  // 编码  unsigned encoding:4;  // 对象最后一次被访问的时间  unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */  // 引用计数  int refcount;  // 指向实际值的指针  void *ptr;} robj;
  • type:表示当前redis对象的类型,可以使用type命令查看某个key对应的值的redisObject的类型,包含5种可能值:
    • REDIS_STRING 字符串对象,type命令输出为"string"
    • REDIS_LIST 列表对象,type命令输出为"list"
    • REDIS_HASH 哈希对象,type命令输出为"hash"
    • REDIS_SET 集合对象,type命令输出为"set"
    • REDIS_ZSET 有序集合对象,type命令输出为"zset"
  • encoding:表示当前对象使用的数据结构类型,即ptr指针指向的对象对应的数据结构,可以使用obejct encoding <key>命令查出对应值的数据结构,可能值如下:
    • REDIS_ENCODING_INT long类型的整数,object encoding命令返回值“int”
    • REDIS_ENCODING_EMBSTR embstr编码的简单动态字符串,object encoding命令返回值“embstr”
    • REDIS_ENCODING_RAW 简单动态字符串,object encoding命令返回值“raw”
    • REDIS_ENCODING_HT 字典,object encoding命令返回值“hashtable”
    • REDIS_ENCODING_LINKEDLIST 双端链表,object encoding命令返回值“linkedlist”
    • REDIS_ENCODING_ZIPLIST 压缩链表,object encoding命令返回值“ziplist”
    • REDIS_ENCODING_INTSET 整数集合,object encoding命令返回值“intset”
    • REDIS_ENCODING_SKIPLIST 跳跃表,object encoding命令返回值“skiplist”

编码与类型对应关系如下:

  • refcount:引用计数,当计数为0时,用于内存回收
  • ptr:指向对象实际结构的指针

 

字符串对象

字符串对象编码可以是int、raw或者embstr,字符串对象是唯一会潜逃到其他数据结构中使用的结构,编码切换条件如下:

  • 如果保存的是一个字符串值(不能转化成整数),且长度大于32字节,使用raw即SDS
  • 如果保存的是一个字符串值(不能转化成整数),且长度小于等于32字节,使用embstr
  • 如果保存的是一个整数,使用int即c语言的long类型

embstr与raw(SDS)结构完全一样,唯一的却别是如果使用raw(SDS)会进行两次内存分配,先分配创建SDS,然后分配创建redisObject,再使ptr指针指向SDS,即SDS和redisObject的内存地址可以不连续。而embstr的SDS结构和redisObject结构内存连续,只需要一次内存分配,embstr优势:

  • 只需要一次内存分配
  • 只需要一次内存回收
  • 由于内存连续,更利于CPU高速缓存载入

字符串各个数据结构之间调用不同方法的转换:

列表对象

列表对象的编码可以是ziplist或者linkedlist,转换规则,当满足下面任意一条将使用linkedlist:

  • 列表对象所存字符串元素长度有一个及以上大于等于64字节;
  • 列表对象所存元素数量大于等于512;

上面两个条件的阀值可以通过配置文件list-max-ziplist-value和list-max-ziplist-entries两个属性进行修改。

ziplist和linkedlist方法实现差异:

哈希对象

哈希对象的编码可以是ziplist或者hashtable,ziplist在存键值对时总是两个相关联的键值对紧挨在一起,建在前值在后,每次都在表尾添加,即越后添加的键值对越靠近表尾。

编码切换条件,满足任意一个,将使用hashtable:

  • 任意一个或以上键或者值长度大于等于64字节
  • 键值对数量大于等于512

上限阀值可以通过配置中的hash-max-ziplist-value和hash-max-ziplist-entries属性修改。

不同数据结构方法实现差异:

集合对象

集合对象的编码可以是intset或者hashtable,切换条件如下,满足任一会使用hashtable:

  • 集合所有元素有一个或以上不是整数值
  • 集合元素数量大于等于512,可以通过配置set-max-intset-entries设置

方法实现差异:

有序集合对象

有序集合的编码可以是ziplist或者skiplist。ziplist编码也和集合对象使用一样,只是插入时会确保score的升序排列,有序列表的skiplist数据结构有些特殊,源代码如下:

/* * 有序集合 */typedef struct zset {  // 字典,键为成员,值为分值  // 用于支持 O(1) 复杂度的按成员取分值操作  dict *dict;  // 跳跃表,按分值排序成员  // 用于支持平均复杂度为 O(log N) 的按分值定位成员操作  // 以及范围操作  zskiplist *zsl;} zset;

同时使用zskiplist和dict,这样做是为了保证可以同时使用skiplist进行高效查找遍历,使用dict高效通过key获取score,由于使用了共享对象,所以内存并没有浪费。

编码转换条件,满足任一对象使用ziplist编码:

  • 保存的元素数量大于等于128
  • 保存的元素长度由一个或以上长度大于等于64字节

可以用配置中zset-max-ziplist-entries和zset-max-ziplist-value属性修改

方法实现区别:

 

转载于:https://my.oschina.net/u/1413049/blog/1522878

你可能感兴趣的文章
服务器软硬件维护需要注意的事项
查看>>
以数字赋能,使万物生长,2017年中国国际信息通信展注册开启
查看>>
密云:大数据平台促进休闲农业发展
查看>>
大数据为青岛点亮智慧城市“灯塔”
查看>>
PSEG收购BayWa r.e北卡罗来纳州6.6MW光伏项目
查看>>
通过“追寻赎金的流向”评估隐藏在以医院为目标的勒索软件背后的犯罪活
查看>>
NetApp公司的4KB块写入技术真能容纳更多数据吗?
查看>>
2016年我国车联网行业市场前景分析
查看>>
Win10份额不给力?企业市场表现惊艳
查看>>
Hortonworks“来到了”亚马逊AWS上
查看>>
昆腾公司稍感安慰:向外扩展存储业务营收有所提升
查看>>
爱立信预计2017年下半年实现初始5G网络
查看>>
Facebook将为尼尔森公司提供用户电视评价数据
查看>>
美国防部针对五角大楼网络武器采购实施改革
查看>>
北京市将率先建5G试验网 扩大WiFi覆盖范围
查看>>
振动传感器选型需注意的问题盘点
查看>>
Ceryx为企业提供UC
查看>>
三家SDN元老企业联手打造最佳SDN传输解决方案
查看>>
跨国企业的工业物联网市场布局分析
查看>>
秋色园QBlog技术原理解析:博客一键安装工具技术实现[附源码下载]
查看>>