本文的分析都是基于 Redis 6.0 版本源码

redis 6.0 源码:https://github.com/redis/redis/tree/6.0

在 Redis 中,有五大数据类型,都统一封装成了一个数据类型:redisObject。定义如下:

typedef struct redisObject {
unsigned type:4; // 类型
unsigned encoding:4; // 编码
unsigned lru:LRU_BITS; // 最近被访问的时间
int refcount; // 引用次数
void *ptr; // 指向具体底层数据的指针
} robj;

一、类型

typedef struct redisObject {
unsigned type:4; // 类型
} robj;

类型就是常见的五大对象类型。

新版本的常量命名是 OBJ 前缀,老版本是 REDIS 前缀(如 REDIS_STRING )

类型常量 对象名称
OBJ_STRING 字符串对象
OBJ_LIST 列表对象
OBJ_SET 集合对象
OBJ_ZSET 有序集合对象
OBJ_HASH 哈希对象

TYPE 命令可以输出指定 key 的值的对象类型。

redis > set str_key str_value
OK
redis > TYPE
string
对象名称 TYPE 命令输出
字符串对象 string
列表对象 list
集合对象 set
有序集合对象 zset
哈希对象 hash

二、编码

typedef struct redisObject {
unsigned encoding:4; // 编码
} robj;

五大类型中,每种类型可能存在着不同的编码。编码的存在主要是为了在节约内存和提高性能之间做平衡。

  • 当数据量小的时候,会采用紧凑(性能偏低)的数据结构
  • 当数据量达到一定阈值的时候,会从紧凑型的结构转成高效率的数据结构

由于篇幅有限,编码又比较复杂。所以编码就放到后面的文章写吧,嘿嘿嘿

三、最近被访问时间

typedef struct redisObject {
unsigned lru:LRU_BITS; // 最近被访问的时间
} robj;

当 Redis 的使用内存达到指定的阈值的时候,Redis 会对内存进行回收,回收有很多策略,其中就有 LRU 策略。

LRU 简单点来说就是,最近有修改或者访问的,就排在前面。等到要淘汰的时候,就淘汰排在后面的元素。淘汰的元素相对来说就是很久没有进行访问/修改了。

Redis 记录这个最近访问时间,就是为了 LRU 策略用的。

命令 OBJECT IDLETIME 可以查看 key 距离上次访问的时间。

由于篇幅有限,具体的淘汰策略就放到后面的文章吧,嘿嘿嘿。

四、引用次数

typedef struct redisObject {
int refcount; // 引用次数
} robj;

refcount 的作用主要是对象的引用计数和内存回收。refcount会随着对象的使用状态而变化:

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

命令 OBJECT REFCOUNT 可以查看指定 key 的引用计数值。

共享对象

那么对象什么时候才会被新程序使用呢?

为了节省内存,Redis 会在初始化的时候,创建好 0 ~ 9999 的对象,后续 0 ~ 9999 的整数值都会用这些共享对象,不会重新创建对象。

server.h

#define OBJ_SHARED_INTEGERS 10000

object.c

// ...
if (value >= 0 && value < OBJ_SHARED_INTEGERS...)
// ...

五、指针

typedef struct redisObject {
void *ptr; // 指向具体底层数据的指针
} robj;

指针通常来说就是指向底层数据的。

不过有个例外,当值是 string 类型,并且编码是 int 时,保存的就是这个整数值,而不是指针。

关于底层数据的结构,后面会说。

Redis 设计与实现:Redis 对象的更多相关文章

  1. Redis设计与实现

    简述Redis设计与实现 Redis是一个高性能的key-value的非关系型数据库,Redis是运行在内存中的一种数据库,但是它也可以持久化到磁盘中,Redis的实现有着更为复杂的数据结构并且提供对 ...

  2. 如何使用redis设计关系数据库

    目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...

  3. Redis | 第一部分:数据结构与对象 上篇《Redis设计与实现》

    目录 前言 1. 简单动态字符串 1.1 SDS的定义 1.2 空间预分配与惰性空间释放 1.3 SDS的API 2. 链表 2.1 链表与节点的定义 2.2 链表的API 3. 字典 3.1 哈希表 ...

  4. Redis | 第一部分:数据结构与对象 下篇《Redis设计与实现》

    目录 前言 1. Redis对象概述 1.1 对象的定义 2. 字符串对象 3. 列表对象 3.1 quicklist 快速链表 4. 哈希对象 5. 集合对象 6. 有序集合对象 7. Redis对 ...

  5. Redis | 第一部分:数据结构与对象 中篇《Redis设计与实现》

    目录 前言 1. 跳跃表 1.1 跳跃表与其节点的定义 1.2 跳跃表的API 2. 整数集合 2.1 整数集合的实现 2.2 整数集合的类型升级 2.3 整数集合的API 3. 压缩列表 3.1 压 ...

  6. Redis设计与实现(一~五整合版)【搬运】

    Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...

  7. Redis设计与实现-内部数据结构篇

    题记:这本书是2015年11月份开始读的,大约花了一个多月的时间通读了一遍,最近由于需要对redis做一些深入的了解,因此又花了两个多月仔细精读了一遍,由于本书设计的内容较多,且每部分的内容都比较细致 ...

  8. Redis笔记(1)数据结构与对象

    1.前言 此系列博客记录redis设计与实现一书的笔记,提取书本中的知识点,省略相关说明,方便查阅. 2.基本数据结构 2.1 简单动态字符串SDS(simple dynamic string) 结构 ...

  9. 《Redis设计与实现》

    <Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...

  10. 180713-Spring之借助Redis设计访问计数器之扩展篇

    之前写了一篇博文,简单的介绍了下如何利用Redis配合Spring搭建一个web的访问计数器,之前的内容比较初级,现在考虑对其进行扩展,新增访问者记录 记录当前站点的总访问人数(根据Ip或则设备号) ...

随机推荐

  1. P5656 【模板】二元一次不定方程(exgcd)

    还不会 exgcd 的请移步窝的学习笔记,这里只讲怎么搞出烦人的答案. 在 \(a,b\) 两者互质的情况下,二元一次不定方程的通解:\(a(x+db)+b(y+da)=c\). 所以要先将 \(a, ...

  2. 6.2 Binding基础

    WPF最为核心的思想是数据驱动UI,实现这一技术的基石就是绑定技术(binding).如果把Binding比作数据的桥梁,那么它的两端分别是源(Source)和目标(Target),Binging是架 ...

  3. JZOJ2020年8月11日提高组反思

    JZOJ2020年8月11日提高组反思 T1 看到题 啊这?! 我看错了吗??? 我理解错题了吗?? 好吧没有-- 高精度模板题,不用多说 T2 看到这种矩阵的问题 以为是前缀和搞事情 结果呢 扫描线 ...

  4. keil/MDK代码配色

    个人配色方案,仅供参考.

  5. url的组成结构信息

    http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name 从上面的URL可以看出,一个完整的 ...

  6. JAVA环境安装及其配置

    一.JAVA版本的选择 我使用的是JAVA8,所以这次方法是JAVA8的安装过程. 这里我给出其下载地址,可以自行下载. 链接: https://pan.baidu.com/s/1k2Xydi6FJ2 ...

  7. Javascrip之BOM

    重点内容 理解windows对象-BOM核心 控制窗口.框架.弹出窗口 利用location对象中的页面信息 利用navigator对象了解浏览器 BOM:浏览器对象模型[Browner Object ...

  8. 使用T4模板动态生成NPoco实体类

    这是一个妥妥的NPoco类,这是我们在工作开发中,手动去写这个实体类,属实非常心累,字段少无所谓一次两次,数量多了,字段多了,就心态裂开

  9. javascript常用继承方式.

      //原型链继承 function Parent() { this.name = 'per'; } function Child() { this.age = 20; } Child.prototy ...

  10. datagrip2020最新安装破解教程方法激活码安装参数

    现在,datagrip的版本已更新至2020.3,尚未升级的用户请赶快升级. 本文教您如何安装datagrip2020.3版本并破解它. 此方法可以100%永久激活datagrip2020.3(低版本 ...