Redis专题(二)

1. Redis的简介

Redis支持多种数据结构,有广泛的业务应用场景。

数据保存在内存,读写性能高,很适合做缓存。

数据可以持久化到硬盘,可以做数据库来用。

官⽅对Redis的作⽤,也已经定位成了三个⽅⾯:Cache(缓存), Database(数据库),Vector Search(向量搜索)。

2. Redis到底是单线程还是多线程?

Redis对于客户端是多线程的,对于服务端是单线程的。

客户端的多线程是基于epoll的IO多路复用。epoll负责监听所有客户端的socket,当有数据可读或者可写的时候,会并行通知redis的主线程,哪些客户端准备就绪。

redis的主线程收到epoll的通知后,将对应的客户端请求放入事件队列。事件分发器将逐个从队列中取出请求,根据请求的时间类型分发到不同的时间处理器执行,并将结果放到输出缓冲区。

命令执行完后,对应的socket会被标记为可写。epoll监听到该状态,并行的将数据发回给客户端。

IO多路复用解决了线程的创建、销毁和上下文切换开销的问题。

事件处理流程(结合图中架构)

图片中间的架构图展示了请求的处理路径:

  1. 多路复用入口client1client4的请求(连接、GET、HSET、HGET)首先汇聚到 IO多路复用​ 层。这一层负责"监听"并收集所有就绪的客户端事件。

  2. 事件分发 :汇聚后的事件被送入 事件分发器

  3. 事件处理器:分发器将不同类型的事件分发给具体的处理器,如:

  • 连接应答处理器:处理新连接建立。
  • 命令请求处理器:读取并解析客户端发送的命令。
  • 命令回复处理器:将执行结果返回给客户端。

关键优势:串行化执行与免锁

Redis 高性能和易用性的关键:

  • 串行化执行 :虽然 Redis 同时接收很多请求,但它会将它们排成队,一个接一个地顺序执行

  • 免并发烦恼 :因为操作是单线程串行执行的,所以 Redis 完全不需要考虑​ 多线程下的脏读、幻读、不可重复读等并发问题。

  • 天然线程安全:你不需要像操作 MySQL 那样为了并发去加锁、考虑事务隔离级别。Redis 的命令执行本身就是原子性的(单个命令内)。

总结:Redis 通过 epoll 实现了高效的 IO 多路复用,使得单线程能够并发处理海量连接;同时,它采用串行化的命令执行方式,彻底规避了多线程并发控制的复杂性,从而实现了极高的性能和可靠性。

3. Redis如何保证指令原⼦性
  • 复合指令:一个指令干着多个指令的活。
  • Redis事务

Redis 的事务保证的是原子性 (命令要么全都不执行【EXEC命令执行之前出现语法/参数错误】,要么按顺序全部执行完,不会出现执行了一半的情况),但它不提供传统意义上的**数据恢复(Undo Log)**功能。如果遇到执行错误【EXEC命令执行之后出现运行时错误】,已经成功的部分不会撤销,这也是 Redis 强调"快"和"简单"的代价。

问题:EXEC执行后,事务中的指令会追加到AOP中,但是事务没有执行完,redis进程被kill'掉,导致数据不一致,redis重启失败。

解决方式:使⽤redis-check-aof⼯具修复AOF⽂件,将这些不完整的事务操作记录移除掉。这样下次服务就可以正常启动了。

  • Pipeline:将客户端的 多个指令打包,⼀起往服务端推送。
  • lua脚本

lua语言是单线程模型。配置Lua脚本的最⻓控制时间,若超时,返回BUSY,不会一直阻塞。

  • Redis Function

Redis Function允许将⼀些功能声明成⼀个统⼀的函数,提前加载到Redis服务端,客户端直接调用,实现Function的复用。

4.Redis性能压测

Redis提供了压测脚本redis-benchmark,可以对Redis进⾏快速的基准测试。

5.单机数据持久化

有四种持久化策略:

  • 无持久化:关闭持久化,把redis当缓存。
  • RDB:按照时间间隔的策略缓存Redis的快照。
  • AOF:记录Redis的每一次操作。通过重放 的方式恢复数据。
  • RDB+AOF:同时保存Redis的快照数据和操作,重启时,优先选AOF。

RDB的优点:

  • RDB文件是二进制文件,适合定期备份和容灾恢复。
  • RDB备份时性能好,不影响主进程。主进程启动一个子进程完成备份工作。
  • RDB进行大数据量重启时更快。

RDB缺点:

  • RDB备份不是实时备份,存在数据丢失。
  • 数据量太大,RDB备份容易造成Redis的短暂服务停止。

何时触发RDB备份:

  • 到达配置文件中配置的策略,会自动触发。
  • 手动save(阻塞主线程),bgsave(后台子线程运行,不会阻塞主线程)。
  • 主从复制触发RDB备份。

AOF优点:

  • AOF持久化更安全,当设置每秒进行一次AOF写入,最多丢失一秒的操作。
  • AOF时追加的操作,记录更完整。即使出现写入未完成Redis下线的等特殊情况,也能使用redis-check-aof修复。
  • AOF文件太大时,会自动切换新的日志文件,防止单个文件太大。
  • 即时有FLUSHALL误删数据的操作,也可以在AOF日志文件中将该指令删掉,重启redis来恢复数据。

AOF缺点:

  • 同样的数据库,AOF文件通常比RDB文件更大。
  • 写操作频繁的情况下,AOF备份的性能通常比RDB更慢。

持久化的使用建议:

  • 如果你只是把Redis当做⼀个缓存来⽤,可以直接关闭持久化。
  • 如果你更关注数据安全性,并且可以接受服务异常宕机时的小部分数据损失,那么可以简单的使用RDB策略。这样性能是⽐较⾼的。
  • 不建议单独使⽤AOF。RDB配合AOF,可以让数据恢复的过程更快。

因为Redis的持久化策略只保证单机的数据安全,为了进一步保证数据的安全,考虑集群化方案。

分布式优化方案:主从复制、哨兵集群、Redis集群。

6. 主从复制的工作流程

1》 Slave启动后,向master发送⼀个sync请求。等待建⽴成功后,slave会删除掉⾃⼰的数据⽇志⽂ 件,等待主节点同步。

2》master接收到slave的sync请求后,会触发⼀次RDB全量备份,同时收集所有接收到的修改数据 的指令。然后master将RDB和操作指令全量同步给slave。完成第⼀次全量同步。

3》主从关系建⽴后,master会定期向slave发送⼼跳包,确认slave的状态。⼼跳发送的间隔通过参 数repl-ping-replica-period指定。默认10秒。

4》只要slave定期向master回复⼼跳请求,master就会持续将后续收集到的修改数据的指令传递给 slave。同时,master会记录offset,即已经同步给slave的消息偏移量。

5》如果slave短暂不回复master的⼼跳请求,master就会停⽌向slave同步数据。直到slave重新上线 后,master从offset开始,继续向slave同步数据。

7. 哨兵集群的工作原理

Sentinel的核⼼⼯作原理分两个步骤,⼀是如何发现master服务宕机了。⼆是发现master服务宕机 后,如何切换新的master。

1》如何发现master服务宕机

每一个哨兵节点都会向主节点发送心跳,当超时没有收到心跳,就主观认为该主节点下线。为了避免网络等原因的误判,哨兵集群内部互相沟通,当超过quorum个哨兵节点认为主节点宕机,则客观认为主节点下线了,开始故障切换了。

2》发现master服务宕机后,如何切换新的master?

Sentinel会在剩余健康的Slave节点中选举出⼀个节点作为新的Master。 选举的规则如下:

  • ⾸先检查是否有提前配置的优先节点,如果⼤家的配置都⼀样,就进⼊下⼀个检查规则。
  • 然后检查复制偏移量offset最⼤的从节点。也就是找同步数据最快的slave节点。因为他的数据是最全的。如果⼤家的offset还是⼀样的,就进⼊下⼀个规则
  • 最后按照slave的RunID字典顺序最⼩的节点。

切换新的主节点。 Sentinel Leader给新的mater节点执⾏ slave of no one操作,将他提升为master节点。 然后给其他slave发送slave of 指令。让其他slave成为新Master的slave。

如果旧的master恢复了,Sentinel Leader会让旧的master降级为slave,并从新的master上同步数据,恢复⼯作。

8. Redis集群的选举流程

当从节点发现自己的主节点变成fail状态,会延迟一会,再尝试进⾏Failover,以期成为新的master。

延迟是为了避免主节点刚挂掉,其他主节点还没反应过来。

若从节点较多,就需要投票选举:

1) 发现故障

从节点(Slave)发现自己负责的主节点(Master)挂了(变为 FAIL 状态)。

2) 发起选举

它给自己记一个"年份"(Epoch)并加 1,然后向全集群广播。

3)获得认可

其他主节点收到请求,确认这个 Slave 合法且数据较新(通过 Rank 判断),就给它投一张赞成票(ACK)。

4)胜选上位

当这个 Slave 收集到的赞成票超过集群中主节点总数的一半时,它立刻升级为新的主节点。

5) 通知全网

新主节点广播 Pong 消息,通知其他集群节点。

相关推荐
tellmewhoisi12 小时前
多版本共用redis的token有效期校验(过期重新登录)
java·redis·缓存
Wzx19801213 小时前
Redis&ES——Retriever的抽象实现
数据库·人工智能·redis·elasticsearch
吴声子夜歌14 小时前
Redis 3.x——哨兵API
redis·sentinel
宠友信息19 小时前
Spring Boot与Redis ZSet实现仿小红书源码双列瀑布流推荐
java·大数据·前端·spring boot·redis·mysql·uni-app
梅头脑19 小时前
Redis 核心原理:为什么快?五种数据结构 + 持久化双引擎
redis
霸道流氓气质19 小时前
CodeBuddy中配置Redis MCP 连接与排错实战
数据库·redis·缓存
数行拙笔20 小时前
Redis---hash类型
数据库·redis·哈希算法
霸道流氓气质21 小时前
Kiro 中配置 Redis MCP Server 完整指南
数据库·redis·缓存
敲上瘾21 小时前
Linux系统调用mmap文件映射与malloc简单模拟实现指南
linux·服务器·c语言·缓存
wdfk_prog1 天前
嵌入式面试真题第 11 题:RTOS 优先级翻转与实时任务阻塞的通用治理
c语言·缓存·面试·职场和发展·架构