阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的( 三 )


BLPOP key [key …] timeout:阻塞直到队列有消息或者超时 。

阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的

文章插图
 

阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的

文章插图
 

阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的

文章插图
 
缺点:按照此种方法,我们生产后的数据只能提供给各个单一消费者消费 。能否实现生产一次就能让多个消费者消费呢?
③Pub/Sub:主题订阅者模式
发送者(Pub)发送消息,订阅者(Sub)接收消息 。订阅者可以订阅任意数量的频道 。
阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的

文章插图
 
Pub/Sub模式的缺点:消息的发布是无状态的,无法保证可达 。对于发布者来说,消息是“即发即失”的 。
此时如果某个消费者在生产者发布消息时下线,重新上线之后,是无法接收该消息的,要解决该问题需要使用专业的消息队列,如 Kafka…此处不再赘述 。
Redis 持久化
什么是持久化
持久化,即将数据持久存储,而不因断电或其他各种复杂外部环境影响数据的完整性 。
由于 Redis 将数据存储在内存而不是磁盘中,所以内存一旦断电,Redis 中存储的数据也随即消失,这往往是用户不期望的,所以 Redis 有持久化机制来保证数据的安全性 。
Redis 如何做持久化
Redis 目前有两种持久化方式,即 RDB 和 AOF,RDB 是通过保存某个时间点的全量数据快照实现数据的持久化,当恢复数据时,直接通过 RDB 文件中的快照,将数据恢复 。
RDB(快照)持久化
RDB持久化会在某个特定的间隔保存那个时间点的全量数据的快照 。
RDB 配置文件,redis.conf:
save 900 1 #在900s内如果有1条数据被写入,则产生一次快照 。save 300 10 #在300s内如果有10条数据被写入,则产生一次快照 save 60 10000 #在60s内如果有10000条数据被写入,则产生一次快照 stop-writes-on-bgsave-error yes #stop-writes-on-bgsave-error : 如果为yes则表示,当备份进程出错的时候,主进程就停止进行接受新的写入操作,这样是为了保护持久化的数据一致性的问题 。
①RDB 的创建与载入
SAVE:阻塞 Redis 的服务器进程,直到 RDB 文件被创建完毕 。SAVE 命令很少被使用,因为其会阻塞主线程来保证快照的写入,由于 Redis 是使用一个主线程来接收所有客户端请求,这样会阻塞所有客户端请求 。
BGSAVE:该指令会 Fork 出一个子进程来创建 RDB 文件,不阻塞服务器进程,子进程接收请求并创建 RDB 快照,父进程继续接收客户端的请求 。
子进程在完成文件的创建时会向父进程发送信号,父进程在接收客户端请求的过程中,在一定的时间间隔通过轮询来接收子进程的信号 。
我们也可以通过使用 lastsave 指令来查看 BGSAVE 是否执行成功,lastsave 可以返回最后一次执行成功 BGSAVE 的时间 。
②自动化触发 RDB 持久化的方式
自动化触发RDB持久化的方式如下:
  • 根据 redis.conf 配置里的 SAVE m n 定时触发(实际上使用的是 BGSAVE) 。
  • 主从复制时,主节点自动触发 。
  • 执行 Debug Reload 。
  • 执行 Shutdown 且没有开启 AOF 持久化 。
③BGSAVE 的原理
阿里P9架构师分享:通俗易懂Redis原理,都是你没看过的

文章插图
 
启动:
  • 检查是否存在子进程正在执行 AOF 或者 RDB 的持久化任务 。如果有则返回 false 。
  • 调用 Redis 源码中的 rdbSaveBackground 方法,方法中执行 fork() 产生子进程执行 RDB 操作 。
  • 关于 fork() 中的 Copy-On-Write 。
fork() 在 linux 中创建子进程采用 Copy-On-Write(写时拷贝技术),即如果有多个调用者同时要求相同资源(如内存或磁盘上的数据存储) 。
他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给调用者,而其他调用者所见到的最初的资源仍然保持不变 。
④RDB 持久化方式的缺点
RDB 持久化方式的缺点如下:
  • 内存数据全量同步,数据量大的状况下,会由于 I/O 而严重影响性能 。
  • 可能会因为 Redis 宕机而丢失从当前至最近一次快照期间的数据 。
AOF 持久化:保存写状态
AOF 持久化是通过保存 Redis 的写状态来记录数据库的 。
相对 RDB 来说,RDB 持久化是通过备份数据库的状态来记录数据库,而 AOF 持久化是备份数据库接收到的指令:


推荐阅读