ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis的持久化

2022-07-26 18:34:26  阅读:130  来源: 互联网

标签:aof 26 持久 Redis redis Jul 6380 root


redis数据存在于内存中,如果机器出了问题,就会导致数据丢失,所以要对redis数据进行备份。

redis数据备份有两种方式:

  • RDB
  • AOF

以下基于 redis3 进行实操,来看看两种方式有什么不同。

简单配置下redis:

port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
# 日志文件、数据备份文件的目录
dir /usr/local/redis/data/
# rdb文件名
dbfilename 6380.rdb
stop-writes-on-bgsave-error yes
rdbcompression yes

为了方便测试,先创建一批数据:

127.0.0.1:6380> dbsize
(integer) 0
127.0.0.1:6380> debug populate 10000000
OK
(9.27s)
127.0.0.1:6380> dbsize
(integer) 10000000

 

RDB

rdb备份,可以用以下方式:

  • save
  • bgsave
  • 配置conf

save

[root@2207011 redis]# ls -lh data/
total 4.0K
-rw-r--r--. 1 root root 2.3K Jul 14 07:48 6380.log
[root@2207011 redis]# ./bin/redis-cli -p 6380127.0.0.1:6380> save
OK
(9.52s)
[root@2207011 redis]# ls -lh data/
total 256M
-rw-r--r--. 1 root root 2.3K Jul 14 08:13 6380.log
-rw-r--r--. 1 root root 256M Jul 14 08:13 6380.rdb

此时看到生成了rdb文件,对应的redis日志也会追加一条类似于5013:M 14 Jul 08:10:51.087 * DB saved on disk的记录。

save操作会把所有的redis数据写入到磁盘中,生成一个rdb格式的文件,由于没有fork新进程来做这件事,应该会堵塞redis:

在客户端中执行save

127.0.0.1:6380> save
OK
(9.90s)

此时客户端堵塞了(命令执行了大概10s),同时在另外一个客户端执行其它命令:

127.0.0.1:6380> get name
(nil)
(8.69s)

明显该命令被堵塞住了!redis是单线程的,该命令排在了save后面,只有save执行成功了,才会执行它。

bgsave

save方式虽然备份了数据,但会堵塞redis服务,并不友好!看看bgsave,又会怎样?

127.0.0.1:6380> bgsave
Background saving started

执行bgsave之后,立马返回 Background saving started 。

同时在另外一个客户端执行命令:

127.0.0.1:6380> get name
(nil)

直接返回了结果!

bgsave备份数据,会开新进程进行:

[root@2207011 redis]# ps -ef | grep redis | grep -v grep | grep -v cli
root      3912     1  1 08:40 ?        00:00:30 ./bin/redis-server *:6380
root      4049  3912 92 09:18 ?        00:00:01 redis-rdb-bgsave *:6380

在看看对应的日志信息:
3912:M 19 Jul 09:07:41.105 * Background saving started by pid 4049
4012:C 19 Jul 09:07:51.155 * DB saved on disk
4012:C 19 Jul 09:07:51.161 * RDB: 4 MB of memory used by copy-on-write
3912:M 19 Jul 09:07:51.239 * Background saving terminated with success

bgsave会异步的备份数据,比save更友好。但它进行了fork系统调用,开子进程,产生一定的系统开销,所以这个过程可能也会出现堵塞!

配置conf

编辑conf文件:
# rdb文件名
dbfilename 6380.rdb
stop-writes-on-bgsave-error yes
rdbcompression yes
# 备份条件:60s内,出现6个key的修改,则进行备份(为了测试这里设置的数值都相对较小)
save 60 6
rdbchecksum no

配置好之后,就可以重启服务。然后在一分钟内操作6个key修改。接着可以在日志里看到:

4155:M 19 Jul 10:00:53.542 * 6 changes in 60 seconds. Saving...
4155:M 19 Jul 10:00:53.543 * Background saving started by pid 4162
4162:C 19 Jul 10:00:53.545 * DB saved on disk
4162:C 19 Jul 10:00:53.545 * RDB: 6 MB of memory used by copy-on-write
4155:M 19 Jul 10:00:53.644 * Background saving terminated with success

也就是达到了 save 60 6 的条件之后,进行了自动的备份,在后台进行了一次bgsave操作。

总结

  save bgsave
优点 没有进程创建消耗 后台进行,不堵塞redis
缺点 堵塞redis 进程创建消耗系统资源

也就是说save和bgsave的优缺点是相对的。

AOF

aof备份,可以用以下方式:

  • bgrewriteaof
  • 配置conf

bgrewriteaof

127.0.0.1:6380> bgrewriteaof
Background append only file rewriting started

命令执行完成,会在后台进行数据备份。通过ps查看进程,会看到:

root      5389  5302 99 03:39 ?        00:00:02 redis-aof-rewrite *:6380

刚开始可以看到临时的数据文件如:temp-rewriteaof-bg-5389.aof,最终备份完成,生成的是6380.aof(aof文件名可以在配置指定:appendfilename选项)

[root@2207011 redis]# ls -lh data/
total 740M
-rw-r--r--. 1 root root 485M Jul 26 03:23 6380.aof
-rw-r--r--. 1 root root  732 Jul 26 03:23 6380.log
-rw-r--r--. 1 root root 256M Jul 26 03:20 6380.rdb

和rdb文件不同,aof文件保存的是生成redis数据的命令,所以通常备份相同的数据情况下,aof文件要比rdb文件大得多。

在看看对应的日志信息:

5302:M 26 Jul 03:23:33.211 * Background append only file rewriting started by pid 5389
5302:M 26 Jul 03:23:43.782 * AOF rewrite child asks to stop sending diffs.
5389:C 26 Jul 03:23:43.783 * Parent agreed to stop sending diffs. Finalizing AOF...
5389:C 26 Jul 03:23:43.785 * Concatenating 0.00 MB of AOF diff received from parent.
5389:C 26 Jul 03:23:43.786 * SYNC append only file rewrite performed
5389:C 26 Jul 03:23:43.795 * AOF rewrite: 0 MB of memory used by copy-on-write
5302:M 26 Jul 03:23:43.910 * Background AOF rewrite terminated with success
5302:M 26 Jul 03:23:43.911 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
5302:M 26 Jul 03:23:43.911 * Background AOF rewrite finished successfully

配置conf 编辑conf文件: # 开启aof备份 appendonly yes # aof文件名
appendfilename "6380.aof" # 把输出缓冲区的数据写入到磁盘的策略,有no、always、everysec三种方式。其中no表示让操作系统决定什么时候刷入磁盘;always表示一有数据就调用fsync刷入磁盘;everysec表示每秒去调用一次fsync刷入磁盘。相对于no不可控,always导致磁盘io高,官方文档描述这是一种折中方式。
appendfsync everysec # 在重写过程中,不进行appendfsync操作(aof重写就是对重复的、过期失效的数据命令进行整理,不然一个key进行数亿次的count,aof记录数亿次该count命令,aof文件就会很大;还有过期数据也是,最终还原并没有该数据。所以通过重写整理这些命令)。由于appendfsync和重写过程都进行磁盘io,磁盘io过大可能会导致redis在调用fsync的时候堵塞住!而且重写完成之后,数据备份也是完整的,所以可以在重写的时候不进行appendfsync操作。
no-appendfsync-on-rewrite no # aof文件多大时会进行自动重写
auto-aof-rewrite-min-size 10mb # aof文件自动重写的比例(即aof文件的增长率,该比例=当前aof文件大小-上次aof文件启动或重写的大小/上次aof文件启动或重写的大小),以下设置成100,意味着当aof文件从10mb变成20mb的时候,会自动进行重写,依此类推。
auto-aof-rewrite-percentage 100 # 通过aof文件恢复数据时尽可能多的读取完整的备份。如果redis生成aof文件过程发生死机或者其它异常的故障,就会导致aof文件不完整,再次通过aof文件恢复数据的时候,这里设置为no则会启动不了redis,设置为yes则可以最大程度去恢复数据。
aof-load-truncated yes 为了方便测试重写过程,可以设置auto-aof-rewrite-min-size 1kb。 配置好之后,重启redis服务。可以发现生成了一个空的6380.aof文件。 通过客户端执行多次incr命令,可以看到6380.aof文件不断增大。 大致看下aof文件内容,会发现: *2
$4
incr
$1
a 大致的意思就是incr a命令 当aof文件达到了1kb的时候就会进行重写,在后台进行了一次bgrewriteaof,可以看对应的日志: 5916:M 26 Jul 10:08:14.989 * Starting automatic rewriting of AOF on 103000% growth
5916:M 26 Jul 10:08:14.990 * Background append only file rewriting started by pid 5975
5916:M 26 Jul 10:08:15.024 * AOF rewrite child asks to stop sending diffs.
5975:C 26 Jul 10:08:15.024 * Parent agreed to stop sending diffs. Finalizing AOF...
5975:C 26 Jul 10:08:15.024 * Concatenating 0.00 MB of AOF diff received from parent.
5975:C 26 Jul 10:08:15.024 * SYNC append only file rewrite performed
5975:C 26 Jul 10:08:15.024 * AOF rewrite: 6 MB of memory used by copy-on-write
5916:M 26 Jul 10:08:15.090 * Background AOF rewrite terminated with success
5916:M 26 Jul 10:08:15.090 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
5916:M 26 Jul 10:08:15.090 * Background AOF rewrite finished successfully 当关闭redis的时候,redis会一次把缓冲区的数据刷入磁盘中,可以看到对应的日志: 5814:M 26 Jul 10:00:26.290 # User requested shutdown...
5814:M 26 Jul 10:00:26.290 * Calling fsync() on the AOF file.
5814:M 26 Jul 10:00:26.290 * Removing the pid file.
5814:M 26 Jul 10:00:26.290 # Redis is now ready to exit, bye bye...

标签:aof,26,持久,Redis,redis,Jul,6380,root
来源: https://www.cnblogs.com/xiaoxiaobug/p/16478173.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有