前面我们看了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. Jwt认识与攻击

    今天看到2018强网杯的题目,因此总结一下. Json Web Token Json Web Token简称jwt 那么怎么样可以让HTTP记住曾经发生的事情呢? 这里的选择可以很多:cookie,s ...

  2. 《闲扯Redis五》List数据类型底层之quicklist

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...

  3. 排序1 - 选择排序 & 插入排序

    请原谅我没有按照之前图片的分类来介绍排序算法,先说最简单的两种排序算法(冒泡略过),选择排序和插入排序,之前老是容易记混.默认输出升序的序列啊,哈哈. 选择排序 对于输入长度为n的数组,一共比较n-1 ...

  4. 从零开始的计算机网络基础(图文并茂,1.8w字,面试复习必备)

    前言 在互联网高速发展的今天,我们通过手机,电脑等通讯设备可以很轻松达到未出茅庐便知天下事的境界.每天我们都要访问数不胜数的网站,通过打开浏览器,输入网址两步搞定.当然更为常规的做法是打开浏览器,设置 ...

  5. OAuth-授权机制

    一.应用场景 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片. 问 ...

  6. [Python进阶].pyc的那点事

    1. 什么是 .pyc文件 .pyc文件 就是 Python的字节码(byte-compiled)文件..py文件运行时,python会自动将其编译成PyCodeObject并写入.pyc文件,再有p ...

  7. Js实现将html页面或div生成图片

    参考:https://blog.csdn.net/huwei2003/article/details/79761580 今天要分享的是用html2canvas根据自己的需求生成截图,并且修复html2 ...

  8. OpenCV学习(4)——动态结构

    学习一个新知识,无外乎学习它本身和它的工具.OpenCV提供许多内置的结构及处理函数,非常值得学习. 内存存储 在OpenCV中,内存存储器是一个可以用来存储序列.数组和图像的动态增长的数据结构.它由 ...

  9. @SessionAttributes 和 @SessionAttribute的区别

    @SessionAttributes 和 @SessionAttribute的区别 Spring MVC中有两个长得非常像的注解:@SessionAttributes 和 @SessionAttrib ...

  10. Netty(七):EventLoop学习前导——Reactor模式

    了解Netty的人多少都会知道Netty的高性能的一个原因就是它是基于事件驱动的,而这一事件的原型就是Reactor模式. 所以在学习EventLoop前,很有必要先搞懂Reactor模式. 本文目录 ...