原创

分布式实战(三)——Redis持久化实战

Redis作为分布式缓存,数据首先是存储在内存中的,但是为了保证数据不丢失,肯定需要将数据持久化到磁盘上。我在分布式进阶篇中的《Redis数据持久化》已经讲过了Redis的持久化原理。Redis一共提供了两种数据持久化方式:RDBAOF

本章,我将带领大家在先前的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持久化。

  1. 首先,在Redis中保存几条数据,立即停掉Redis进程(kill -9),然后重启Redis,会发现刚才插入的数据在Redis中并不存在。
  2. 接着,我们配置下/etc/redis/6379.conf,增加一个save检查点save 5 1,写入几条数据,等待5秒钟,会在/var/redis/6379目录下一个rdb快照文件,里面有刚才存入Redis的数据。
  3. 最后,kill -9停掉Redis进程,再重新启动Redis,发现刚才插入的数据还在。

三、AOF持久化

AOF持久化是默认关闭的,可以在Redis的配置文件中配置如下行,打开AOF持久化。打开AOF持久化机制之后,Redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下。

appendonly yes

AOF的fsync策略,有三种策略可以选择,可以在配置文件中进行配置:

  1. appendfsync always:每写入一条数据就执行一次fsync;
  2. appendfsync no:不主动执行fsync
  3. appendfsync everysec:每隔一秒执行一次fsync(默认策略)

关于AOF持久化的原理,不了解的读者先去看看分布式进阶篇中的《Redis数据持久化》

3.1 持久化实验

我们可以做以下实验验证下AOF持久化:

  1. 仅打开RDB,写入一些数据,然后kill -9杀掉Redis进程;
  2. 重启Redis,我们会发现刚才写入的数据没了,因为RDB快照还没生成;
  3. 打开AOF持久化,写入一些数据,可以发现AOF文件中(appendonly.aof)多了一些日志内容;
  4. 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两种持久化方式的实战操作,最后总结下:

  1. 如果Redis正在执行RDB持久化,那就不会再同时执行AOF rewrite,反之亦然;
  2. 如果Redis正在执行RDB持久化,此时用户执行BGREWRITEAOF命令,那么只有等RDB快照生成之后,才会去执行AOF rewrite;
  3. Redis重启的时候,如果发现同时有RBD快照和aof日志文件,那会优先使用AOF进行数据恢复,因为其中的日志更完整。
正文到此结束
本文目录