Redis 用作缓存,其特点之一就是数据可以丢,只需要保证其响应急速,性能较高!
但是如果把 Redis 做数据库:数据绝对不能丢的,所以除了保证其速度之外,还必须保证其持久性,数据一定不可以丢失
而我们知道 Redis 处于内存,内存数据掉电易失!所以如果想要使用 Redis 作为数据库,必须要保证其持久性
只要是存储层,为了保证数据安全,都会有如下两个通用的功能:
快照/副本:记录某一时刻数据库中所有的正确数据状况。可以保存在本地主机,也可以拷贝到另一台远程主机,一旦出现断电,甚至服务器瘫痪,也可以根据快照恢复某一时刻的正常数据日志:用户发生增删改的时候,所有的操作都会记录到一个日志文件。如果周一数据正常,周二系统上线新功能出现一个致命错误,造成大量资金损失,此时可以将系统紧急停服,根据日志将数据回滚到一个正常状态官网持久化介绍:http://redis.cn/topics/persistence.html
Redis 提供了不同级别的持久化方式:
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.最重要的事情是了解RDB和AOF持久化方式的不同,这也是面试高频,下面我们就来详细学习以下 RDB 和 AOF
RDB 全称 redis database,在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的 Snapshot 快照,它恢复时直接将快照文件直接读到内存里;
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,主进程是不进行任何 IO操作的,它就确保了极高的性能;RDB 文件是在硬盘上的二进制文件,是 Redis 在内存存储的数据在某一时刻的快照
系统中不可能每分每秒都进行快照存储,这样会大量占用系统资源且毫无意义,所以运维人员一般会定时保存快照
假设使用 RDB 每一小时进行一次快照存储,假设一个正常系统的快照文件大小有 10 G,肯定不可能瞬时就能保存到磁盘,那么快照存储该如何实现呢?我们最先想到的一种方式如下图:
阻塞保存快照:Redis 主进程阻塞,不再对外提供服务,只进行快照的持久化。这种方式能保证快照的时点性,但是会导致服务停用,这种情况生产环境不会允许发生。所以我们就想让 Redis 一边提供服务,一边进行快照的持久化,处理过程如下:
非阻塞保存快照:会导致时点混乱,无法保存正确的快照信息,导致数据不一致
那么 RDB 究竟是如何进行持久化呢?——主进程非阻塞继续提供服务,同时 fork 出子进程进行持久化,处理流程如下:
fork 子进程保存快照:Redis 主进程继续对外提供服务,同时 fork 出子进程进行快照持久化。在持久化期间,客户端对主进程的修改对于 fork 出的子进程是看不到的,所以能够保证快照的时点性,不会发生混乱
补充:fork 是怎么实现的?或者说使用 fork 有什么优势?
fork 创建子进程不会发生数据的复制,只是会创建引用指针,这样创建子进程的时候,速度特别快;
只有发生写操作时才会触发复制,即 copy on write (写时复制)机制,不会发生全量的数据修改
fork() 创建子进程优势:
创建子进程时只需要创建指针引用,不需要数据复制,创建速度快并不是全量复制数据,占用空间小RDB 流程:
上面理论学习完之后,Redis 是怎么完成以 RDB 进程持久化的呢?
人为触发:可以通过两个指令人为触发 save:前台阻塞,不再提供服务,只进行快照持久化。较少使用,使用场景明确——只有明确什么时间会关机停服维护的时候才可能用到bgsave:后台异步非阻塞,fork 创建子进程完成快照的持久化 配置文件配置 bgsave 规则: save 60 10000:时间达到 60 秒,或者写操作数达到 10000 次,两者满足其一,就会触发 RDBsave 300 10:时间达到 300 秒,或者写操作到达 10 次,两者满足其一,就会触发 RDBsave 900 1:时间达到 900 秒,或者写操作数达到 1 次,两者满足其一,就会触发 RDB根据系统的并发量、高峰时点等等灵活设置总结:
AOF 即 Append-only file,使用追加写操作
如果说 RDB 是类似于快照/副本,那么 AOF 就是类似于日志。AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录。而且是以文本的方式记录,可以打开文件看到详细的操作记录
redis中,RDB和AOF可以同时开启,如果开启了AOF只会用AOF恢复
因为 AOF 是追加写,只要服务器不停,日志文件就会无限膨胀。假设 redis 服务运行了10年,AOF文件可能达到数十G,甚至数十T大小,此时可能导致内存溢出,而且根据这么大的文件中的指令一条一条的进行数据恢复,耗时将会很长
所以在 Redis 4.0 以后,AOF是一个混合体,将老的数据以 RDB 方式保存到 AOF 文件中,将增量的以指令的方式 Append 到AOF。既利用了 RDB 的快速,又保证了AOF日志的全量
既然作为数据库,那么每次的写操作都应该要保存下来,任何一条增删改操作都不能丢失。但是写操作都会触发IO,频繁的 IO 将会拖慢 redis 的速度,所以 Redis 中对于写操作有三种级别:
无 fsync:不进行同步(不安全)每秒 fsync:每秒进行一次同步(默认方式,既保证数据丢失量少,而且速度不算慢,性能比较均衡)每次写的时候 fsync:每次写操作都进行一次同步(频率过高,拖慢速度)关联文章:
Redis入门–万字长文详解epoll
Redis——详解五种数据结构
Redis——Redis的进阶使用(管道/发布订阅/事务/布隆过滤器)
Redis——Redis用作缓存(内存回收/穿透/击穿/雪崩)