Redis作为分布式缓存,数据首先是存储在内存中的,但是为了保证数据不丢失,肯定需要将数据持久化到磁盘上。我在分布式进阶篇中的《Redis数据持久化》已经讲过了Redis的持久化原理。Redis一共提供了两种数据持久化方式: RDB 、 AOF 。
本章,我将带领大家在先前的1个CentOS节点上搭建单机Redis,然后通过实战讲解Redis的RDB和AOF持久化配置。
一、Redis安装
我首先在ressmix-dsf01这个节点上安装单机版本的Redis,后续随着我们讲解的深入,会配置成集群模式。进入/usr/local
目录,执行以下命令:
wget http://download.redis.io/releases/redis-5.0.8.tar.gz
tar xzf redis-5.0.8.tar.gz
cd redis-5.0.8
然后进入到src目录,执行make && make test && make install
命令进行编译构建。注意,如果没安装tcl需要先进行安装下(yum install tcl
)。
1.1 Redis配置
首先,我们创建两个目录:
#存放Redis的配置文件
mkdir /etc/redis
#存放Redis的持久化文件
mkdir -p /var/redis/6379
然后,将redis安装包util目录下的redis_init_script
脚本拷贝到/etc/init.d
目录中,并重命名为redis_6379
(6379是我们希望这个Redis实例监听的端口号)。
接着,将Redis的配置文件redis.conf
拷贝到/etc/redis
目录中,然后修改其名称为6379.conf
,修改配置文件:
#让redis以daemon进程运行
daemonize yes
#设置redis的pid文件位置
pidfile /var/run/redis_6379.pid
#设置redis的监听端口号
port 6379
#设置持久化文件的存储位置
dir /var/redis/6379
然后,进入/etc/init.d
目录,在redis_6379
开头增加两行注释,增加redis_6379
的执行权限,然后执行chkconfig redis_6379 on
让Redis开机自启动,如下:
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 90 10
# description: Redis is a persistent key-value database
接着,进入/usr/local/redis-5.0.8
目录,执行make install
;
最后,执行./redis_6379 start
启动Redis。我们可以通过redis-cli
测试下Redis的使用:
二、RDB持久化
RDB持久化默认是打开的,我们先来看下如何进行Redis的RBD持久化配置。
2.1 持久化配置
我可以通过修改redis.conf
文件,也就是/etc/redis/6379.conf
,去配置持久化:
# 每隔60s,如果有超过1000个key发生了变更,那么就生成一个新的dump.rdb文件
save 60 1000
注意,save可以设置多个,就是多个snapshotting检查点,每到一个检查点,Redis就会去check一下是否有指定的key数量发生了变更,如果有就生成一个新的dump.rdb文件。
2.2 持久化实验
我们可以通过实验来模拟下RDB持久化。
- 首先,在Redis中保存几条数据,立即停掉Redis进程(
kill -9
),然后重启Redis,会发现刚才插入的数据在Redis中并不存在。 - 接着,我们配置下
/etc/redis/6379.conf
,增加一个save检查点save 5 1
,写入几条数据,等待5秒钟,会在/var/redis/6379
目录下一个rdb快照文件,里面有刚才存入Redis的数据。 - 最后,
kill -9
停掉Redis进程,再重新启动Redis,发现刚才插入的数据还在。
三、AOF持久化
AOF持久化是默认关闭的,可以在Redis的配置文件中配置如下行,打开AOF持久化。打开AOF持久化机制之后,Redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下。
appendonly yes
AOF的fsync策略,有三种策略可以选择,可以在配置文件中进行配置:
- appendfsync always:每写入一条数据就执行一次fsync;
- appendfsync no:不主动执行fsync
- appendfsync everysec:每隔一秒执行一次fsync(默认策略)
关于AOF持久化的原理,不了解的读者先去看看分布式进阶篇中的《Redis数据持久化》。
3.1 持久化实验
我们可以做以下实验验证下AOF持久化:
- 仅打开RDB,写入一些数据,然后kill -9杀掉Redis进程;
- 重启Redis,我们会发现刚才写入的数据没了,因为RDB快照还没生成;
- 打开AOF持久化,写入一些数据,可以发现AOF文件中(appendonly.aof)多了一些日志内容;
- kill -9杀掉Redis进程,然后重启Redis进程,会发现数据被恢复回来了。因为Redis进程启动的时候,直接就会从appendonly.aof中加载所有的日志,把内存中的数据恢复回来。
3.2 AOF rewrite
Redis内存中的数据是有限的,很多Key可能会过期,可能会被用户删除,但是它们对应的写日志还停留在AOF日志文件中,而AOF日志文件就一个,所以会不断的膨胀。
AOF会自动在后台每隔一定时间做rewrite操作:比如日志里已经存放了针对100w数据的写日志了,Redis内存只剩下10万,那么Redis会基于内存中当前的10万数据构建一个新的AOF文件,确保AOF日志文件不会过大,保持跟Redis内存中的数据量一致。
我们可以在Redis的配置文件中进行如下AOF rewrite配置:
#AOF文件增长超过的比例
auto-aof-rewrite-percentage 100
#AOF文件增长超过的最小大小
auto-aof-rewrite-min-size 64mb
我举个例子来帮助大家理解下上面这两个参数:
假设最近一次rewrite后,aof文件大小为128MB,那么当继续写入数据,文件越来越大达到256MB时(增长100%),Redis会去判断下,增长的文件大小(256-128=128MB)是否大于64MB,如果大于就进行一次AOF rewrite。
3.3 AOF文件修复
如果Redis在写AOF日志时,机器宕机了,则可能会导致AOF文件破损。我们可以用redis-check-aof --fix [aof文件名]
命令来修复破损的AOF文件。
AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复。
四、总结
本章,我介绍了RBD和AOF两种持久化方式的实战操作,最后总结下:
- 如果Redis正在执行RDB持久化,那就不会再同时执行AOF rewrite,反之亦然;
- 如果Redis正在执行RDB持久化,此时用户执行
BGREWRITEAOF
命令,那么只有等RDB快照生成之后,才会去执行AOF rewrite; - Redis重启的时候,如果发现同时有RBD快照和aof日志文件,那会优先使用AOF进行数据恢复,因为其中的日志更完整。