Redis 设计与实现:Redis 对象
本文的分析都是基于 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 对象的更多相关文章
- Redis设计与实现
简述Redis设计与实现 Redis是一个高性能的key-value的非关系型数据库,Redis是运行在内存中的一种数据库,但是它也可以持久化到磁盘中,Redis的实现有着更为复杂的数据结构并且提供对 ...
- 如何使用redis设计关系数据库
目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...
- Redis | 第一部分:数据结构与对象 上篇《Redis设计与实现》
目录 前言 1. 简单动态字符串 1.1 SDS的定义 1.2 空间预分配与惰性空间释放 1.3 SDS的API 2. 链表 2.1 链表与节点的定义 2.2 链表的API 3. 字典 3.1 哈希表 ...
- Redis | 第一部分:数据结构与对象 下篇《Redis设计与实现》
目录 前言 1. Redis对象概述 1.1 对象的定义 2. 字符串对象 3. 列表对象 3.1 quicklist 快速链表 4. 哈希对象 5. 集合对象 6. 有序集合对象 7. Redis对 ...
- Redis | 第一部分:数据结构与对象 中篇《Redis设计与实现》
目录 前言 1. 跳跃表 1.1 跳跃表与其节点的定义 1.2 跳跃表的API 2. 整数集合 2.1 整数集合的实现 2.2 整数集合的类型升级 2.3 整数集合的API 3. 压缩列表 3.1 压 ...
- Redis设计与实现(一~五整合版)【搬运】
Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...
- Redis设计与实现-内部数据结构篇
题记:这本书是2015年11月份开始读的,大约花了一个多月的时间通读了一遍,最近由于需要对redis做一些深入的了解,因此又花了两个多月仔细精读了一遍,由于本书设计的内容较多,且每部分的内容都比较细致 ...
- Redis笔记(1)数据结构与对象
1.前言 此系列博客记录redis设计与实现一书的笔记,提取书本中的知识点,省略相关说明,方便查阅. 2.基本数据结构 2.1 简单动态字符串SDS(simple dynamic string) 结构 ...
- 《Redis设计与实现》
<Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...
- 180713-Spring之借助Redis设计访问计数器之扩展篇
之前写了一篇博文,简单的介绍了下如何利用Redis配合Spring搭建一个web的访问计数器,之前的内容比较初级,现在考虑对其进行扩展,新增访问者记录 记录当前站点的总访问人数(根据Ip或则设备号) ...
随机推荐
- 怎样安装Arch Linux以及Deepin桌面环境
一.概述 Arch Linux 是一个轻量级的Linux发行版本,实际上,Arch Linux提供给用户很多选择,用户可以自定义自己的安装过程,不x像其他很多的Linux发行版本,安装过程甚至是一个只 ...
- 心跳event
在通过sessionID和passwd获取会话的时候会使原会话断开,后续的事件都变为disconnected,且zk会不断发送disconnected给原连接,connected给新连接
- Java多线程中的虚假唤醒和如何避免
先来看一个例子 一个卖面的面馆,有一个做面的厨师和一个吃面的食客,需要保证,厨师做一碗面,食客吃一碗面,不能一次性多做几碗面,更不能没有面的时候吃面:按照上述操作,进行十轮做面吃面的操作. 用代码说话 ...
- 音视频入门-18-手动生成一张GIF图片
* 音视频入门文章目录 * GIF 编码知识 GIF 包含的数据块: 文件头(Header) 逻辑屏幕标识符(Logical Screen Descriptor) 全局颜色表(Global Color ...
- Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?
Python中使用百分号占位符的字符串格式化方法中%s和%r表示需要显示的数据对应变量x会以str(x)还是repr(x)输出内容展示. 关于str和repr的关系请见: <Python中rep ...
- PyQt学习随笔:QTableWidget的selectedRanges、setRangeSelected访问选中矩形范围的方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在QTableWidget对项的操作支持选中多个项的情况下,可以通过方法selectedRanges ...
- PyQt(Python+Qt)学习随笔:Qt Designer中的menu菜单及menu bar菜单栏
菜单由menu bar菜单栏和menu菜单两部分构成,分别对应类QMenuBar和QMenu. menuBar是包含一系列下拉菜单项组成,menu包含两种,一种是直接对应Action的,一种是父菜单, ...
- Project Lombok——带给你简洁、清晰的代码
相信但凡有一点Java编程经历的人,都见过或者写过下面这种代码.这是一个简单的POJO,只有4个fields,加上构造器.equals.hash.toString以及各种getter setter,前 ...
- Java集合源码分析(三)——LinkedList
简介 LinkedList是一个链表结构的列表,也可以被作为堆栈.队列或双端队列使用.它继承于AbstractSequentialList双向链表,实现了List.Deque.Cloneable.ja ...
- 廖雪峰官网学习js 数据类型和变量
数据类型: number 不分整数 和浮点数 字符串 用' ' " " 表示 布尔值 true false && 与运算符(都ture才ture ...