REDIS

本文深入解析Redis内存数据库结构,包括数据库、客户端、订阅发布系统及事务处理。探讨过期策略、RDB与AOF持久化机制,事件处理流程,复制与Sentinel高可用方案,以及集群与发布订阅功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、内存数据库结构

struct redisServer {
//一个数组,保存着服务器中的所有数据库
redisDB *db;
int dbnum;
//记录了保存条件的数组
saveparam *saveparams;
//AOF缓冲区··
sds aof_buf;
list *clients;
//保存所有频道的订阅者
dict *pubsub_channels;
//保存着所有模式订阅关系
list *pubsub_patterns;
}

struct redisDb {
//数据库键空间,保存着数据库中的所有键值对
dict *dict;
}

struct saveparam {
time_t seconds;
int changes;
}

struct redisClient {
int fd;
//事务状态
multiState mstate;
}
struct multiState {
// 事务队列,FIFI顺序
multiCmd *commands;
// 已入队命令计数
int count;
}
struct multiCmd{
// 参数
robj **argv;
int argc;
struct redisCommand *cmd;
}

strct pubsubPattern {
//订阅模式的客户端
redisClient *client;
robj *pattern;
}

1)设置数据
redis > SET message “hello world”
redis > RPUSH alphabet “a” “b” “c” //队列(也叫列表),可重复
redis > SADD SADD bbs “tianya.cn” “groups.google.com” //集合,无序不可重复
redis > HSET book name “Redis in Action”
redis > HSET book author “Josiah L. Carlson”
redis > HSET book publisher “Manning”
2)获取数据
redis > GET message
redis > LRANGE alphabet 0 -1

二、过期删除策略

理论上有三种删除策略,定时删除,定期删除,惰性删除。
由于定时删除的CPU压力过大,所以采用定期删除+惰性删除的过期删除策略

三、Redis持久化机制

1.RDB持久化
1)RDB持久化方式
i.命令持久化:
redis > SAVE //等待直到RDB文件生成完毕
redis > BGSAVE //派生子进程,并由子进程创建RDB文件
ii.自动间隔性保存
save 900 1
save 300 10
save 60 10000
只要满足以下三个条件中的任意一个,BGSAVE命令就会被执行:

  • 服务器在900秒之内,对数据库进行了至少1次修改。
  • 服务器在300秒之内,对数据库进行了至少10次修改。
  • 服务器在60秒之内,对数据库进行了至少10000次修改。
    2)RDB文件结构
    |REDIS| db_version| SELECTDB|0| pairs| SELECTDB|3| pairs|EOF|check_sum|

2.AOF持久化
RDB持久化保存数据库状态的方法是将键值对的数据存放到RDB文件中,被写入到AOF文件中的所有命令都是以Redis的命令请求协议格式保存的。AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync )三个步骤。
1)命令追加
举个列子,如果客户端向服务器发送以下命令:
redis > SET KEY Value
那么服务器在执行这个SET命令之后,会将以下协议内容追加到aof_buf缓冲区的末尾
2)AOF文件的写入与同步
def eventLoop();
while True:
processFileEvents();
processTimeEvents();
# 考虑是否要将aof_buf中的内容写入和保存到AOF文件里面,由appendfsync参数配置
flushAppendOnlyFile();
appendfsync:
- always:将aof_buf缓冲区中的多有内容写入并同步到AOF文件中
- everysec:将aof_buf写入到AOF文件中,如果上次同步时间距离现在超过一秒钟,那么对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的
- no:将aof_buf缓冲的所有内容写入到AOF文件,单并不对AOF文件进行同步,由操作系统来决定何时同步
3)AOF文件重写的实现
如果AOF文件不重写,AOF会越来越大因为存在冗余的命令,这样就需要针对Redis的数据进行重新生成一份AOF文件。

四、事件

1、文件事件
用多路复用的IO实现与客户端的交互。
2、时间事件
服务器将所有时间事件都放在一个无序列表中,每当时间事件执行执行器运行时,他就遍历整个链表,查找所有已到达的时间事件,并调用相应的时间处理器。

五、复制

PSYNC命令具有完整重同步和部分重同步两种模式:

  1. 其中完整重同步:用于处理初次复制的情况:通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步。
  2. 部分重同步:用于处理断线后重复制的情况
  3. 当完成同步之后,主服务器就会进入命令传播阶段,这时主服务器只要将自己执行的写命令发送给从服务器,而从服务器只要一直接收并执行主服务器的写命令,就可以保证主从服务器一直保持一致了。

五、Sentinel

Sentinel是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器。

六、集群

七、发布订阅

Redis的发布订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。
1、频道的订阅与退订

pubsub_channels
"news.it" -> client-1 -> client-2
"news.sport" -> client-4

2、模式的订阅与退订

redisServer
   ...
   pubsub_patterns  ->   pubsubPattern
                         client-7
                         "music.*"
   ...

3、发送消息
当一个Redis客户端执行PUBLISH 命令将消息message发送给频道channel的时候,服务器将执行以下两个动作:
1)将消息message发送给channel的所有订阅者
2)如果有一个或多个pattern与频道channel相匹配,那么将消息message发送给pattern模式的订阅者。

八、事务

Redis通过MULTI、EXEC、WATCH等命令实现事务功能
1、事务举例
redis > MULTI
OK

redis > SET “name” “Practical Common Lisp”
QUEUED

redis > GET “name”
QUEUED

redis > SET “author” “Peter Seibel”
QUEUED

redis > EXEC
1)OK
2)“Practical Common Lisp”
3)OK
4)“Peter Seibel”
2、乐观锁
c10086 > WATCH “name”
OK

watched_keys
"name"  -> c1 -> c2 -> c10086
"age" -> c3
"address" -> c2 ->c4

c10086 MULTI
OK

c10086 SET “NAME” “peter”
QUEUED

接下去另外一个客户端执行命令
c999 > SET “name” “john”
OK
c999执行这个命令以后会导致正在监视"name"键的所有客户端的REDIS_DIRTY_CAS标识被打开,其中包括客户端c10086

接下去执行事务时发现REDIS_DIRTY_CAS被打开,所以服务器将拒绝执行他提交的事务
c10086 > EXEC
(nil)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值