Redis
子知识库
文章
01 Redis概述
Redis概述1 概述Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射。 键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。 Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能,使用分片来扩展写性能。 优势使用Redis有哪些好处? 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) 支持丰富数据类型,支持string,list,set,sorted set,hash 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除 2 Redis 与 Memcached两者都是非关系型内存键值数据库,主要有以下不同: 数据类型。 Memcached 仅支持字符串类型, Redis 支持五种不同的数据类型,可以更灵活地解决问题。 数据持久化。 Redis 支持两种持久化策略:RDB 快照和 AOF 日志...
02 对象类型
数据类型 数据类型 0 数据类型 对象说明 对象代码实现 对象编码encoding 对象类型type 1 字符串对象STRING 字符串实现 编码的转换 字符串命令 2 列表对象LIST 列表实现 编码转换 列表命令 3 哈希对象HASH 哈希实现 编码转换 哈希命令 4 集合对象SET 集合实现 编码的转换 集合命令 5 有序集合的对象ZSET 编码的转换 有序集合命令 6 类型检查与命令多态 7 内存回收 8 对象共享 9 对象的空转时长 0 数据类型关于数据类型的说明。从C++标准库的角度来说,实现的数据结构主要可以如下方式进行划分 线性数据结构 vector(数组) list(链表) deque(双端队列) 非线性数据结构 set(集合) set红黑树实现的有序set unordered_set哈希实现的无序的set map(映射map、字典dict、哈希hash) map红黑树实现的有序map unordered_set哈希实现的无序的map 扩展数据结构 stack(栈) queue(队列) priority_queue...
03 数据结构
底层数据结构 参考文献 底层数据结构 底层数据结构 1 动态字符串SDS SDS 代码实现 SDS 特点(与C字符串的不同) SDS API 2 链表 双向链表 代码实现 链表 特点 链表 API 3 字典 字典的实现 哈希算法 解决键冲突 Rehash 哈希表的扩展与收缩 渐进式rehash 字典API 4 跳表 跳表 代码实现 跳表使用 跳跃表API 5 整数集合——特殊情况 整数集合的实现 升级 升级的好处 降级 整数集合API 6 压缩列表——特殊情况 压缩列表的构成 压缩列表节点的构成 连锁更新 压缩列表API 1 动态字符串SDSRedis构建了 简单动态字符串(simple dynamic string,SDS)来表示字符串值。 SDS还被用作缓冲区:AOF缓冲区,客户端状态中的输入缓冲区。 SDS 代码实现每个sds.h/sdshdr结构表示一个SDS值: 1234567891011struct sdshdr { // 记录buf数组中已使用字节的数量 // 等于SDS所保存字符串的长度 int le...
04 数据库
数据库1 数据库的实现服务器数据库Redis服务器负责与多个客户端建立连接,处理客户端的命令请求,在数据库中保存命令产生的数据,并通过资源管理来维持服务器自身的运转。 Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,数组的每个项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库: 12345678910struct redisServer { // ... redisDb *db; int dbnum; // 数据库的数量 // ... list *clients; redisClient *lua_client; // Lua伪客户端,服务器运行时一直存在 // ... // ...}; 其中dbnum的值有服务器配置的database选项决定,默认为16。 redisServer结构保存了一个clients链表,保存了所有连接的客户端的状态信息。 客户端数据库默认情况下,Redis客户端的目标数据库是0号数据库,客户端可以执行SE...
05 生命周期
生命周期1 数据库键生命周期概述Redis 可以为每个键设置过期时间,当键过期时,会自动删除该键。 对于散列表这种容器,只能为整个键设置过期时间(整个散列表),而不能为键里面的单个元素设置过期时间。 设置键的生存时间或过期时间EXPIRE或PEXPIRE命令让客户端可以以秒或者毫秒进度为某个键设置生存时间。经过指定的时间后,服务器会自动删除生存时间为0的键。 EXPIREAT或PEXPIREAT命令,以秒或毫秒精度为某个键设置过期时间,过期时间是一个UNIX时间戳。 TTL和PTTL命令可查看某个键的剩余生存时间。 实际上,EXPIRE、PEXPIRE、EXPIREAT三个命令都是使用PEXPIREAT来实现的。 保存过期时间redisDb结构的expires字典保存了所有键的过期时间: 过期字典的键是一个指针,指向键空间中的某个键对象。 过期字典的值是一个long long类型的整数,保存了一个UNIX时间戳。 12345typedef struct redisDb { // ... dict *expires; // ...} redisDb; ...
06 RDB持久化
RDB持久化1 RDB持久化方法概念RDB持久化可将内存中的数据库状态保存到磁盘上,避免数据丢失。持久化可以手动,也可以根据服务器配置选项定期执行。 RDB持久化生成的RDB文件是一个压缩过的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态。 RDB文件的创建与载入有两个命令可以生成RDB文件: SAVE。该命令会阻塞Redis服务器进程,直到RDB文件创建完毕,期间拒绝任何命令请求。 BGSAVE。派生出一个子进程来创建RDB文件,服务器进程(父进程)继续处理命令请求。 在BGSAVE命令执行期间,服务器处理SAVE、GBSAVE、BGREWRITEAOF命令会被拒绝执行。 创建RDB文件的操作由rdb.c/rdbSave函数完成。RDB文件的载入工作在服务器启动时自动执行。另外,AOF文件的更新频率比RDB文件要高,所以: 如果服务器开启了AOF,那么优先用AOF来还原数据库。 只有在AOF关闭时,服务器才会用RDB来还原数据库。 载入RDB文件的工作由rdb.c/rdbLoad函数完成。载入RDB文件期间,服务器一直处于阻塞状态。 2 自动间隔性保存R...
07 AOF持久化
AOF持久化1 AOF持久化方法概念AOF(Append Only File)持久化,与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF保存Redis所执行的写命令来记录数据库状态。被写入AOF文件的命令都是以Redis的命令请求协议格式保存的,纯文本格式,打开即可查看。 AOF持久化的实现三个步骤。 命令追加(append)、 文件写入、 文件同步(sync) 命令追加如果打开AOF功能,服务器在执行完一个写命令后,会以协议格式将被执行的命令追加到服务器状态的aof_buf缓冲区的末尾。 12345struct redisServer { // ... sds aof_buf; // ...}; 文件写入与同步Redis的服务器进程就是一个事件循环(loop),这个循环中的文件事件负责接受客户端的请求,并向客户端发送回复,而时间事件则负责执行像serverCron函数这样的定时任务。 服务器在处理文件任务时可能会执行写命令,追加内容到aof_buf缓冲区,所以服务器在每次结束一个事件循环前,都会调用flushAppendOnlyF...
08 事务
事务1 事务简介Redis通过MULTI、EXEC、WATCH等命令实现事务(transaction)功能。事务提供一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制。在事务执行期间,服务器不会中断事务去执行其他客户端的命令请求。 事务以MULTI开始,接着是多个命令放入事务之中,最后由EXEC将这个事务提交(commit)到服务器执行。 一个事务包含了多个命令,服务器在执行事务期间,不会改去执行其它客户端的命令请求。 事务中的多个命令被一次性发送给服务器,而不是一条一条发送,这种方式被称为流水线,它可以减少客户端与服务器之间的网络通信次数从而提升性能。 Redis 最简单的事务实现方式是使用 MULTI 和 EXEC 命令将事务操作包围起来。 事务队列每个Redis客户端都有自己的事务状态,保存在客户端状态的mstate属性中: 12345678910111213141516171819202122typedef struct redisClient { multiState mstate;} redisClient;typedef struct...
09 事件与并发
事件0 概述Redis服务器是一个事件驱动程序,需要处理以下两类事件: 文件事件(file event):Redis服务器通过socket与客户端连接,文件事件就是对套接字操作的对象。服务器与客户端的通信会产生相应的文件事件,服务器监听并处理这些事件来完成一系列的网络通信操作。 时间事件(time event):Redis服务器的一些操作(如serverCron函数)需要在特定时间点执行,时间事件就是对这类定时任务的抽象。 1 文件事件原理Redis基于Reactor模式开发了自己的网络事件处理器,称为文件事件处理器,文件事件处理器以单线程方式运行。 Redis 基于Reactor 模式开发了自己的网络事件处理器,使用 I/O 多路复用程序来同时监听多个套接字,并将到达的事件传送给文件事件分派器,分派器会根据套接字产生的事件类型调用相应的事件处理器。 文件事件处理器的四个组成部分: 套接字。当被监听的套接字准备好执行accept、read、write、close等操作时,与操作相对应的文件事件就会产生。 I/O多路复用程序。使用I/O多路复用...
10 复制
复制0 概述Redis中,用户可以执行saveof命令或设置saveof选项,让一个服务器去复制(replicate)另一个服务器。被复制的服务器叫做master,对master进行复制的服务器叫做slave。 进行复制中的master和slave应该保存相同的数据,这称作“数据库状态一致”。 一个从服务器只能有一个主服务器,并且不支持主主复制。 1 旧版复制功能的实现Redis的复制功能分为同步(sync)和命令传播(command propagate)两个操作: 同步用于将slave的数据库状态更新至master当前所处的数据库状态。 命令传播用于master的数据块状态被修改,导致和lsave的数据库状态不一致时,让两者的数据库重回一致状态。 同步复制开始时,slave会先执行同步操作,步骤如下: slave对master发送SYNC命令 master收到SYNC执行BGSAVE,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。 master的BGSAVE执行完毕后,将生成的RDB文件发送给slave,slave接收并载入这个RDB,更新自己...














