目录
其实就是集群
单点 Redis 的缺点
-
数据丢失问题:单节点 Redis 的问题,Redis 是内存存储,服务重启可能会丢失数据
-
并发能力的问题:单节点的 Redis 的并发能力虽然不错,但是也无法满足如今 618 这种高并发的场景
-
故障恢复问题:如果 Redis 宕机,则服务不可用,需要一种自动的故障恢复手段
-
存储能力问题:Redis 基于内存,单节点能存储的数据量是难以满足海量数据需求
RDB 持久化
全称 Redis Database Backup file (Redis 数据备份文件) , 也被叫做 Redis 数据快照,简单来说就是把内存中的所有数据记录到磁盘中,当 Redis 实例故障重启后,从磁盘读取快照文件,恢复数据,缺点就是由 Redis 主进程来执行 RDB ,会阻塞所有命令
其实 RDB 方案默认就开启了,只不过它是在服务端正常关闭时会自动执行一次
Redis 内部有触发 RDB 的机制,可以在 redis.conf 文件中找到
RDB 的 fork 原理
bgsave 开始时会 fork 主进程得到子进程,子进程共享主进程的内存数据。完成 fork 之后读取内存数据并写入到 RDB 文件
原理解析:首先准备一个物理内存,我们可以理解成为就是我们电脑里面的内存条,我们现在有一个 redis 的主进程,要是实现对 redis 的数据的读写,很定是在内存中操作,但是在 Linux 系统当中,所有的进程都没有办法直接操作物理内存,而是由操作系统给每一个进程分配一个虚拟内存,主进程只能操作虚拟内存,操作系统会维护一个虚拟内存与物理内存之间的一个映射关系表,这个表称之为页表,所以主进程操作虚拟内存,而虚拟内存通过页表的映射关系到我们的物理内存,这样就能实现对物理内存数据的读写了,而我们执行 fork 的时候,其实会去创建一个子进程,fork 的过程它不是把内存数据做拷贝,仅仅是把页表做拷贝,只是把那个映射关系拷贝给子进程,当子进程有了和主进程一样的映射关系之后,当子进程在操作自己的虚拟内存时,因为映射关系和主进程一样,所以最后会和主进程一样映射到最终的物理内存上
fork 采用的是 copy-on-write 技术
当主进程执行读操作的时候,访问共享内存
当主进程执行写操作的时候,则会拷贝一份数据,执行写操作
如果非要写数据,那么这个时候主进程就必须先拷贝一个数据,然后再去完成写操作,当然一旦完成了拷贝的操作,那么以后的读操作月就只能在拷贝的这个文件中去操作了,这就是 copy-on-write 的原理,但是如果这个情况下的写操作太频繁的话,这个时候对内存就会造成一个不小的负荷,每一次拷贝都是对内存占用的一次翻倍,所以 redis 一般情况下都要预留一些内存空间
RDB 总结
RDB 方式 bgsave 的基本流程
-
fork 主进程得到一个子进程,共享内存空间
-
子进程读取内存数据并写入新的 RDB 文件
-
用新的 RDB 文件替换旧的 RDB 文件
RDB 会在什么时候执行
-
save 会在服务停机的那一刻执行
-
bgsave 就要看 redis.conf 文件中的 save 参数是怎么设置的了
RDB 的缺点
-
RDB 执行的时间间隔太长,两次 RDB 之间可能会造成数据丢失的风险
-
fork 子进程,压缩,写出 RDB 文件都比较耗时
AOF 持久化
全称 Append Only File (追加文件) 。Redis 处理的每一个写命令都会记录在 AOF 文件,可以看做是命令日志文件
AOF 默认是关闭的 ,需要修改 redis.conf 配置文件来开启 AOF
# 是否开启 AOF 功能,默认是 no
appenddonly yes
# AOF 文件名称
appendfilename ”appenddonly。aof"
AOF 的命令记录的频率也可以通过 redis.conf 文件来配置
# 表示每执行一次写命令,立即记录到 AOF 文件 (性能较差)
appendafsync always
# 写命令执行完先放入 AOF 缓冲区,然后表示每间隔 1 秒将缓冲区的数据写入到 AOF 文件,是默认方案
appendfsync everysec
# 写命令执行完先放入 AOF 缓冲区,由操作系统来决定何时将缓冲区内容写回磁盘
appendfsync no
配置项 | 刷盘时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步刷盘 | 可靠性高,几乎不会丢数据 | 性能影响大 |
everysec | 每秒刷盘 | 性能适中 | 最多丢失 1 秒数据 |
no | 操作系统控制 | 性能最好 | 可靠性较差,可能丢失大量数据 |
bgrewriteaof
因为是记录命令,AOF 文件会比 RDB 文件大的多,而且 AOF 会记录对同一个 key 的多次写操作,但只有最后一次写操作才有意义,通过执行 bgrewriteaof 命令,可以让 AOF 文件执行重写功能,用最少的命令达到一样的效果
Redis 也会在触发阀值时自动去重写 AOF 文件,阀值也可以在 redis.conf 中配置
# AOF 文件比上次文件增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF 文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
RDB AOF 总结
RDB | AOF | |
---|---|---|
持久化方式 | 定时对整个内存做快照 | 记录每一次命令的执行 |
数据完整性 | 不完整,两次备份之间肯可能会丢失数据 | 相对完整取决都刷盘策略 |
文件大小 | 会有压缩,文件体积小 | 记录命令,文件体积过大 |
当即恢复速度 | 很快 | 慢 |
数据恢复优先级 | 低,因为数据完整性不如 AOF | 高,因为数据完整性更高 |
系统资源占用 | 高,大量 CPU 和内存消耗 | 低,因为是磁盘 IO 资源,但 AOF 重写时会占用大量 CPU 和内存资源 |
使用场景 | 可以容忍数分钟的数据丢失,最求更快的启动速度 | 对数据安全性要求较高常见 |