在这篇文章,我们一起了解 redis 使用中非常重要的两个机制:Reids 持久化和主从复制 。
文章插图
图片来自 Unsplash
什么是 Redis 持久化?
Redis 作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客户端请求时,所有操作都在内存当中进行,如下所示:
文章插图
这样做有什么问题呢?其实,只要稍微有点计算机基础知识的人都知道,存储在内存当中的数据,只要服务器关机(各种原因引起的),内存中的数据就会消失了 。
不仅服务器关机会造成数据消失,Redis 服务器守护进程退出,内存中的数据也一样会消失 。
文章插图
对于只把 Redis 当缓存来用的项目来说,数据消失或许问题不大,重新从数据源把数据加载进来就可以了 。
但如果直接把用户提交的业务数据存储在 Redis 当中,把 Redis 作为数据库来使用,在其放存储重要业务数据,那么 Redis 的内存数据丢失所造成的影响也许是毁灭性 。
为了避免内存中数据丢失,Redis 提供了对持久化的支持,我们可以选择不同的方式将数据从内存中保存到硬盘当中,使数据可以持久化保存 。
文章插图
Redis 提供了 RDB 和 AOF 两种不同的数据持久化方式,下面我们就来详细介绍一下这种不同的持久化方式吧 。
RDB
RDB 是一种快照存储持久化方式,具体就是将 Redis 某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为 dump.rdb,而在 Redis 服务器启动时,会重新加载 dump.rdb 文件的数据到内存当中恢复数据 。
①开启 RDB 持久化方式
开启 RDB 持久化方式很简单,客户端可以通过向 Redis 服务器发送 Save 或 Bgsave 命令让服务器生成 RDB 文件,或者通过服务器配置文件指定触发 RDB 条件 。
save 命令:是一个同步操作 。
# 同步数据到磁盘上 > save
文章插图
当客户端向服务器发送 Save 命令请求进行持久化时,服务器会阻塞 Save 命令之后的其他客户端的请求,直到数据同步完成 。
如果数据量太大,同步数据会执行很久,而这期间 Redis 服务器也无法接收其他请求,所以,最好不要在生产环境使用 Save 命令 。
Bgsave:与 Save 命令不同,Bgsave 命令是一个异步操作 。
# 异步保存数据集到磁盘上 > bgsave
文章插图
当客户端发服务发出 Bgsave 命令时,Redis 服务器主进程会 Forks 一个子进程来数据同步问题,在将数据保存到 RDB 文件之后,子进程会退出 。
所以,与 Save 命令相比,Redis 服务器在处理 Bgsave 采用子线程进行 IO 写入 。
而主进程仍然可以接收其他请求,但 Forks 子进程是同步的,所以 Forks 子进程时,一样不能接收其他请求 。
这意味着,如果 Forks 一个子进程花费的时间太久(一般是很快的),Bgsave 命令仍然有阻塞其他客户的请求的情况发生 。
服务器配置自动触发:除了通过客户端发送命令外,还有一种方式,就是在 Redis 配置文件中的 Save 指定到达触发 RDB 持久化的条件,比如【多少秒内至少达到多少写操作】就开启 RDB 数据同步 。
例如我们可以在配置文件 redis.conf 指定如下的选项:
# 900s内至少达到一条写命令 save 900 1 # 300s内至少达至10条写命令 save 300 10 # 60s内至少达到10000条写命令 save 60 10000 之后在启动服务器时加载配置文件 。
# 启动服务器加载配置文件 redis-server redis.conf 这种通过服务器配置文件触发 RDB 的方式,与 Bgsave 命令类似,达到触发条件时,会 Forks 一个子进程进行数据同步 。
不过最好不要通过这方式来触发 RDB 持久化,因为设置触发的时间太短,则容易频繁写入 RDB 文件,影响服务器性能,时间设置太长则会造成数据丢失 。
②RDB 文件
前面介绍了三种让服务器生成 RDB 文件的方式,无论是由主进程生成还是子进程来生成,其过程如下: