Redis系列四 | 持久化和发布订阅

Redis提供RDB和AOF两种持久化方式,RDB通过快照实现,适合大规模数据恢复但可能丢失最近修改;AOF记录每次操作,保证数据完整性,但文件大,恢复慢。Redis的发布订阅机制允许发送者发布消息,订阅者接收,适用于实时消息系统和聊天应用。
摘要由CSDN通过智能技术生成

1.8 Redis持久化

Redis是内存数据库,如果不将内存中的数据库状态保存到硬盘中,那么一旦服务器进程退出,服务器中的数据状态也会消失,所以Redis提供了持久化功能

1.8.1 RDB(Redis DataBase)

RDB

在指定的时间间隔内,将内存中的数据集体快照写入磁盘中,也就是进行Snapshot快照,它恢复时是将快照文件直接读到内存里。

操作

单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程不进行任何IO操作。这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高校。RDB的缺点是嘴鸥一次持久化后的数据可能丢失。我们默认的就是RDB,一般情况下不需要修改此配置!

rdb保存的文件是dump.rdb

image-20211211214237695

image-20211211214658639

# 触发机制
1.save的规则满足的情况下
2.执行了FLUSHALL命令
3.退出redis也会触发

如何恢复rdb文件

  1. 只需要将rdb文件放在redis启动目录下即可,启动的时候会自动检查dump.rdb恢复其中的数据
# 查看存放的位置
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"

优缺点

优点

  1. 适合大规模的数据恢复
  2. 如果你对数据的完整性要求不高

缺点

  1. 需要一定的时间间隔进行操作!如果redis意外宕机,最后一次修改的数据就没有了
  2. fork进程的时候,会占用一定的内存空间

1.8.2 AOF(Append Only File)

将我们的所有命令都记录下来,history,恢复的时候就把这个文件全部执行一遍

AOF

以日志的形式来记录每个操作,将redis执行过的所有指令记录下来(读操作不会记录),只许追加文件但不可改写文件,redis启动之后会读取文件重新构建数据,换言之,redis重启的话根据日志文件的内容将写指令从前到 后执行一次以完成数据的恢复工作

aof保存的文件是appendonly.aof文件

image-20211212083202539

# 破坏aof文件后,尝试连接
[root@yunmx bin]# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
# 使用检测文件自动修复这个AOF文件:redis-check-aof
[root@yunmx bin]# redis-check-aof --fix appendonly.aof
0x              62: Expected \r\n, got: 6173
AOF analyzed: size=122, ok_up_to=23, diff=99
This will shrink the AOF from 122 bytes, with 99 bytes, to 23 bytes
Continue? [y/N]: y
Successfully truncated AOF

优缺点

优点

  1. 每次修改都同步,文件完整性更好,
  2. 每秒同步一次,这样会丢失一秒的数据
  3. 从不同步,效率最高的!

缺点

  1. 相对于数据文件来说,aof远远大于rdb,修复的速度比rdb慢
  2. aof运行效率要比rdb慢,会进行IO操作

扩展:

  • RBD
    RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。

  • AOF
    AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。

  • 只做缓存
    如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.。

  • 同时开启两种持久化方式

    • 在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
    • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
  • 性能建议

    • 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。
    • 如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
    • 如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构。

1.9 Redis发布订阅

1.9.1 Redis发布订阅

订阅、发布消息图:

image-20211212120719861

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息

Redis客户端可以订阅任意数量的频道

第一个是:消息发送者 第二个是:频道 第三个是:消息订阅者

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

img

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

img

Redis 发布订阅命令
下表列出了 redis 发布订阅常用命令:

  • PSUBSCRIBE pattern [pattern …]
    订阅一个或多个符合给定模式的频道。
  • PUBSUB subcommand [argument [argument …]]
    查看订阅与发布系统状态。
  • PUBLISH channel message
    将信息发送到指定的频道。
  • PUNSUBSCRIBE [pattern [pattern …]]
    退订所有给定模式的频道。
  • SUBSCRIBE channel [channel …]
    订阅给定的一个或多个频道的信息。
  • UNSUBSCRIBE [channel [channel …]]
    指退订给定的频道。
# 测试
# 订阅一个频道
127.0.0.1:6379> SUBSCRIBE yunmx										# 订阅一个频道到yunmx
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yunmx"
3) (integer) 1

# 新窗口发送一个消息:发布者
[root@yunmx ~]# redis-cli
127.0.0.1:6379> PUBLISH yunmx test									# 发布者发布消息到指定名称的频道
(integer) 1

# 接收到的消息
127.0.0.1:6379> SUBSCRIBE yunmx		
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "yunmx"
3) (integer) 1
1) "message"														# 接收的消息
2) "yunmx"															# 哪个频道
3) "test"															# 消息内容

Redis发布订阅的原理

使用C实现的,通过分析Redis源码里面的pubsub.c文件,了解发布和订阅机制的底层实现逻辑,加深对redis的理解。(俺也不懂C,俺也不是开发,咋整)

通过PUBLISH/SUBSCRIBE/PSUBSCRIBE等命令实现发布订阅功能

  • SUBSCRIBE:通过此命令订阅频道以后,redis-server里维护一个字典,字典的键就是一个个channel(频道),而字典的值则是一个链表,链表中保存了所有订阅这个频道的客户端。-----就是将客户端添加到给定channel的订阅链表中
  • PUBLISH:向订阅者发送消息,redis-server会使用给定的频道作为键,在它所维护的channel字典中查询了记录了订阅这个频道所有的客户端连接,遍历整个链表,将消息发送给所有订阅者
  • PUB、SUB:就是发布、订阅,在redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值进行了消息发布以后,所有订阅它的客户端都会收到相应的消息,这一功能明显的用法就是用作实时消息系统,比如普通的即时聊天、群聊等功能

1.9.2 使用场景

  • 实时消息系统
  • 实时聊天------频道当作聊天室,将信息回显给所有人即可
  • 订阅,公众号订阅等
  • 稍微复杂的场景我们会使用消息中间件(MQ)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值