redis数据存在于内存中,如果机器出了问题,就会导致数据丢失,所以要对redis数据进行备份。
redis数据备份有两种方式:
以下基于 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备份,可以用以下方式:
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备份,可以用以下方式:
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