本文的分析都是基于 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. dubbo协议之响应头编码器&响应对象编码

    前2节分析完了请求头和请求对象的编码,这里看一下响应头和响应对象的编码: 和请求头部一样进来先指定序列化器,没有的话用默认的Hessian2,接下来2个字节的操作和请求头编码类似,第三个字节时去req ...

  2. LaTeX中的插图

    插图代码及注释: 显示效果: 更多命令可以看相关文档,通过在命令行终端输入 texdoc graphicx 命令打开文档.

  3. 关于深度学习之中Batch Size的一点理解(待更新)

    batch 概念:训练时候一批一批的进行正向推导和反向传播.一批计算一次loss mini batch:不去计算这个batch下所有的iter,仅计算一部分iter的loss平均值代替所有的. 以下来 ...

  4. 虚拟机VM15 Ubuntu18.04写第一个c程序并实现ssh连接

    输入"su",再输入密码进入根用户 1.开启ssh服务 /etc/init.d/ssh start 若没有安装会出现: (1).安装ssh apt-get install open ...

  5. java46

    1.迭代器遍历 import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public c ...

  6. IntelliJ IDEA 2020.3正式发布,年度最后一个版本很讲武德

    仰不愧天,俯不愧人,内不愧心.关注公众号[BAT的乌托邦],有Spring技术栈.MyBatis.JVM.中间件等小而美的原创专栏供以免费学习.分享.成长,拒绝浅尝辄止.本文已被 https://ww ...

  7. Spring Cloud Alibaba 初体验(四) Sentinel

    一.Sentinel 下载与运行 本文使用 Sentinel 1.7.1:https://github.com/alibaba/Sentinel/releases 使用自定义端口 8089 运行 Se ...

  8. 洛谷P3906 Hoof Paper, Scissor (记忆化搜索)

    这道题问的是石头剪刀布的的出题问题 首先不难看出这是个dp题 其次这道题的状态也很好确定,之前输赢与之后无关,确定三个状态:当前位置,当前手势,当前剩余次数,所以对于剪刀,要么出石头+1分用一次机会, ...

  9. 老猿学5G随笔:5G网元功能体NF以及NF之间的两种接口--服务化接口和参考点

    一.5G功能体之间的接口类型 5G不同功能体之间提供了两种接口: 服务化接口:Service-basedinterface,这个是类似微服务化架构的服务注册和服务发现来实现的功能体对外暴露的接口,这种 ...

  10. 第11.16节 Python正则元字符“()”(小括号)与组(group)匹配模式

    一. 什么是组 关于组匹配模式,Python官网上说得比较简单,也没有这个名词,只有组这个名词,老猿查了比较多的资料和做了相关测试之后才理解. 组匹配模式,就是在匹配的正则表达式中使用小括号" ...