Redis 持久化
2023-11-14 23:22:40 2 举报
AI智能生成
Redis 持久化
作者其他创作
大纲/内容
AOF 日志
以日志的形式记录 Redis服务器所执行的写操作
配置方式:redis.conf 文件中设置 appendonly 参数
保存过程:先执行写操作后,再记录到日志中
优点
1、避免额外的检查开销
2、不会阻塞当前写操作命令的执行
缺点
1、执行命令和记录日志是两个过程,会存在丢失的风险
2、写操作之后才记录到日志,可能会阻塞下一个命令
写回策略
AOF 日志写回硬盘的时机
写回过程,1、将命令追加到 aofbuf 缓冲区。 2、通过 write 函数,写入到内核缓冲区。 3、内核决定什么时候写入到硬盘文件
写回策略
配置方式:redis.conf 中的 appendfsync 参数
控制的就是写回过程的第三步,内核什么时候写入到硬盘文件的时机
3 种参数
Always
含义:每次写操作命令执行后,同步将 AOF 日志数据写回硬盘
优缺点
高可靠, 最大程序保证数据不丢失。
每执行一条写操作命令,都要写回到硬盘,影响主进程的性能
Everysec
含义:每次写操作命令执行后,先将命令写入到 AOF 文件的内核缓冲区,每隔一秒将缓冲区里的内存写回到硬盘
优缺点
折中方式,避免了 Always 策略的性能开销,也比 No 策略更能避免数据丢失,最多丢失一秒的数据
No
含义:由操作系统决定何时将缓冲区内存写回硬盘
优缺点
高性能
一旦服务器宕机,会丢失不定数量的数据
对比
策略的实现方式
控制 fsync() 函数的调用时机
调用该函数后,内核就会将内核缓冲区的数据直接写入硬盘
Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数
Everysec 策略就会创建一个异步任务来执行 fsync() 函数;
No 策略就是永不执行 fsync() 函数
AOF 重写机制
目的:避免 AOF 文件越写越大,利用 AOF 重写机制,来压缩 AOF 文件
含义:在重写时,读取当前数据库中的所有键值对,然后将每一个键值对用一条命令记录到的【新的 AOF 文件】,等到全部记录完后,用新的的 AOF 文件替换掉现有的 AOF 文件
实现方式:通过 fork 系统调用生成后台子进程 bgrewriteaof 来完成
避免阻塞主进程
子进程带有主进程的数据副本,写时复制,不用加锁来保证数据安全
写时复制也能避免 fork 创建子进程复制时间太长导致父进程长时间阻塞的问题
RDB 持久化
优点:适用于大规模数据集的快速恢复
配置方式:redis.conf 文件中设置 save 参数
save 900 1
save 300 10
save 60 10000
save 300 10
save 60 10000
缺点:可能会丢失最后一次快照后的数据
保存过程:fork 子进程,将数据写入临时文件,替换原有快照文件
混合持久化
优点:结合 RDB 和 AOF 的优点
配置方式:redis.conf 文件中 aof-use-rdb-preamble yes
混合持久化工作在 AOF 日志重写过程
当开启了混合持久化时,在 AOF 重写日志时, fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 的方式写入到 AOF 文件,然后主线程处理的操作命令会被记录在重写缓冲区中,重写缓冲区里的增量命令会以 AOF 方式写入到 AO 文件。写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替代旧的 AOF 文件。
使用了混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据
big key
什么是大key
string: 超过 10KB
set\zset\hash
数据超过 5000 条
持久化影响
创建子进程的途中,由于要复制父进程的页表等数据结构,阻塞的时间跟页表的大小有关,页表越大,阻塞的时间也越长;
创建完子进程后,如果父进程修改了共享数据中的大 Key,就会发生写时复制,这期间会拷贝物理内存,由于大 Key 占用的物理内存会很大,那么在复制物理内存这一过程,就会比较耗时,所以有可能会阻塞父进程。
其他影响
客户端超时阻塞。由于 Redis 执行命令是单线程处理,然后在操作大 key 时会比较耗时,那么就会阻塞 Redis,从客户端这一视角看,就是很久很久都没有响应。
引发网络阻塞。每次获取大 key 产生的网络流量较大,如果一个 key 的大小是 1 MB,每秒访问量为 1000,那么每秒会产生 1000MB 的流量,这对于普通千兆网卡的服务器来说是灾难性的。
阻塞工作线程。如果使用 del 删除大 key 时,会阻塞工作线程,这样就没办法处理后续的命令。
内存分布不均。集群模型在 slot 分片均匀情况下,会出现数据和查询倾斜情况,部分有大 key 的 Redis 节点占用内存多,QPS 也会比较大。
如何避免
设计阶段就拆分
定时检查是否存在大key。
不要用 del 删除大key,用 unlink 命令,该命令时异步的
0 条评论
下一页