前面我们看了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. vue原生表格怎样实现动态列及表格数据下载

    最近项目经常用到带有合并效果以及动态列的表格,而翻阅iview和element-ui官网没有找到合适的(也有可能自己的水平有限,不会改写),所以只好自己用原生表格写了一个,具体效果如下: 这个表格右侧 ...

  2. 分析 Nanocore

    Nanocore是一个非常强大的木马控制系统,当Nanocore木马运行时,我们发现Windows Defender可以很好地识别威胁.本文的目的是分析Nanocore的传播方式,它是怎样感染Wind ...

  3. Nginx(1)---安装及基础命令

    一.简述 Nginx是一个高性能WEB服务器,除它之外Apache.Tomcat.Jetty.IIS,它们都是Web服务器 Nginx  相对基它WEB服务有什么优势:Tomcat.Jetty 面向j ...

  4. 在项目中部署redis的读写分离架构(包含节点间认证口令)

    #### 在项目中部署redis的读写分离架构(包含节点间认证口令) ##### 1.配置过程 ---  1.此前就是已经将redis在系统中已经安装好了,redis utils目录下,有个redis ...

  5. 0day学习笔记(3)Windows定位API引起的惨案(原理)

    段选择器FS与TEB WinNT内核下内存采用保护模式,段寄存器的意义与实模式汇编下的意义不同.另外,FS存的是段选择子,而不是实模式下的高16位基地址. FS寄存器指向当前活动线程的TEB结构(线程 ...

  6. Git基本操作和使用

    基本命令: git config git init git clone git remote git fetch git commit git rebase git push 本地基本操作: git ...

  7. 使用宝塔面板部署tp5网站

    来源:https://www.cnblogs.com/e0yu/p/9102902.html 遇到一个问题,就是当thinkphp5部署在宝塔面板上,会出现这个问题: 参考解决办法: http://w ...

  8. 如何用hugo 搭建博客

    1,Hugo 简介 搭建个人博客有很多开源的博客框架,我们要介绍的框架叫作Hugo.Hugo 是一个基于Go 语言的框架,可以快速方便的创建自己的博客. Hugo 支持Markdown 语法,我们可以 ...

  9. Java5-7作业总结(第八次作业)19201421-吴志越

    前言:关于此次三次作业,相比于前3次难度着实高了一个档次,第五次作业,虽然对于工具类没有很高.但是第一题的复杂程度很高,对于正则表达式有很高的要求,需要使用很多正则表达式的方法,而且不能有一处错误,对 ...

  10. Java9新特性系列(module&maven&starter)

    上篇已经深入分析了Java9中的模块化,有读者又提到了module与starter是什么关系?本篇将进行分析. 首先先回顾下module与maven/gradle的关系: module与maven/g ...