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 消息,通知其他集群节点。

相关推荐
只爱喝胡辣汤17 分钟前
Redis Intset(整数集合)技术文档
redis
01传说1 小时前
redis开机自启脚本
数据库·redis·缓存
只爱喝胡辣汤3 小时前
Redis SDS(Simple Dynamic String)技术文档
redis
只爱喝胡辣汤3 小时前
Redis Dict(字典/哈希表)技术文档
redis
就叫_这个吧5 小时前
RabbitMQ+elasticsearch+Redis,实现新增内容并异步到es中,是否消费成功检测
redis·elasticsearch·rabbitmq
李可以量化5 小时前
Redis Client 从了解到精通(二)下:String 类型进阶操作全解
redis·git·python·量化交易·qmt
BUG研究员_7 小时前
LangChain 向量数据库实战:Redis 与 Pinecone 的知识点总结
数据库·redis·langchain
李可以量化8 小时前
Redis Client 从了解到精通(二)上:redis-py 高级用法与核心命令实战
前端·数据库·redis·python·缓存·ptrade
仍然.8 小时前
Redis---String
数据库·redis·缓存
JavaPub-rodert8 小时前
Redis 和 MySQL 如何保证数据一致性?从缓存更新到延迟双删完整讲解
redis·mysql·缓存