当前位置:网站首页>结合实操带你吃透Redis持久化

结合实操带你吃透Redis持久化

2022-06-24 21:29:00 逻魔代码

点击卡片 关注、置顶 公众号

技术干货,及时送达!


所谓持久化,就是把缓存内容写进磁盘永久存储(你不删,磁盘不坏可不就是永久嘛)

RDB

RDB 是 Redis 默认的持久化方案。RDB快照(Redis DataBase):当满足 一定条件 的时候,会把当前内存中的数据写入磁盘,生成一个快照文件 dump.rdb。

还是先贴配置:

# 文件路径,
dir ./
# 文件名称
dbfilename dump.rdb
# 是否是 LZF 压缩 rdb 文件
rdbcompression yes
# 开启数据校验 sht
rdbchecksum yes

Redis重启会通过dump.rdb文件恢复数据。那么 一定的条件 是啥呢?到底什么时候写入 rdb 文件?

自动触发

  1. 配置规则触发

redis.conf, SNAPSHOTTING配置,其中定义了触发 把数据保存到磁盘的 触发频率。如果不需要 RDB 方案,注释 或者配置成空字符串 " " 。

save 900 1 # 900 秒内至少有一个 key 被修改(包括添加)
save 300 10 # 300 秒内至少有 10 个key 被修改
save 60 10000 # 60 秒内至少有 10000 个 key 被修改
注意上面的配置是不冲突的,只要满足任意一个都会触发。
  1. shutdown 触发,保证服务器正常关闭,关闭的时候不会造成数据丢失

手动触发

如果我们需要重启服务或者迁移数据,这个时候就需要手动触发RDB快照保存。所以redis也提供了2种手动保存RDB快照的指令。

  1. Save save在生成快照的时候会阻塞当前Redis服务器,Redis不能处理其他命令。如果内存中的数据比较多,会造成Redis长时间的阻塞。生产环境不建议使用这个命令。为了解决这个问题,Redis 提供了第二种方式。
  2. bgsave 执行bgsave时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork(创建进程函数)操作创建子进程(copy-on-write),RDB持久化过程由子进程负责,完成后自动结束。它不会记录 fork之后后续的命令。阻塞只发生在fork阶段,一般时间很短。用lastsave 命令可以查看最近一次成功生成快照的时间。

演示一次RDB快照恢复数据的一个过程!(我的快照在src下面)

我们首先添加一份数据并且备份到RDB:

redis> set k1 1
redis> set k2 2
redis> set k3 3

查看数据是否存在:

redis>keys *

我们进行shutdown操作触发RDB快照:(模拟意外断电)

redis> shutdown

对现有RDB数据进行备份 cp:

redis>cp dump.rdb dump.rdb.bak

启动redis:

redis> src/redis-server& redis.conf

发现数据都还在,现在模拟数据丢失(手动清一下)

redis> flushall

停服务器再启动

redis> shutdown
redis> src/redis-server& redis.conf

发现数据已经丢失,我们现在就要从我们备份的数据恢复,先关闭

redis> shutdown

删除原RDB备份数据 cd

redis>rm dump.rdb

将备份数据改名为dump.rdb

mv dump.rdb.bak dump.rdb

重启服务

src/redis-server& redis.conf

自己看一下数据喽(手动滑稽)

我们知道了RDB的实现的原理逻辑,那么我们就来分析下RDB到底有什么优劣势。

优势

  • RDB是一个非常紧凑(compact类型)的文件,它保存了redis在某个时间点上的数据集。这种文件非常适合用于进行备份和灾难恢复。
  • 生成RDB文件的时候,redis主进程会fork()复刻一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
  • RDB在恢复大数据集时的速度比AOF的恢复速度要快。

劣势

  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行 fork 操作创建子进程,频繁执行成本过高。
  • 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照之后的所有修改(数据有丢失)。

针对劣势情况,redis又提供了一种持久化机制,就是AOF持久化机制!

AOF

AOF 是 Append Only File 的简称,只加载文件,这个方案在redis默认是不开启的。

AOF是怎么恢复的?

AOF采用日志的形式来记录每个写操作,并追加到文件中。

开启后,执行更改 Redis数据的命令时,就会把命令写入到AOF文件中。Redis重启时会根据日志文件的内容把写指令从前到后执行一次以完成数据的恢复工作。

那么它从哪里开启,又有些什么特性?

还是贴配置:配置文件 redis.conf

# 开关
appendonly no
# 文件名
appendfilename "appendonly.aof"

同步机制

AOF,会记录每个写操作,那么问题来了?我难道每次操作命令又得跟磁盘交互?当然不行,所以,redis支持几种策略,由你们自己来决定要不要每次都跟磁盘交互。

appendfsync always 表示每次写入都执行fsync(刷新)函数
appendfsync everysec 每秒执行一次fsync函数 默认1s一次,最多有1s丢失
appendfsync no 由操作系统保证数据同步到磁盘,速度最快

重写机制(rewrite)

为什么要重写?

比如,我们用分布式锁,指令是setnx,然后设置过期日期;由于是每次都是命令追加。那么1年后,10年后,我们会发现这个AOF文件里面全都是这样的指令!!

我一个1T的AOF文件,竟然全都是这样的指令。所以我们需要重写。

AOF文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的AOF文件。

怎么重写:

4.0版本之前,是比较指令并去除无效指令

假如:aof文件里这样几个指令:

redis> lpush huihuilist a
redis> lpush huihuilist b c d
redis> lpop huihuilist

就会重写成

redis> lpush huihuilist a b c

后来人们发现,这种方法效率很低,需要一个一个区比对!

所以,4.0之后引入了RDB 跟AOF 混合的模式,让RDB跟AOF一起使用,因为RDB的速度快,那么我们就引入这个特点,根据RDB模式,将以前的指令以二进制的方式覆盖到aof,后面写入的继续追求到文件后面。(混合模式默认是开启,也可以关闭)

aof-use-rdb-preamble yes //是否开启RDB与AOF混合模式

什么时候重写?

配置文件redis.conf

# 重写触发机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb 
//最开始aof文件必须要达到这个文件大小时才触发,后面的每次重写就不会根据这个变量了

说明一下上述配置的意义:

在 aof 文件小于64mb的时候不进行重写,当到达64mb的时候,就重写一次。
重写后的 aof文件可能是20mb。上面配置了auto-aof-rewrite-percentag为100,即 aof 文件到了40mb的时候,又开始重写一次。以此类推。

我们知道了AOF的实现原理,我们来分析下它的优缺点。

优点

  • 能最大限度地保证数据安全,就算用默认的配置everysec,也最多只会造成 1s 的数据丢失。

缺点

  • 数据量比RDB要大很多,所以性能没有RDB好,没有一个性能保证!

那我们平时开发中应该使用哪种持久化呢?

如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成RDB快照,非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。


作者:向着百万年薪努力的小赵

https://blog.csdn.net/weixin_44688973/article/details/125335060

PS:文章有帮助的话,点赞、在看、转发吧!
-----------------------------------------------
点击卡片关注我们,更多技术干货,及时为您送达!

往期推荐



【干货】超精妙!Twitter开源分布式自增ID算法snowflake,附演算验证过程
阿里 P8 总结的 10 条 SQL 优化方案(非常实用)
干货!前端 JS 模块化及其工具演变!
带你一文吃透 logback.xml 基础和进阶配置


公众号“逻魔代码”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!


原网站

版权声明
本文为[逻魔代码]所创,转载请带上原文链接,感谢
https://toutiao.io/k/1u6o78n