前面我们看了Redis用到的主要数据结构,如简单动态字符串(SDS)、双向链表、字典、压缩列表、整数集合等。

但是Redis并没有直接使用这些数据结构来实现键值对,而是基于这些数据结构创建了一个对象系统,这个系统包括字符串对象、列表对象、哈希对象、集合对象、有序集合对象,除此之外,redis的对象系统还实现了基于计数技术的内存回收机制,另外redis还通过引用计数技术实现了对象共享机制(适当条件下,多个数据库键共享同一个对象来节约内存)。

最后,redis的对象带有访问时间记录信息,该信息可以用于计算数据库键的空转时长,在服务器启用了maxmemory功能的情况下,空转时长较大的键会优先被服务器删除。

1、Redis中的每个结构都是由redisObject结构标识,包含ptr(指向底层实现的数据结构)、encoding(决定用那种底层数据结构)、type等属性。

2、当我们创建一个键值对时,我们至少会创建两个对象:键对象(字符串对象),值对象(物种类型)。

3、字符串对象的编码可以是整数、raw或者enbstr、sds

  1. enbstr(短字符串长度小于32)调用一次分配内存函数,分配一个连续的内存包含redisObject结构与sdshdr结构,不包含修改命令,执行任何修改命令会转为raw对象。

  2. sds(字符串长度超过32)。

  3. raw 会调用两次内存分配分别创建redisObject结构与sdshdr结构。

4、列表对象,列表对象的编码可以是ziplist或者linkedlist

  1. ziplist使用压缩列表作为底层实现。列表对象保存的所有字符串元素长度都小于64字节,元素数量小于512个时使用压缩列表做为底层实现。

  2. linkedlist编码列表对象使用双向链表作为底层实现,每个双向链表节点都保存一个字符串对象。

5、哈希对象

  1. 哈希对象的编码可以是ziplist或者hashtable

  2. ziplist编码的哈希对象使用压缩表作为底层实现,当由新的键值对加入到hash对象时,程序会先将保存了键的压缩列表节点推入到压缩列表的表尾,然后将保存了值的压缩列表节点推入到压缩列表的表尾。

  3. 使用hashtable作为编码的哈希对象使用字典作为底层实现,键使用字符串对象,值使用字符串对象。

6、集合对象

  1. 集合对象的编码可以是 intset或者是hashtable

  2. intset编码的集合对象使用整数集合作为底层实现。

  3. hashtable编码的集合对象使用字典作为底层实现,字典的每个键都是一个字符串对象,每个字符串对象包含一个集合元素,而字段的值则全部设置为null。

  4. 对象转换 。intset转hashtable条件:元素中不全是整数或者元素数量超过512.

7、有序集合对象

  1. 有序集合的编码可以是ziplist 或者skiplist

  2. ziplist编码的压缩列表对象使用压缩列表作为底层实现,每个集合元素使用两个挨在一起的压缩列表节点来保存,第一个节点保存元素的成员(member)第二个元素则保存元素的分值(score)。

  3. skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表。

  4. typedef struct zset{
    zskiplist *zsl;
    dict *dict;//保存从成员到分值的映射,键保存元素成员 值保存了分数。
    }
  5. 解释下为什么同时使用字典与跳跃表来实现有序集合:虽然用两种结构的任意一种都能实现有序集合,但是当我们只是用字典来实现有序集合时,由于字典是一个无序的保存元素,当我们实行范围操作时,需要先对所有的元素进行排序,这里所使用的时间复杂度至少为O(NlogN),并且有额外的内存消费;另外如果只使用跳跃表来实现有序集合时,虽然范围操作的优势被保留,但是没有了字典根据成员查找分值时这一操作的复杂度将从O(1)提升到O(logN)。

  6. 编码转换,当元素的数量小于128,且每个元素的长度都小于64字节时,使用ziplist。

8、内存回收

  1. 每个对象的引用技术信息由redisObject结构的refcount属性记录。

  2. 创建对象时,计数值会被默认初始化为1,被程序使用时,计数器加一,不再被使用时,计数器减一,当计数器为0时,对象占用的内存会被释放。

9、对象空转时长

  1. 对象空转时长使用redisObjet结构中的lru属性记录,该属性记录对象最后一次被访问的时间。

--------- end --------

每天学一点,总会有收获。

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。

Redis学习笔记(六) 对象的更多相关文章

  1. Redis学习笔记六:持久化实验(AOF,RDB)

    作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...

  2. Redis学习笔记六:独立功能之 Lua 脚本

    Redis 2.6 开始支持 Lua 脚本,通过在服务器环境嵌入 Lua 环境,Redis 客户端中可以原子地执行多个 Redis 命令. 使用 eval 命令可以直接对输入的脚本求值: 127.0. ...

  3. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  4. Redis学习笔记(二) Redis 数据类型

    Redis 支持五种数据类型:string(字符串).list(列表).hash(哈希).set(集合)和 zset(有序集合),接下来我们讲解分别讲解一下这五种类型的的使用. String(字符串) ...

  5. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  6. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  7. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  8. Redis学习笔记(二)Redis支持的5种数据类型的总结之String和Hash

    引言 在Redis学习笔记(一)中我们已经会安装并且简单使用Redis了,接下来我们一起来学习下Redis支持的5大数据类型. 简介 Redis是REmote DIctionary Server(远程 ...

  9. Redis学习笔记(2)——Redis的下载安装部署

    一.下载Redis Redis的官网下载页上有各种各样的版本,如图 但是官网下载的Redis项目不正式支持Windows.如果需要再windows系统上部署,要去GitHub上下载.我下载的是Redi ...

  10. Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...

随机推荐

  1. Springboot:员工管理之添加员工(十(7))

    构建员工添加请求 com\springboot\controller\EmployeeController.java /*调转到员工添加页 携带部门信息 restful风格*/ @GetMapping ...

  2. tp5.0看点

    前置操作:操作一些其他动作,例如要操作其他表格的数据啊,操作之前要有什么动作为前提或者要注意的动作. 模型事件:操作数据,例如照片的上传修改和删除. 两者的区别在于“前置操作”是动作,而“模型事件”只 ...

  3. 如何给 Visual Studio 的输出程序添加版本信息

    出处:https://stackoverflow.com/questions/284258/how-do-i-set-the-version-information-for-an-existing-e ...

  4. Ubuntu 修改 hosts 文件

    sudo vi /etc/hosts sudo /etc/init.d/networking restart

  5. Spring5参考指南:Bean的生命周期管理

    文章目录 Spring Bean 的生命周期回调 总结生命周期机制 startup和Shutdown回调 优雅的关闭Spring IoC容器 Spring Bean 的生命周期回调 Spring中的B ...

  6. Scala教程之:函数式的Scala

    文章目录 高阶函数 强制转换方法为函数 方法嵌套 多参数列表 样例类 比较 拷贝 模式匹配 密封类 单例对象 伴生对象 正则表达式模式 For表达式 Scala是一门函数式语言,接下来我们会讲一下几个 ...

  7. String、String[]、ArrayList<String>之间的转换

    1. ArrayList<String> 转换为 String[]: ArrayList<String>  list = new ArrayList<>(); li ...

  8. Git 常见问题汇总

    git reabse 合并多个commit git rebase -i HEAD~{NUM} git rebase -i start end 会进入一个指定区间的commit列表 根据提示进行文本编辑 ...

  9. element-ui中cascader同时获取label和value值

    关于elementUI中cascader选中值后,能获取value或者label,但不能同时获value和label,这一问题,琢磨出了这么个办法.以新增和编辑城市为例,type: 1 编辑,type ...

  10. Netty随记之ChannelInboundHandlerAdapter、SimpleChannelInboundHandler

    ChannelInboundHandlerAdapter ChannelInboundHandlerAdapter是ChannelInboundHandler的一个简单实现,默认情况下不会做任何处理, ...