本文的分析都是基于 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. LeetCode 039 Combination Sum

    题目要求:Combination Sum Given a set of candidate numbers (C) and a target number (T), find all unique c ...

  2. FPGA 流水灯

    VerilogHDL那些事儿_建模篇(黑金FPGA开发板配套教程) 作者:akuei2 说明:参照该书将部分程序验证学习一遍 学习时间:2014年5月2号 主要收获: 1. 对FPGA有初步了解: 2 ...

  3. 02_启动和销毁Service

    在Application关闭后,Service仍然会运行. package com.example.servdemo; import android.app.Activity; import andr ...

  4. Spring Cloud 学习 (五) Zuul

    Zuul 作为路由网关组件,在微服务架构中有着非常重要的作用,主要体现在以下 6 个方面: Zuul, Ribbon 以及 Eureka 相结合,可以实现智能路由和负载均衡的功能,Zuul 能够将请求 ...

  5. 关闭Win10窗口拖动到桌面边缘自动缩放功能

  6. 【C++】“反转链表”相关的题目

    1.反转链表:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点. (1)这道题是经典的题目了,用迭代的方式解决也是很容易的,代码量也不大.分享一个我个人做题的方式,我会先在题目开 ...

  7. day6(celery原理与组件)

    1.Celery介绍 1.1 celery应用举例 Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理,如果你的业务场景中需要用到异步任务,就可以考 ...

  8. 第十二章 Python标准库内置模块和包简介

    在<第十章 Python的模块和包>老猿详细介绍了Python模块和包的相关概念,模块和包是Python功能扩展的重要手段,也是Python开放的重要特征.为了提供强大的能力,Python ...

  9. java试用静态图片制作gif

    参考博客:https://www.cnblogs.com/dreammyle/p/4843365.html 代码中需要的依赖: <!-- gif --> <dependency> ...

  10. Json处理方式记录

    1.可以直接使用Parse方法 JObject jObject = JObject.Parse(res); string mediaId = jObject["media_id"] ...