Redis
是一个基于内存的非关系型的数据库,数据保存在内存中,可是内存中的数据也容易发生丢失。这里Redis就为咱们提供了持久化的机制,分别是
RDB(Redis DataBase)
和
AOF(Append Only File)
。
Redis在之前的版本中是单线程的,而在6.0后对Redis的io模型作了优化,io Thread
为多线程的,可是worker Thread
仍然是单线程。redis
在Redis启动的时候就会去加载持久化的文件,若是没有就直接启动,在启动后的某一时刻由继续持久化内存中产生的数据。数据库
接下来咱们就来详细了解Redis的两种持久化机制RDB(Redis DataBase)
和AOF(Append Only File)
。缓存
什么是RDB持久化呢?RDB持久化就是将当前进程的数据以生成快照的形式持久化到磁盘中。对于快照的理解,咱们能够理解为将当前线程的数据以拍照的形式保存下来。安全
RDB持久化的时候会单独fork一个与当前进程一摸同样的子进程来进行持久化,所以RDB持久化有以下特色:bash
开机恢复数据快。服务器
写入持久化文件快。多线程
RDB的持久化也是Redis默认的持久化机制,它会把内存中的数据以快照的形式写入默认文件名为dump.rdb
中保存。app
在安装后的Redis中,Redis的配置都在redis.conf
文件中,以下图所示,dbfilename
就是配置RDB的持久化文件名。
异步
在RDB机制中触发内存中的数据进行持久化,有如下三种方式:ide
(1)save命令:
save命令不会fork子进程,经过阻塞当前Redis服务器,直到RDB完成为止,因此该命令在生产中通常不会使用。save命令执行原理图以下:
dir
的配置就是RDB持久化后生成rdb二进制文件所在的位置,默认的位置是
./
,表示当前位置,哪里启动redis,就会在哪里生成持久化文件,以下图所示:
/root/redis-4.0.6/src/redis-server /root/redis-4.0.6/redis.conf
接着经过该命令:ps -aux | grep redis
,查看咱们的redis服务是否正常启动,如果显示以下图所示,则表示Redis是正常启动的:
save
命令,在该文件夹下就会出现
dump.rdb
持久化的数据文件。
./
文件,通常咱们会把它改为服务器本身的特定位置下,原理都是同样的,能够本身进行尝试,这里再也不进行演示。
(2)bgsave命令:
bgsave
命令会在后台fork一个与Redis主线程一摸同样的子线程,由子线程负责内存中的数据持久化。
这样fork与主线程同样的子线程消耗了内存,可是不会阻塞主线程处理客户端请求,是以空间换时间的方式快照内存中的数据到到文件中。
bgsave
命令阻塞只会发生在fork子线程的时候,这段时间发生的很是短,能够忽略不计,以下图是 bgsave执行的流程图:
dir
配置是配置持久化文件生成的指定的目录,
dbfilename
是配置生成的文件名,也能够经过命令行使用命令来动态的设置这两个配置,命令以下:
config set dir{newDir}
config set dbfilename{newFileName}
(3)自动化
除了上面在命令行使用save和bgsave命令触发持久化,也能够在redis.conf
配置文件中,完成配置,以下图所示:
save 900 1
表示900秒内若是至少有1个key值变化,则进行持久化保存数据;
save 300 10
则表示300秒内若是至少有10个key值发生变化,则进行持久化,save 60 10000
以此类推。
经过以上的分析能够得出如下save和bgsave的对比区别:
save是同步持久化数据,而bgsave是异步持久化数据。
save
不会fork子进程,经过主进程持久化数据,会阻塞处理客户端的请求,而bdsave
会fork
子进程持久化数据,同时还能够处理客户端请求,高效。
save不会消耗内存,而bgsave会消耗内存。
缺点: RDB持久化后的文件是紧凑的二进制文件,适合于备份、全量复制、大规模数据恢复的场景,对数据完整性和一致性要求不高,RDB会丢失最后一次快照的数据。
优势: 开机的恢复数据快,写入持久化文件快。
AOF持久化机制是以日志的形式记录Redis中的每一次的增删改操做,不会记录查询操做,以文本的形式记录,打开记录的日志文件就能够查看操做记录。
AOF是默认不开启的,如果像开启AOF,在以下图的配置修改便可:
appendonly no
修改成
appendonly yes
便可开启,在AOF中经过
appendfilename
配置生成的文件名,该文件名默认为
appendonly.aof
,路径也是经过dir配置的,这个于RDB的同样,具体的配置信息以下图所示:
AOF带来的持久化更加安全可靠,默认提供三种触发机制,以下所示:
no
:表示等操做系统等数据缓存同步到磁盘中(快、持久化没保证)。
always
:同步持久化,每次发生数据变动时,就会当即记录到磁盘中(慢,安全)。
everysec
:表示每秒同步一次(默认值,很快,可是会丢失一秒内的数据)。
AOF中每秒同步也是异步完成的,效率是很是高的,因为该机制对日志文件的写入操做是采用append
的形式。
所以在写入的过程即便宕机,也不会丢失已经存入日志文件的数据,数据的完整性是很是高的。
在新安装的Redis的配置文件中,AOF的配置以下所示:
可是,在写入全部的操做到日志文件中时,就会出现日志文件不少重复的操做,甚至是无效的操做,致使日志文件愈来愈大。
所谓的无效的的操做,举个例子,好比某一时刻对一个k++,而后后面的某一时刻k--,这样k的值是保持不变的,那么这两次的操做就是无效的。
若是像这样的无效操做不少,记录的文件臃肿,就浪费了资源空间,因此在Redis中出现了rewrite
机制。
redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
重写AOF的日志文件不是读取旧的日志文件瘦身,而是将内存中的数据用命令的方式重写一个AOF文件,从新保存替换原来旧的日志文件,所以内存中的数据才是最新的。
重写操做也会fork
一个子进程来处理重写操做,重写之内存中的数据做为重写的源,避免了操做的冗余性,保证了数据的最新。
在Redis以append的形式将修改的数据写入老的磁盘中 ,同时Redis也会建立一个新的文件用于记录此期间有哪些命令被执行。
下面进行演示一下AOF的操做,首先先打开AOF机制,修改配置文件中的appendonly no
为appendonly yes
,而后执行以下图的操做:
appendonly.aof
key *
映射到该配置文件中的命令以下:
*2 //表示该命令两组key 为一组 * 为一组
$6 //表示SELECT有6字符
SELECT
$1 //表示下面的0一个字符
0
而后执行set k1 1
的命令,此命令映射到文件中的命令以下:
*3 //表示该命令有三组set为一组 k1为一组 1为一组
$3 // 表示set有三个字符
set // 表示执行了set命令
$2 // 表示k1有两个字符
k1 // key值
$1 // 即是value值的字符长度为1
1 // value值
当AOF的日志文件增加到必定大小的时候Redis就可以bgrewriteaof对日志文件进行重写瘦身。当AOF配置文件大于改配置项时自动开启重写(这里指超过原大小的100%)。
该配置能够经过以下的配置项进行配置:
优势: AOF更好保证数据不会被丢失,最多只丢失一秒内的数据,经过foek一个子进程处理持久化操做,保证了主进程不会进程io操做,能高效的处理客户端的请求。
另外重写操做保证了数据的有效性,即便日志文件过大也会进行重写。
AOF的日志文件的记录可读性很是的高,即便某一时刻有人执行flushall
清空了全部数据,只须要拿到aof的日志文件,而后把最后一条的flushall给删除掉,就能够恢复数据。
缺点: 对于相同数量的数据集而言,AOF文件一般要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。AOF在运行效率上每每会慢于RDB。
在redis4.0后混合持久化(RDB+AOF)对重写的优化,4.0版本的混合持久化默认是关闭的,能够经过如下的配置开启混合持久化:
bgrewriteaof
来完成的,不一样的是当开启混合持久化时,fork出的子进程先将共享内存的数据以RDB方式写入aof文件中,而后再将重写缓冲区的增量命令以AOF方式写入文件中。
写入完成后通知主进程统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的AOF文件。简单的说:新的AOF文件前半段是以RDB格式的全量数据后半段是AOF格式的增量数据。
优势: 混合持久化结合RDB持久化和AOF持久化的优势,因为绝大部分的格式是RDB格式,加载速度快,增量数据以AOF方式保存,数据更少的丢失。
rdb适合大规模的数据恢复,因为rdb时异快照的形式持久化数据,恢复的数据快,在必定的时间备份一次,而aof的保证数据更加完整,损失的数据只在秒内。
具体哪一种更适合生产,在官方的建议中两种持久化机制同时开启,若是两种机制同时开启,优先使用aof持久化机制。