redis持久化
Redis虽然是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。
AOF与RDB对比
** AOF **更安全,可将数据及时同步到文件中,但需要较多的磁盘IO,AOF文件尺寸较大,文件内容恢复相对较慢, 也更完整。
** RDB **持久化,安全性较差,它是正常时期数据备份及 master-slave数据同步的最佳手段,文件尺寸较小,恢复数度较快。
RDB持久化
redis提供了RDB持久化的功能,这个功能可以将redis在内存中的的状态保存到硬盘中,它可以手动执行,也可以再redis.conf中配置,定期执行。
RDB持久化产生的RDB文件是一个经过压缩的二进制文件,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。
RDB的创建与载入
RDB文件可以通过两个命令来生成:
SAVE
:阻塞redis的服务器进程,直到RDB文件被创建完毕。BGSAVE
:派生(fork)一个子进程来创建新的RDB文件,记录接收到BGSAVE当时的数据库状态,父进程继续处理接收到的命令,子进程完成文件的创建之后,会发送信号给父进程,而与此同时,父进程处理命令的同时,通过轮询来接收子进程的信号。
而RDB文件的载入一般情况是自动的,redis服务器启动的时候,redis服务器再启动的时候如果检测到RDB文件的存在,那么redis会自动载入这个文件。
如果服务器开启了AOF持久化,那么服务器会优先使用AOF文件来还原数据库状态。
RDB是通过保存键值对来记录数据库状态的,采用copy on write的模式,每次都是全量的备份。
自动保存间隔
BGSAVE
可以在不阻塞主进程的情况下完成数据的备份。可以通过redis.conf中设置多个自动保存条件,只要有一个条件被满足,服务器就会执行BGSAVE命令。
相关配置
1 | # 以下配置表示的条件: |
AOF持久化
AOF持久化(Append-Only-File),与RDB持久化不同,AOF持久化是通过保存Redis服务器锁执行的写状态来记录数据库的
具体来说,RDB持久化相当于备份数据库状态,而AOF持久化是备份数据库接收到的命令,所有被写入AOF的命令都是以redis的协议格式来保存的。
在AOF持久化的文件中,数据库会记录下所有变更数据库状态的命令,除了指定数据库的select命令,其他的命令都是来自client的,这些命令会以追加(append)的形式保存到文件中。
** appendfsync** 影响服务器多久完成一次命令的记录
always
:将缓存区的内容总是即时写到AOF文件中。
everysec
:将缓存区的内容每隔一秒写入AOF文件中。
no
:写入AOF文件中的操作由操作系统决定,一般而言为了提高效率,操作系统会等待缓存区被填满,才会开始同步数据到磁盘
redis默认everysec
redis在载入AOF文件的时候,会创建一个虚拟的client,把AOF中每一条命令都执行一遍,最终还原回数据库的状态,它的载入也是自动的。在RDB和AOF备份文件都有的情况下,redis会优先载入AOF备份文件
AOF文件可能会随着服务器运行的时间越来越大,可以利用AOF重写的功能,来控制AOF文件的大小。AOF重写功能会首先读取数据库中现有的键值对状态,然后根据类型使用一条命令来替代前的键值对多条命令。
AOF重写功能有大量写入操作,所以redis才用子进程来处理AOF重写。这里带来一个新的问题,由于处理重新的是子进程,这样意味着如果主线程的数据在此时被修改,备份的数据和主库的数据将会有不一致的情况发生。因此redis还设置了一个AOF重写缓冲区,这个缓冲区在子进程被创建开始之后开始使用,这个期间,所有的命令会被存两份,一份在AOF缓存空间,一份在AOF重写缓冲区,当AOF重写完成之后,子进程发送信号给主进程,通知主进程将AOF重写缓冲区的内容添加到AOF文件中。
相关配置:
1 | #AOF 和 RDB 持久化方式可以同时启动并且无冲突。 |
目录结构
1 | test1 |
新建redis.conf
具体配置如下:
1 | # 使用守护进程模式 |
新建Dockerfile
1 | FROM redis:4-alpine |
** 生成镜像**
1 | docker build -t redis:v2 . |
新建docker-compose.yml
1 | version: '3' |
** 执行**
1 | docker-compose up -d |
验证
在data目录查看是否有.aof文件生成
1 | [root@localhost redistest1]# cd data |
获取容器IP
1 | docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis_server |
连接Redis
1 | docker exec -it redis_server redis-cli -h 172.19.0.2 -p 6380 |
参考: