零、本文纲要
一、单机Redis的问题
二、Redis持久化
(一)RDB持久化
(二)AOF持久化
(三)RDB与AOF对比
三、Redis主从
tips:Ctrl + F快速定位所需内容进行阅读吧。
一、单机Redis的问题
1、数据丢失问题
实现Redis数据持久化;
2、并发能力问题
搭建主从集群,实现读写分离;
3、故障恢复问题
利用哨兵机制,实现健康检测和自动恢复;
4、存储能力问题
搭建分片集群,利用插槽机制实现动态扩容。
二、Redis持久化
(一)RDB持久化
1、RDB持久化
RDB全称Redis Database Backup file(Redis数据备份文件)
,也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件,默认是保存在当前运行目录
。
2、持久化执行时机
- ① 执行
save命令
;
由Redis主进程来执行RDB,会阻塞所有命令;
127.0.0.1:6379> save
OK
- ② 执行
bgsave命令
;
开启子进程执行RDB,主进程可以继续处理用户请求,不受影响;
127.0.0.1:6379> bgsave
Background saving started
- ③ Redis
停机
时;
Redis停机时会执行一次save命令,实现RDB持久化,如下日志中的Saving the final RDB snapshot before exiting.
;
[47784] 30 Mar 21:55:57.615 # User requested shutdown... # 用户请求关闭服务
[47784] 30 Mar 21:55:57.615 * Saving the final RDB snapshot before exiting. # 在退出前保存RDB快照
[47784] 30 Mar 21:55:57.617 * DB saved on disk # DB快照成功保存至磁盘
[47784] 30 Mar 21:55:57.617 # Redis is now ready to exit, bye bye... # Redis准备退出,拜拜...
- ④ 触发
RDB条件
时。
Redis内部有触发RDB的机制(执行的是bgsave命令
),可以在redis.conf文件中找到,格式如下:
# save "" # remove all the previously configured save points # 开启此配置会使RDB持久化失效,默认关闭
save 900 1 # after 900 sec (15 min) if at least 1 key changed # 900秒内至少1个写操作,则触发RDB持久化
save 300 10 # after 300 sec (5 min) if at least 10 keys changed # 300秒内至少10个写操作,则触发RDB持久化
save 60 10000 # after 60 sec if at least 10000 keys changed # 60秒内至少10000个写操作,则触发RDB持久化
3、bgsave原理
bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。
fork采用的是copy-on-write技术
:
- 当主进程执行读操作时,访问共享内存;
- 当主进程执行写操作时,则会拷贝一份数据,执行写操作。
- ① bgsave过程
Ⅰ fork
主进程得到一个子进程
,共享内存
空间;
Ⅱ 子进程读取内存数据并写入新的RDB文件
;
Ⅲ 用新
RDB文件替换旧
的RDB文件。
- ② bgsave缺点
Ⅰ 如果未触发条件宕机,两次bgsave间的数据有丢失风险;
Ⅱ fork子进程、压缩、写出RDB文件都比较耗时;
Ⅲ 写新的RDB文件时,主进程是copy数据副本操作的,如果大量的写操作则需要更多的内存空间。
注意:copy-on-write在理论极端情况下可能需要双倍的内存,所以实际生产环境请给Redis预留一些额外内存。
(二)AOF持久化
1、AOF持久化
AOF全称为Append Only File(追加文件)
。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件
。
2、AOF配置
AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:
# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"
AOF的命令记录的频率也可以通过redis.conf文件来配:
# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
3、AOF文件重写
AOF文件因为是记录命令,所以会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令
,可以让AOF文件执行重写
功能,用最少的命令达到相同效果。
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k1 v2
OK
127.0.0.1:6379> set k2 v3
OK
127.0.0.1:6379> set k2 v4
OK
127.0.0.1:6379> bgrewriteaof
Background append only file rewriting started
上述案例四条指令其实可以简化成mset k1 v2 k2 v4
,使用bgrewriteaof
指令可以帮助我们完成命令重写。
Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:
# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
(三)RDB与AOF对比
RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。
三、Redis主从
(一)单机搭建主从
1、准备实例和配置
- ① 创建各实例目录
# 进入/tmp目录
cd /tmp
# 创建目录
mkdir 7001 7002 7003
- ② 拷贝配置文件到每个实例目录
Ⅰ xargs:命令格式somecommand |xargs -item command
;
Ⅱ -n num:后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的,此处我们指定-n 1
;
Ⅲ -t 表示先打印命令,然后再执行;
Ⅳ echo:用于字符串的输出,echo 7001 7002 7003
输出字符串到|
后面的命令。
# 方式一:逐个拷贝
cp /usr/local/src/redis-6.2.6/redis.conf 7001
cp /usr/local/src/redis-6.2.6/redis.conf 7002
cp /usr/local/src/redis-6.2.6/redis.conf 7003
# 方式二:管道组合命令,一键拷贝
echo 7001 7002 7003 | xargs -t -n 1 cp /usr/local/src/redis-6.2.6/redis.conf
- ③ 修改每个实例的端口、工作目录
Ⅰ sed:利用脚本来处理文本文件,语法sed [-hnV][-e