前言
最近的学习中,荔枝深入了解了Redis的持久化、Redis事务相关的知识点并整理相应的学习笔记,在这篇文章中荔枝也主要梳理了相应的笔记和基本知识,小伙伴们如果需要的话可以看看哈。
文章目录
一、Redis持久化
首先来看看官网的描述:Persistence refers to the writing of data to durable storage, such as a solid-state disk (SSD).翻译过来就是redis持久化其实就是将内存中的数据写入到磁盘中,之所有需要持久化的原因是Redis是一种内存数据库,而内存在断电或服务器宕机后所有的数据将会被清空而导致恢复功能时原来的请求依旧大规模的发到mysql服务器上,所以这时候就需要持久化来使得缓存中的数据长期持有。官网中提出了四种Redis持久化的模式:RDB、AOF、No persistence和RDB+AOF。
1.1 RDB
Redis Database即RDB,按指定的时间间隔执行数据集的时间点快照。换句话说就是Redis以指定的时间点间隔执行数据集的时间点快照。实现类似照片记录效果的方式,就是把某一时刻的数据和状态以文件的形式写到磁盘上,也就是Snapshot内存快照。这样一来即使故障宕机,快照文件也不会丢失,数据的可靠性也就得到了保证。这个快照文件就称为RDB文件(dump.rdb),其中,RDB就是Redis DataBase的缩写。
1.1.1 Redis7前后snapshot时间配置的区别
这个时间点的设置在Redis6和Redis7中又有不同,其中Redis6在redis.conf配置文件中默认有如下三个配置:save 900 1 | save 300 10 | save 60 10000。save 900 1指的是在15min中如果有一个key发生变化就写一份新的RDB文件。而在redis7以后可以看到对于该时间也做出了相应的修改:save 3600 1 300 100 60 10000。
1.1.2 RDB的操作
自动触发——修改redis.conf文件
修改触发时间和条件:10秒钟2次
save 10 2
修改dump.rdb文件的保存路径
dir ./ ---> dir /myredis/dumpfiles
修改dump.rdb文件的名称
dbfilename dump6379.rdb
重启一下
查看配置详情:config get
config get dir
需要注意的是触发备份主要有两种情况来产生:一种是在指定时间内达到一定的频率;第二种是在不同的时间间隔中触发的。
现在我们尝试使用flushall/fiushdb来清空数据库的时候,会产生一个新的空dump.rdb文件,在再次重启后不再使用原来记录数据的dump.rdb文件。这就需要我们将有备份文件dump.rdb和生产redis服务器放在不同的机器上,必须分开各自存储以防止生产机物理损坏后备份文件也挂了。
手动触发
Redis提供了两个命令来手动生成RDB文件,分别是save和bgsave。我们默认使用的是bgsave,这是因为使用save会在主程序中执行会阻塞当前redis服务器,直到持久化工作完成,执行save命令期间,Redis不能处理其他命令,线上禁止使用。而对于bgsave,Redis会在后台异步进行快照操作,不阻寒快照同时还可以响应客户端请求,该触发方式会fork一个子进程由子进程复制持久化过程。
Linux下时间戳格式变换: data -d @时间戳
在Redis中我们可以通过lastsave获得最后一次保存的时间戳
触发RDB快照的几种情况:
- 配置文件中默认的快照配置
- 手动save/bgsavei命令
- 执行flushall/flushdbi命令也会产生dump.rdb文件,但里面是空的,无意义
- 执行shutdown.且没有设置开启AOF持久化
- 主从复制时,主节点自动触发
1.1.3 优缺点
优点:
- 适合大规模的数据恢复
- 按照业务定时备份
- 对数据完整性和一致性要求不高
- RDB文件在内存中的加载速度要比AOF快得多,因为其派生了一个子进程来进行持久化的操作,父进程永远不会执行磁盘IO操作
缺点:
- 由于RDB是按照一定的时间点或者修改频率来进行备份的,因此在Redis服务器突然停止工作的时候可能会丢失最新分钟的数据。
- RDB需要使用fork()来将数据持久化到磁盘中,如果数据集比较大,那么这个fork可能会比较耗时并导致Redis对客户端的服务停止几毫秒甚至一秒钟。AOF也需要fork()但频率较低,您可以调整要重写日志的频率,而不需要对持久性进行任何权衡。
- 内存数据的全量同步,如果数据量太大会导致/0严重影响服务器性能
1.1.4 检查并修复RDB文件
Redis在安装后提供了一个软链接,跟redis-server类似,可以使用redis-check-rdb来自动纠错并修复rdb文件。
redis-check-rdb /myredis/dumpfiles/dump6379.rdb
1.1.5 RDB快照禁用
本次禁用,动态所有停止RDB保存规则的方法:redis-cli config set save “”
快照禁用,配置文件配置save “”
1.1.6 RDB配置文件参数详解
- save <seconds><changes>:配置快照触发条件
- dbfilename:redis快照文件的名称
- dir:redis快照文件的存储路径
- stop-writes-on-bgsave-error:配置当后台快照写入出错的时候是否需要停止redis接收新的写请求,涉及的是数据一致性的问题,默认使用yes。
- rdbcompression:对于存储在磁盘中的快照是否消耗CPU来进行压缩存储,默认是yes
- rdbchecksum:在存储快照后,还可以让rdis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能
- rdb-del-sync-files:在没有持久性的情况下删除复制中使用的RDB文件启用。默认情况下o,此选项是禁用的。
1.2 AOF
Append Only File即AOF,记录服务器收到的每个写入操作。然后可以在服务器启动时再次重播这些操作,重建原始数据集,命令的记录格式与 Redis 协议本身相同。以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
默认情况下,redis是没有开启AOF(append only file)的。开启AOF功能需要设置配置:appendonly yes
1.2.1 AOF持久化流程
三种写回策略
Always:总是在写回,同步写回,每个写命令执行完立刻同步地将日志写回磁盘;
everysec:每隔一秒写回,每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔1秒把缓冲区中的内容写入磁盘;
no:不写回。操作系统控制的写回,每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘;
1.2.2 配置文件以及参数
//开启
appendonly yes
//设置写回策略---这里一般采用的是默认的配置
appendfsync everysec
//文件保存路径
redis6:AOF和RDB保存文件的位置一样,都是在redis.conf中来配置文件的dir配置
redis7:会在dir配置的文件路径下使用appenddirname "appendonlydir"中的文件夹名字,再在该文件夹中储存appendonly.aof文件
//aof文件名字
redis6:appenddirname "appendonlydir"
redis7:采用的是Multi Part AOF的设计
使用了base基本文件、incr增量文件以及manifest清单文件
//如有下的aof文件存在
1.基本文件
appendonly.aof.1.base.rdb
2.增量文件
appendonly.aof.1.incr.aof
appendonly.aof.2.incr.aof
3.清单文件
appendonly.aof.manifest
- BASE:表示基础AOF,它一般由子进程通过重写产生,该文件最多只有一个。
- INCR:表示增量AOF,它一般会在AOFRW开始执行时被创建,该文件可能存在多个。
- HISTORY:表示历史AOF,它由BASE和INCR AOF变化而来,每次AOFRW成功完成时本次AOFRW之前对应的BASE和INCR AOF都将变为HISTORY,HISTORY类型的AOF会被Redis自动删除。
为了管理这些AOF文件,我们引入了一个manifest(清单)文件来跟踪管理这些AOF。同时,为了便于AOF备份和拷贝,我们将所有的AOF文件和manifest.文件放入一个单独的文件目装中,目录名由appenddirname配置(Redis7.0新增配置项)决定。
需要注意的是:在我们执行写操作命令的时候一般是incr.aof文件来记录。
1.2.3 AOF的恢复
正常恢复
在Redis关机后,同RDB一样会重新创建一个appendonly.aof文件并在再次开启Redis服务器是进行写回操作。
异常恢复当AOF文件写入出现异常时,通过手动模拟乱写aof文件,在关机重启后发现redis无法启动,可以通过redis-check-aof 这个修复工具类来修复。
redis-check-aof --fix 需要修复的incr.aof文件
1.2.4 AOF的优缺点
优势:能够更好的保护数据不丢失,性能高、可做紧急恢复
劣势:
- 相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb,AOF文件通常比相同数据集的RDB文件慢,一般来说将fsync设置为每秒性能仍然非常高,并且在禁用fsyc的情况下,即使在高负载下它也应该与RDB一样快。即使在巨大的写入负载的情况心,RDB仍然能够提供关于最大延迟的更多保证。
- aof运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同
1.2.5 AOF的重写机制
由于AOF持久化是Redis不断将写命令记录到AOF文件中,随着Redis不断的进行,AOF的文件会越来越大,文件越大,占用服务器内存越大以及AOF恢复要求时间越长。为了解决这个问题,Redis新增了重写机制,当AOF文件的大小超过所设定的峰值时,Redis就会自动启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集或者可以手动使用命令bgrewriteaof来重新。
自动触发重写机制的配置
auto-aof-rewrite-percentage 100 //达到的内存百分比
auto-aof-rewrite-min-size 64mb //设定的AOF文件的内存阈值
超过了设定的阈值之后会重新生成base.aof文件以及incr.aof文件,并将内容压缩后的最小指令集记录在新的base文件中。
手动触发重写机制
bgrewriteaof
也就是说AOF文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的AOF文件。
1.2.6 AOF的常见配置参数
//是否开启aof
appendonly yes
//文件名称
appendfilename "appendonly.aof"
//同步方式
appendfsync everysec/always/no
//aof重写期间是否同步
no-appendfsync-on-rewrite no
//重写触发配置、文件重写策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
1.3 RDB和AOF的混合持久化
appendonly配置参数设置为true后AOF开启,此时Redis数据恢复使用AOF文件。也就是说,在同时开启rdb和aof持久化时,重启时只会加载aof文件,不会加载rdb文件。
特性比较
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。
如何选择?
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文供保存的数据集要完整,RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。但是也建议不要只使用AOF,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),留着RDB作为一个万一的手段。因此推荐的方法就是RDB+AOF混合持久化的方式来实现Redis中数据的持久化。
混合持久化:RDB镜像做全量持久化,AOF做增量持久化
先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,既保证了数据完整性,又提高了恢复数据的性能。简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。AOF包括了RDB头部+AOF混写。
纯缓存模式:在高并发场景下使用为了更高的性能关闭了持久化的功能,也就是禁用了RDB和AOF
二、事务
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。相比于mysql数据库事务有单独的隔离操作,同时没有隔离级别的概念,具备排他性但不保证原子性。
单独的隔离操作
Redis的事务仅仅是保证事务里的操作会被连续独占的执行,redis命令执行是单线程架构,在执行完事务内所有指令前是不可能再去同时执行其他客户端的请求的 。
不保证原子性
Rdis的事务不保证原子性,也就是不保证所有指令同时成功或同时失败,只有决定是否开始执行全部指令的能力,没有执行到一半进行回滚的能力
排他性
Redis会保证一个事务内的命令依次执行,而不会被其它命令插入。
2.1 常见指令
//取消事务,放弃执行事务块内的所有命令
DISCARD
//执行所有事务块内
EXEC
//标记一个事务块的开始
MULTI
//取消NATCH命令对所有key的监视
UNWATCH
//监视一个(或多个)key,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断
WATCH key [key...]
Reds不提供事务回滚的功能,开发者必须在事务执行出错后,自行恢复数据库状态
2.2 监控
Redis使用Watch来提供乐观锁定,类似于CAS。
悲观锁(Pessimistic Lock):每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会bock直到它拿到锁。
乐观锁(Optimistic Lock):每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据。提交版本必须大于记录当前版本才能执行更新
简单理解watch的过程就是:在一次事务的提交过程中,Redis使用watch来监控每一个操作的key,一旦在本次事务中Redis监控发现key被别的事务发生修改,本次事务就会作废并等待重新的事务提交。而对于监控的生命期在于一旦执行了exec之前加的监控锁都会被取消,当客户端连接丢失的时候(比如退出链接),所有东西都会被取消监视。
总结
在这篇文章中,荔枝主要梳理了有关Redis持久化和Redis事务的基本概念和原理,希望能对正在学习的小伙伴有些许的帮助~最近状态不错,荔枝要继续加油保持学习,快乐的暑假嘿嘿嘿~~~
今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,麻烦举起小爪爪点个赞吧哈哈哈~~~ 比心心♥~~~