一.Redis持久化之RDB
Redis的RDB持久化机制是通过快照(snapshot)的形式将存储在内存中的数据以一定的时间间隔保存到硬盘上。以下是RDB持久化的具体流程:- 触发条件:RDB文件可以通过配置文件设置自动触发(例如,根据时间或修改次数),也可以手动通过命令SAVE或BGSAVE来触发。
- 开始持久化:当使用SAVE命令时,Redis会阻塞当前所有的客户端请求,直到RDB文件创建完成。这种方式不推荐在生产环境中使用,因为它会影响服务性能。使用BGSAVE命令时,Redis会派生(fork)出一个子进程来处理实际的持久化工作,而父进程继续处理客户端请求。这是更常用的持久化方法。
- 写入临时文件:子进程开始将数据库状态写入一个临时的RDB文件中。在此期间,Redis会记录所有新发生的写操作,但不会立即将它们加入到正在生成的RDB文件中。
- 写入完成:当子进程完成RDB文件的写入后,Redis会用这个新的RDB文件替换旧的RDB文件。
- 处理写操作缓冲:如果在持久化过程中有新的写操作发生,这些操作会被记录在一个缓冲区中,并且在下一次持久化时被考虑到。
rdb持久化默认保存的dump.rdb文件,也可以在配置文件中配置
为了测试一下,我们可以修改一下rdb的缓存策略,让其一分钟更改3次就持久化一次
测试
我们关机之后,再开机,测试数据是否完成保存:
我们可以发现由于内存关机即失的原理,所以内存中应当没有数据,但是有趣redis启动时会加载dump.rdb文件,最后就会重新数据,正常情况下关机也会持久化一次
但是也有极端情况,会导致宕机到上一次持久化之前的数据会丢失
rdb使用自己的一些命令规则保存的数据,而aof则是使用的存储命令
优点是大数据恢复速度很快,缺点是可能会有数据缺失的情况
二.Redis持久化之AOF
Redis的AOF(Append Only File)持久化机制通过记录服务器接收到的每个写操作命令到日志文件中,并在Redis重启时重新执行这些命令来恢复数据。
- 开启AOF:首先需要在Redis配置文件(redis.conf)中开启AOF功能,设置appendonly yes。
- 选择同步策略:Redis允许你配置何时将数据写入磁盘,这是通过设置appendfsync选项来实现的。你可以选择以下三种之一:always: 每次有新命令时都同步。这种方式最安全但性能消耗最大。everysec: 每秒同步一次。这是平衡性能和安全性的推荐设置。no: 不主动同步,让操作系统决定何时进行同步。这提供了最佳性能但降低了安全性。
- 命令追加到AOF文件:每当一个写命令到达Redis服务器,这个命令会被追加到AOF缓冲区中,随后根据上述配置的同步策略被写入到磁盘上的AOF文件。
- 重写过程(AOF Rewrite):随着Redis运行时间的增长,AOF文件会越来越大。为了避免AOF文件过大,Redis支持AOF重写。重写过程可以手动触发(BGREWRITEAOF命令)或自动触发(基于配置)。重写过程中,Redis会创建一个新的AOF文件,只包含重建当前数据集所需的最小命令集合,从而减少文件大小。
- 加载AOF文件:当Redis重启时,它会优先尝试使用AOF文件来恢复数据,因为AOF文件通常比RDB文件更完整。Redis读取AOF文件中的命令并逐一执行,以此来重建内存中的数据集。
默认aof是不开启的,因为它保存到是用户的更新命令,而且是追加模式,如果不断的增加Aof文件会非常大;但是在两种策略都开启的情况下,默认会使用aof恢复,rdb就会做备份校对,因为aof保存的原始命令使得其可以精准的构建出原始的数据结构。
默认保存的文件是appendonly.aof
三种持久化模式:每次命令都持久化,每秒都同步,不主动同步
更改允许aof持久化之后测试:
我们可以查看aof文件中的数据:
我们发现果然就是记录的命令,接着我们去毁坏里面的数据,看看重启会发生什么:
我们发现毁坏aof文件后启动不了redis了,但是发生这种情况先不要慌,因为redis官方给我们提供了一个组件专门用于修复:redis-check-aof
命令:
redis-check-aof --fix appendonly.aof
修复工具有好有坏,好处可以帮我们快速启动redis,坏处也很明显,可能存在丢失数据的情况
aof的存储文件会很大占用很多内存,并且运行也比rdb慢,故而redis默认的是rdb,但是相较来说aof可以做到只丢失一秒钟的交互数据,或者丢失,各有所长
RDB的优点
- 性能影响小:RDB通过快照的形式进行数据持久化,整个过程由子进程完成,因此对Redis服务器性能的影响较小。
- 恢复速度快:因为RDB文件是一个紧凑的二进制文件,所以加载速度较快,适合用于灾难恢复。
- 易于备份:RDB文件是某一时刻的数据快照,便于进行全量备份。
RDB的缺点
- 数据丢失风险:由于RDB是定时生成快照,因此在两次快照之间如果发生故障,则这段时间内的数据将会丢失。
- 高负载下的性能问题:创建RDB文件时,特别是在数据集非常大的情况下,可能会导致Redis短暂地停止服务(尤其是在使用SAVE而非BGSAVE命令时)。
AOF的优点
- 更高的数据安全性:AOF记录了每个写操作,因此即使发生故障也能最大程度地减少数据丢失。
- 灵活的同步策略:可以根据实际需求选择不同的fsync策略(always, everysec, no),以平衡数据安全性和性能。
- 日志可读性:AOF文件本质上是一系列Redis命令,人类可读,便于调试和修复。
AOF的缺点
- 文件体积大:由于记录了所有的写操作,AOF文件通常比RDB文件大得多。
- 恢复时间较长:因为需要重新执行所有的写命令来恢复数据集,所以在数据量较大时,恢复时间可能较长。
- 性能消耗:尽管有多种同步策略可供选择,但在某些配置下(如always),会对性能产生显著影响。
三.Redis订阅发布
Redis的发布/订阅(Pub/Sub)是一种消息通信模式,它允许消息发送者(发布者)通过频道(Channel)发送消息,而不需要知道谁是接收者。同样地,接收者(订阅者)可以订阅一个或多个频道来接收消息,而不需要知道是谁发送了这些消息。这种模式实现了发布者和订阅者之间的解耦,使得系统更加灵活和可扩展
在Redis中,发布/订阅功能主要依赖于以下命令:
PUBLISH channel message
:将消息发布到指定的频道。SUBSCRIBE channel [channel ...]
:订阅给定的一个或多个频道。PSUBSCRIBE pattern [pattern ...]
:订阅符合给定模式的一个或多个频道。模式支持通配符,如news.*
会匹配所有以news.
开头的频道。UNSUBSCRIBE [channel [channel ...]]
:停止接收指定频道的消息。如果没有参数,则取消当前所有频道的订阅。PUNSUBSCRIBE [pattern [pattern ...]]
:停止接收符合指定模式的所有频道的消息。
订阅一个消息号SUBSCRIBE:
SUBSCRIBE users
发布一个订阅信息:
PUBLISH users hello,world
Redis维护了一个全局的字典,字典的键是频道名,值是一个链表,链表中存储了所有订阅该频道的客户端对象。
对于模式匹配订阅,Redis还有一个独立的字典,其键是模式,值是一个链表,链表中存储了所有订阅该模式的客户端对象。
消息发布:
当执行PUBLISH channel message命令时,Redis首先查找订阅了指定频道的所有客户端列表。然后,Redis遍历这个列表,并将消息发送给每个订阅者。如果有模式匹配订阅也符合当前频道,则相应的客户端也会接收到消息。
订阅操作:
当执行SUBSCRIBE channel [channel ...]命令时,Redis会在上述提到的全局字典中添加对应的客户端对象到指定频道的订阅者列表中。对于PSUBSCRIBE pattern [pattern ...]命令,Redis则在模式匹配的字典中添加客户端对象到相应模式的订阅者列表中。