本文的脑图Redis是一个基于内存的非关系型数据库。数据保存在内存中,但是内存中的数据也容易丢失。这里Redis为我们提供了持久化机制,即RDB(RedisDataBase)和AOF(AppendOnlyFile)。Redis在之前的版本中是单线程的,但是在6.0之后,优化了Redis的io模型。ioThread是多线程的,但是workerThread还是单线程的。当Redis启动时,它会加载持久化文件。如果没有,它将直接启动。在启动后的某个时刻,它会继续持久化内存中产生的数据。接下来我们来详细了解一下Redis的两种持久化机制RDB(RedisDataBase)和AOF(AppendOnlyFile)。RDB持久化机制什么是RDB持久化?RDB持久化就是将当前进程的数据以快照的形式持久化到磁盘。对于快照的理解,我们可以理解为以拍照的形式保存当前线程的数据。RDB在持久化时,会单独fork一个和当前进程一模一样的子进程进行持久化。因此,RDB持久化具有以下特点:开机后数据恢复快。写入持久文件很快。RDB的持久化也是Redis默认的持久化机制。它会将内存中的数据以快照的形式保存在默认文件dump.rdb中。在安装好的Redis中,Redis的配置在redis.conf文件中,如下图,dbfilename是配置RDB的持久化文件名。持久化触发时机在RDB机制中,内存中的数据被触发持久化。有三种方式:(1)save命令:save命令不会fork子进程,阻塞当前Redis服务器,直到RDB完成,所以在生产中一般不会使用该Commands。save命令的执行示意图如下:在redis.conf的配置中,dir的配置是RDB持久化后生成rdb二进制文件的位置。默认位置是./,表示当前位置。redis启动的地方,会在那里生成Persistent文件,如下图:下面做一个实际操作来演示生成二进制文件的过程。在我本地电脑虚拟机中,我的位置如下。这个文件夹就是新建的redis数据存储文件夹。然后我们直接在这个位置启动我们的Redis服务,启动命令如下:/root/redis-4.0.6/src/redis-server/root/redis-4.0.6/redis.conf然后通过这个命令:ps-辅助|grepredis,查看我们的redis服务是否正常启动,如果显示如下图,说明Redis正常启动:正常启动后,直接登录Redis,可以通过以下方式登录Redis命令,如下图:因为目前Redis是新安装的,数据是空的,什么都没有,然后通过下图的命令输入几个命令到Redis中,最后执行保存命令,dump.rdb会一直出现在这个文件夹格式化的数据文件中。当然,如前所述,在新安装的Redis中,默认的RDB数据持久化位置是./file。一般我们会改成服务器本身的具体位置。原理是一样的。大家可以自己试试,这里就不演示了。(2)bgsave命令:bgsave命令会在后台fork出一个与Redis主线程完全相同的子线程,该子线程负责数据在内存中的持久化。这样fork的子线程和主线程消耗内存,但不会阻塞主线程处理客户端请求,内存中的数据以空间换时间的方式快照到文件中。bgsave命令阻塞只会在fork子线程发生时发生。这段时间很短,可以忽略不计。下图是bgsave执行的流程图:上面提到的redis.conf中的dir配置是配置持久化文件的生成指定的目录,dbfilename是配置生成的文件名,这两个配置也可以是动态的通过命令行设置。命令如下:save和bgsave命令触发持久化,配置也可以在redis.conf配置文件中完成,如下图所示:在新安装的redis中,以上三个save配置被使用默认,而save9001表示在900秒内如果至少有一个key值发生变化,则数据会被持久化;save30010表示如果300秒内至少有10个键值改变,则数据会被持久化,save6010000等等。通过上面的分析,我们可以得出以下save和bgsave的对比和区别:save是同步持久化数据,而bgsave是异步持久化数据。save不会fork子进程,通过主进程持久化数据,会阻塞客户端请求的处理,而bdsave会fork子进程持久化数据,也可以处理客户端请求,效率高。save不消耗内存,而bgsave消耗内存。RDB的优缺点缺点:RDB持久化文件是紧凑型二进制文件,适用于备份、全量复制、大规模数据恢复场景。对数据完整性和一致性要求不高,RDB会丢失最后的快照。数据。优点:启动时快速恢复数据,快速写入持久化文件。AOF持久化机制AOF持久化机制以日志的形式记录Redis中的每一次增删改查操作。它不记录查询操作,而是以文本的形式记录。您可以通过打开记录的日志文件来查看操作记录。默认情况下不启用AOF。如果要开启AOF,可以修改下图的配置:将appendonlyno改为appendonlyyes即可开启。在AOF中,配置appendfilename生成的文件名。默认文件名是appendonly.aof,路径也是通过dir配置的,和RDB一样。具体配置信息如下图所示:AOF触发机制AOF带来的持久化更加安全可靠。默认提供三种触发机制,如下图:no:表示操作系统等数据缓存同步到磁盘(不保证快速持久)。always:同步持久化,每次发生数据变化,都会立即记录到磁盘(慢,安全)。everysec:表示每秒同步一次(默认值,很快,但一秒内数据会丢失)。AOF中每秒的同步也是异步完成的,效率非常高,因为这种机制对日志文件的写操作是append的形式。因此,即使在写入过程中出现宕机,已经保存在日志文件中的数据也不会丢失,数据完整性非常高。在新安装的Redis配置文件中,AOF配置如下:AOF重写机制但是,在将所有操作写入日志文件时,日志文件中会出现很多重复操作,甚至是无效操作,导致日志文件变大越来越大。所谓无效操作,比如说,比如某个时刻一个k++,之后的某个时刻k--,使得k的值不变,那么这两个操作都是无效的。如果这样的无效操作很多,记录的文件就会臃肿,资源空间就会被浪费,所以Redis中出现了rewrite机制。Redis提供了bgrewriteaof命令。将内存中的数据以命令的形式保存到一个临时文件中,同时会fork出一个新的进程来重写该文件。重写AOF日志文件并不是读取旧的日志文件瘦身,而是通过命令将内存中的数据重写到一个AOF文件中,并保存替换原来的旧日志文件,所以内存中的数据就是最新的。重写操作也会派生一个子进程来处理重写操作。rewrite以内存中的数据作为rewrite的源头,避免了操作的冗余,保证了最新的数据。在Redis中,修改后的数据以append的形式写入旧磁盘,同时Redis还会新建一个文件来记录这期间执行了哪些命令。下面来演示一下AOF的操作。首先开启AOF机制,将配置文件中的appendonlyno修改为appendonlyyes,然后执行如下图所示的操作:均表明执行成功。用ls检查当前文件夹,最后会出现appendonly。.aof,AOF的数据持久化文件,通过cat命令查看内容:从上面存储的文件可以看出,每条命令都是很有规律的,比如第一个执行键*映射到配置文件的命令是as如下:*2//表示两组键为一组*为一组$6//表示SELECT有6个字符SELECT$1//表示后面的0和一个字符0然后执行setk11的命令,这个命令映射文件中的命令如下:*3//表示该命令有三组set为一组,k1为一组,1为一组$3//表示set有三个字符集//表示已经执行了set命令$2//表示k1有两个字符k1//key值$1//是value的字符长度value为11//valuevalue当AOF日志文件增长到一定的时候size,Redis可以通过bgrewriteaof重写日志文件来瘦身。当AOF配置文件大于修改后的配置项时,自动启用重写(这里指超过原来大小的100%)。这个配置可以通过如下配置项进行配置:AOF的优缺点优点:AOF更好的保证数据不会丢失,最多只丢失一秒内的数据,通过fork子进程来处理持久化操作,保证主进程不处理io操作,可以高效处理客户端请求。另外,重写操作保证了数据的有效性,即使日志文件过大,也会被重写。AOF日志文件的记录可读性很强。即使某个时刻有人执行flushall清除了所有的数据,你只需要拿到AOF日志文件,删除最后的flushall就可以恢复数据了。缺点:同样数量的数据集,AOF文件通常比RDB文件大。RDB在恢复大型数据集时比AOF更快。AOF在运行效率上往往比RDB慢。redis4.0之后,混合持久化(RDB+AOF)优化重写。默认情况下禁用4.0版混合持久性。可以通过如下配置开启混合持久化:混合持久化也是通过bgrewriteaof完成的,不同的是开启混合持久化时,fork子进程先将共享内存数据以RDB方式写入aof文件,然后写入AOF模式中将缓冲区重写到文件中的增量命令。写入完成后通知主进程统计信息,同时将旧的AOF文件替换为包含RDB格式和AOF格式的新AOF文件。简单来说:新的AOF文件前半部分是RDB格式的全量数据,后半部分是AOF格式的增量数据。优点:混合持久化结合了RDB持久化和AOF持久化的优点。由于格式多为RDB,加载速度快,增量数据采用AOF方式保存,数据丢失少。RDB和AOF的优缺点RDB适用于大规模数据恢复。由于RDB以快照的形式持久化数据,恢复数据速度快,并且可以在一定时间内备份??一次。AOF保证数据更完整,丢失数据只在秒级之内。具体哪个更适合生产,官方建议同时开启两种持久化机制。如果同时启用两种机制,则首选aof持久化机制。
