Redis对象系统

Redis对象

  • 字符串(String)的底层实现方式

    • 直接保存整数值:字符串对象保存的是整数值,且可以用long类型来表示。
    • embstr编码的SDS:字符串对象保存的是一个长度小于等于39字节的字符串值。
    • SDS:字符串对象保存的是一个长度大于39字节的字符串值。
  • 列表(List)的底层实现方式
    • 压缩列表:列表对象保存的所有字符串元素的长度都小于64字节,且元素数量小于152个(注意:上限值是可以修改的,其他对象的上限值也是同洋的道理)。
    • 双端链表:不满足压缩列表的使用条件,则使用双端链表。
  • 哈希(Hash)的底层实现方式
    • 压缩列表:哈希对象保存的所有键值对的键和值的字符串长度都小于64字节,且键值对数量小于512个。
    • 字典:不满足压缩列表的使用条件,则使用字典。
  • 集合(Set)的底层实现方式
    • 整数集合:集合对象保存的所有元素都是整数,且元素数量不超过512个。
    • 字典:不满足整数集合的使用条件,则使用字典。
  • 有序集合(Zset)的底层实现方式
    • 压缩列表:有序集合保存的元素数量小于128个,且所有元素的长度都小于64字节。
    • 跳跃表+字典:不满足压缩列表的使用条件,则使用跳跃表+字典

Redis对象的实现

typedef struct redisObject {
// 类型
unsigned type:4; // 编码
unsigned encoding:4; // 指向底层数据结构的指针
void *ptr; // 引用计数
int refcount; // 最后一次被命令程序访问的时间
unsigned lru:8; //...
} robj;

对象的类型属性Type

类型常量 对象的名称
REDIS_STRING 字符串对象
REDIS_LIST 列表对象
REDIS_HASH 哈希对象
REDIS_SET 集合对象
REDIS_ZSET 有序集合对象

对象的编码属性Encoding和底层实现

类型 编码 对象
REDIS_STRING REDIS_ENCODING_INT 使用整数值实现的字符串对象
REDIS_STRING REDIS_ENCODING_EMBSTR 使用embstr编码的简单动态字符串实现的字符串对象
REDIS_STRING REDIS_ENCODING_RAW 使用Simple Dynamic String实现的字符串对象
REDIS_LIST REDIS_ENCODING_ZIPLIST 使用压缩列表实现的列表对象
REDIS_LIST REDIS_ENCODING_LINKEDLIST 使用双端链表实现的列表对象
REDIS_HASH REDIS_ENCODING_ZIPLIST 使用压缩列表实现的哈希对象
REDIS_HASH REDIS_ENCODING_HT 使用字典实现的哈希对象
REDIS_SET REDIS_ENCODING_INTSET 使用整数集合实现的集合对象
REDIS_SET REDIS_ENCODING_HT 使用字典实现的集合对象
REDIS_ZSET REDIS_ENCODING_ZIPLIST 使用压缩列表实现的有序集合对象
REDIS_ZSET REDIS_ENCODING_SKIPLIST 使用跳跃表和字典实现的有序集合对象

为什么需要同时使用跳跃表和字典来实现有序集合?

  1. 只使用字典来实现:执行查找的时间复杂度为O(1),但是执行范围性查询操作如ZRANGE、ZRANK等,需要对字典保存的所有元素排序,至少需要O(NlogN)的时间,以及额外的O(N)空间。
  2. 只使用跳跃表来实现:执行范围性查询的优点会被保留,但执行查找的时间复杂度为O(logN)。

所以为了查找和范围性查询都有尽可能快的执行,同时使用字典和跳跃表实现。

内存回收

对象的引用计数会随着对象的使用状态而不断变化:

  • 当创建一个新对象时,引用计数的值被初始化为1
  • 当对象被一个新程序使用时,引用计数的值会加1
  • 当对象不再被一个程序使用时,引用计数的值会减1
  • 当对象的引用计数变为0时,对象所占的内存会被释放

对象共享

Redis中让多个键共享同一个值对象(节约内存):

  • 将key的值指针指向一个现有的对象
  • 将被共享的值对象的引用计数加1

Redis只对包含整数值的字符串对象进行共享

当共享对象时,首先需要检查给定的共享对象和想创建的目标对象是否完全一致,只有在共享对象和目标对象完全相同的情况下才会使用共享对象。

  • 如果共享的是保存整数值的字符串对象,那么验证是否一致的时间复杂度为O(1)
  • 如果共享的是保存字符串的字符串对象,那么验证是否一致的时间复杂度为O(N)
  • 如果共享的是包含了多个值的对象,那么验证是否一致的时间复杂度为O(N*2)

所以考虑到CPU时间的限制,Redis只对包含整数的字符串对象进行共享。

Redis读书笔记(二)的更多相关文章

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

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

  2. 《你必须知道的.NET》读书笔记二:小OO有大原则

    此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...

  3. spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...

  4. ES6读书笔记(二)

    前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...

  5. spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定

    本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...

  6. redis相关笔记(二.集群配置及使用)

    redis笔记一 redis笔记二 redis笔记三 1.配置:在原redis-sentinel文件夹中添加{8337,8338,8339,8340}文件夹,且复制原8333中的配置 在上述8333配 ...

  7. [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串

    本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...

  8. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  9. Mastering Web Application Development with AngularJS 读书笔记(二)

    第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...

  10. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

随机推荐

  1. ceph 因权重问题导致pgs active+clean+remapped 状态

    1.现象: 2.原因:是因为前期权重调整不合理导致,调整回来就正常了 3.操作步骤: ceph osd crush reweight osd.2 0.98317    # osd 位置. 权重值 权重 ...

  2. FII-PRA006/010开发板硬件实验一

    FII-PRA006/010开发板硬件实验一 以一位全加器为例介绍如何利用开发板进行板载实验.一位全加器的Verilog代码如下: 1 2 3 4 5 6 7 8 9 10 module fadd1 ...

  3. Java swing图形界面计算器

    效果图如下所示 : import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.Gr ...

  4. 【机器学习】搞清楚机器学习的TP、FN、FP、TN,查全率和查准率,PR曲线和ROC曲线的含义与关系

    最近重新学习了一下机器学习的一些基础知识,这里对性能度量涉及到的各种值与图像做一个总结. 西瓜书里的这一部分讲的比较快,这些概念个人感觉非常绕,推敲了半天才搞清楚. 这些概念分别是:TP.FN.FP. ...

  5. yapi的一些基本操作

    一.yapi能干什么 强大的接口管理平台 提供mock功能 提供测试功能 项目管理功能 插件齐全 二.yapi的权限 项目权限 操作 游客 项目开发者 项目组长 超级管理员 浏览公开项目与接口 √ √ ...

  6. 用javassist和CGLIB 解决JDK动态代理的缺陷

     用 javassist 解决 JDK 动态代理的缺陷 JDK动态代理的缺陷 要求目标类必须实现接口,否则产生不了代理.有些场景下,目标类也要产生代理类但是木有实现接口,这个时间 Java 中有两个常 ...

  7. 通过Rdp实现连接远程桌面

    unit UnitMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Fo ...

  8. Ansible之Playbook介绍和使用

    1.https://blog.csdn.net/zfw_666666/article/details/124691877 1.Playbook介绍        Playbook与ad-hoc相比,是 ...

  9. AssetBuddle(一)

    一·含义 一个压缩文件,针对于特定平台的资产压缩包.资产包括模型,贴图,预制体,音效,材质球等,注意不包括c#脚本. 二·作用 相对于resource文件夹下面的东西打包后定死只读,无法修改. AB包 ...

  10. Python内置函数:enumerate

    enumerate(sequence, [start=0]) enumerate单词本身翻译为列举.枚举. 官方说明: enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组 ...