redis为什么要持久化?怎么持久化,持久化的方式有哪些?

1. redis为什么要做持久化

  首先,要知道我们为什么要对redis做持久化?

  因为,redis本身运行时数据保存在内存中,如果不进行持久化,那么在redis出现非正常原因宕机或者关闭redis的进程或者关闭计算机后数据肯定被会操作系统从内存中清掉。

很多人又会问,“明明我们在本地自己搭redis环境的时候没有多余的配置操作呀,但是就算自己重启redis或者重启计算机后,甚至过了几个月后,redis中的数据仍然存在哦!?”。

  当然,redis本身默认采用了一种持久化方式,即RDB (Redis DataBase)——可以在redis的目录中找到dump.rdb文件,这就是使用RDB方式做持久化后生成的数据文件。所以,redis如果没有做持久化,在重启redis后,数据会丢失,而redis默认就采用了一种持久化方式,即RDB。

2. redis怎么做持久化,持久化的方式有哪些

  redis持久化的方式有两种:RDB(Redis DataBase)和AOF(Append Only File)

2.1. RDB(Redis DataBase)

  RDB方式采用的思想是定时将内存中的数据进行快照,并写入dump.rdb文件当中,这个文件当中所存储的就是当前redis环境中的配置以及数据。每次当redis重启之后,redis会先读dump.rdb文件,将数据从硬盘写入到内存中。

  • Redis 调用fork函数复制一份子进程. 同时拥有(当前进程)父进程和子进程。

  • 父进程继续接收处理客户端发送过来的请求操作,子进程则从内存中将数据集写入到一个临时 RDB 文件中。

  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

redis为什么要持久化?怎么持久化,持久化的方式有哪些?

2.1.1 RDB模式的配置方式

  在redis的配置文件redis.conf中搜索save,这一个save可以设置在指定时间内,更新操作达到了固定次数,就将数据同步到数据文件,这里可以写多个save多条件配合使用。比如以下代码所示

# 表示900秒内有一次更改,或者900秒内有10次更改,或者60秒内有10000此更改执行同步操作
save 900 1
save 300 10
save 60 10000

  另外,如果想不使用RDB做持久化了,可以不配置任何的save,或者将save配成空字符串,如下图所示。

save ""

2.1.2 dbfilename与dir

  在redis的配置文件中如果使用RDB的方式做持久化,除了要注意save的配置外,还有两个配置需注意。其中一个是dbfilename,这一个配置表示存储的快照文件(数据文件)的文件名,redis默认为dump.rdb,所以我们看到redis目录中会有这样一个文件,这个文件中存放了二进制的内容。另外一个是dir,dir的配置表示了dbfilename所配置的这一个文件的路径,这里最好配一个绝对路径,因为如果使用了相对路径,那么通过不同的方式其启动redis可能会出现文件找不到导致数据前后不一致的情况发生。

2.2. AOF(Append Only File)

  AOP模式做持久化,把所有的写操作命令记录到磁盘文件中保存,也就是说使用AOF会将客户端对于redis的操作(查询除外)以一个字符串的形式记录到磁盘的文件中去,而在启动redis的时候会去读取这一个文件,将命令执行。

  AOF 文件与RDB 文件相比不同的是AOF 文件并不是一个snapshot (快照)的概念, 他是一个 append 的概念,文件的信息会直接添加到文件的末尾,当然这的方式比上面的RDB文件的好处就是,通过调整数据的刷新(同步)方式,是可以做到数据不丢失的,但不利的地方,即使随着保证数据不丢失的等级升高,对REDIS 本身的性能影响就会越突出。并且AOF 文件是在系统重启动,或者CRASH 后,在启动REDIS后对系统数据进行恢复的一种方式。
redis为什么要持久化?怎么持久化,持久化的方式有哪些?

2.2.1 AOF模式的配置方式

  redis默认是关闭AOF模式持久化的,需要打开,并且默认是每秒来进行与磁盘的交互,如果要使用需要修改一下配置:

# 默认为no,需修改为yes
appendonly yes
# AOF默认的持久化文件的文件名称
appendfilename "appendonly.aof"

  而指定更新日志条件的同步策略有三个可选条件,默认每秒进行同步:

# 当操作系统进行数据缓存同步到磁盘文件
# appendfsync no
# 每秒同步一次(默认值,也是最佳的选择,速度快,可能会丢失一秒以内的数据(最多不过2秒))
appendfsync everysec
# 同步持久化,当数据发生变更时,立即同步到磁盘文件(效率慢些,能保证数据的完整性) 
# appendfsync always

  另外,可以配置当持久化的文件到达一定程度后,进行重写,为什么要进行重写?由于AOF模式持久化记录的是操作命令,文件会越来越大,其实可以优化aof文件,去掉多余的中间操作命令,比如说当有这两个命令set key "value1", set key "value2"依次执行后,实际上要恢复数据只需要执行set key "value2"即可。经过类似的压缩,可以为原本已经很大的文件“瘦身”,以下的内容,即为执行此“瘦身”操作的配置。触发重写机制为:

# 当AOF的持久化文件大小的增长率大于此配置时,自动开启重写,redis会自动执行“BGREWRITEAOF”命令;
auto-aof-rewrite-percentage 100
# 当AOF的持久化文件大小大于此配置时,自动开启重写,redis会自动执行“BGREWRITEAOF”命令;
auto-aof-rewrite-min-size 3000mb

注:通过fork一个子进程,重新写一个新的aof文件,该次重写不是读取旧的aof文件进行复制,而是将读取内存中的redis数据库,重写一份aof文件,有点类似于rdb的快照方式;

2.2.2 AOF模式的优缺点

  AOF的优点:

  (1)AOF模式可以更好的保护数据不丢失,在redis因为非正常原因挂掉时,其保存数据的完整度理论上高于RDB模式,因为采用appendfsync everysec去写入持久化文件,最多丢失一秒到两秒的数据;而RDB模式丢失的数据根据其配置的写入频率决定;

  (2)AOF写入性能高,这归功于其是以append-only的方式写入;

  AOF的缺点:

  (1)对于同样的数据,通常AOF文件的大小回比RDB的要大;

  (2)因为AOF存的是命令而不是数据,所以恢复数据时可能较慢。

3. 同时开启RDB和AOF持久化模式来处理集群高并发、高频更新操作的业务场景

  如果你的REDIS 是从事写缓冲的工作,例如经常更新数据,所以在REDIS中进行了数据的更新,在多次的运算和更新后,将最后的结果刷入到传统的数据库中,这的确是一个解决高并发,更新值,降低传统数据库负担的方式。例如你一分钟更新上百次或上千次的值的情况下,在这样的情况下,你就需要将 RDB 文件和 AOF 文件都开启的,并且随着你的应用逻辑和你容忍数据可能丢失度的降低,你的RDB 文件和 AOF 文件的保存方式等级都会提高;

  例如 RDB 文件,你是否需要提高下面的RDB 文件的刷新率  ,根据刷新的频率,调整:

  redis为什么要持久化?怎么持久化,持久化的方式有哪些?

  例如,如果写入的在5秒就有10000次,则不需要调整,如果60秒内写入9999次,则需要调整一下 save 60 10000 变为 save 60 5000,这样RDB 的刷新文件(同步)的频率就会提高,满足你的需求。另外在你CTRL + C 终止REDIS 的情况下(Redis 并未在有),会强制先将数据刷入到 RDB 文件,否则除非你 KILL 否则是无法关闭 REDIS的。

  像我上面所说,AOF 持久化模式默认是关闭的,需要打开,并且默认是每秒来进行与磁盘的交互:

  redis为什么要持久化?怎么持久化,持久化的方式有哪些?

   redis为什么要持久化?怎么持久化,持久化的方式有哪些?

   所以在双重的RDB 和AOF 文件的加持下,在这样的业务场景下,数据安全是有保证的,如果还想严格的不丢失数据,则需要将上图的设置调整为 appendfsync always 打开,则任何的操作都会记录在 appendonly.aof 文件中,这种同步模式虽然是最安全,但也是性能最差的。

4. 总结

  所以REDIS 的持久化可以根据Redis在系统中所承担的作用来设置,如果是只读作为读缓冲,则可以不需要进行持久化的操作,可以将RDB AOF 文件关闭,已达到最好的效果,当然你的程序也需要考虑在 REDIS CRASH (崩了)后的数据重新刷入,否则会引起缓存雪崩,导致你的实体数据库 MYSQL ORACLE ,POSTGRESQL SQL SERVER 等数据库无法承受短期的高频的数据读取,而不再有响应。

  要不就需要设置 RDB, AOF 文件,在某些应用场景下,防止丢失数据,或者引起缓冲击穿后的雪崩问题。

  建议如果没有特殊的要求,需要打开 RDB AOF 持久化,这样REDIS 好, 传统数据库好,你好我好,大家好。

 

参考文章:
https://blog.csdn.net/y506798278/article/details/103541097

https://blog.csdn.net/liuhuayang/article/details/105743430

 

redis为什么要持久化?怎么持久化,持久化的方式有哪些?

上一篇:并发编程之:JMM


下一篇:Redis之Set类型