redis的RDB,AOF,事务,主从复制(二)

发布于 2021-04-22  472 次阅读


一,持久化RDB

一,RDB的概述
 
RDB的概念(Redis DataBase ):在指定的时间间隔内将内存中的数据集快照写入到磁盘中,它恢复时是将快照文件直接读到内存里
Redis会单独创建一个fork子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,再用这个临时文件替换上一次持久化好的文件,整个过程中主进程是不进行任何IO操作的,确保了它极高的性能
 
如果需要进行大规模的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效,RDB的缺点是最后一次持久化后的数据可能丢失

Fork的作用:复制一个与但前主进程一样的进程,新进程的所有数据(变量,环境变量,程序计数器等)数值都与原进程保持一致,但是是一个全新的进程,并作为原进程的子进程
RDB的保存:RDB以rdb文件的方式保存再磁盘,默认保存再dump.rdb文件中,可以再配置文件中修改
 
注:假如在更新过程中触发了RDB但持久化但突然断电了,那么数据会丢失

二,RDB的配置

1,save:触发保存
   格式:save <seconds> <changes>
   在seconds(秒)内进行了changes次更新,将触发RDB持久化
   例:save 10 1 在10秒钟内进行了1次更新,触发RDB将数据集快照写入磁盘中
 save禁用:save ""
  save 手动备份
2,rdbcompression:对存储在磁盘中的快照,可以设置是否进行压缩存储,如果是的话,redis会采用LAF算法进行压缩,如果你不想消耗CPU来进行压缩的话,可以设置关闭此功能
3,rdbchecksum:在存储快照后,还可以让redis使用CRC64算法进行校验,,但是会增加性能10%的消耗
4,rdbfilename:设置rdb文件名
5,dir:设置快照文件路径

三,如何触发RDB快照

一,配置文件中默认的快照配置

save 900 1
save 300 10
save 60 10000
 
冷拷贝后重新恢复:cp dump.rdb dump_new.rdb

二,执行命令save或者bysave

save和bysave是手动触发RDB的命令

三,执行flushall命令

执行Flushall命令会产生一个dump.rdb文件覆盖原文件,但是dump.rdb为空

四,如何恢复RDB快照文件到redis中

1,将备份文件(dump.rdb)移动到redis安装的目录,并启动服务,redis会自动将持久化文件读到内存中
2,config get dir :手动导入rdb文件

五,RDB的优势和劣势

优势:
  • 适合大规模的数据恢复
  • 对数据的完整性要求不高
劣势:
  • 在指定时间间隔内做一次备份,所以如果redis突然挂掉,就会丢失最后一次快照后所有的修改
  • fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需求考虑
动态停止RDB保存的规则方法:redis-cli config set save ""(当前客户端被修改,要永久修改需要在redis.config中假如save “”)

二,持久化AOF

一,AOF的概述

AOF的概念(Append Only File):以日志的形式来记录每一个写操作,将Redis执行过的所有写指令记录下来(读操作不记录)
 
AOF只允许追加文件但不可以改写文件,redis启动之初会读取该文件的操作重构数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

AOF默认是关闭的:appendonly no
 
AOF的保存:AOF默认保存在appendonly.aof文件中,文件中全部为操作

二,AOF的配置

1,appendonly:是否开启AOF持久化
 
2,appendfilename:AOF文件名称,默认为appenonly.aof
 
3,appendfsync:AOF刷新的几种方式
 
  • Always:同步持久化,每一次发生数据变更都会被立即记录到磁盘文件中,性能较差但数据完整性较好
  • Everysec:出厂默认推荐,异步操作,每秒记录,如果一秒宕机,有数据丢失
  • NO
4,no-appendfsync-on-rewrite:指定是否在后台aof文件rewrite期间调用fsync,默认为no,表示要调用fsync(无论后台是否有子进程在刷盘)。Redis在后台写RDB文件或重写AOF文件期间会存在大量磁盘IO,此时,在某些linux系统中,调用fsync可能会阻塞。
 
5, auto-aof-rewrite-percentage:当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写 。当AOF文件大小的增长率大于该配置项时自动开启重写。
 
6,auto-aof-rewrite-min-size:当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写 。当AOF文件大小大于该配置项时自动开启重写。
 
7,aof-load-truncated : redis在启动时可以加载被截断的AOF文件,而不需要先执行 redis-check-aof 工具

三,AOF的启动/恢复/修复

正常恢复步骤:
  1. 开启AOF:把appendony设置yes
  2. 将有数据的aof文件复制一份保存到对应文件目录中(config get dir )
  3. 恢复:重启redis然后自动加载appendonly.aof文件
异常恢复步骤:
  1. 开启AOF
  2. 备份被写坏的AOF文件
  3. 修复:redis-check-aof --fix 文件路径(把异常指令全部删除)
  4. 恢复:重启redis然后自动加载appendonly.aof文件

四,Rewrite重写机制

rewrite的概念:AOF采用文件追加的方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定阀值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令byrewriteaof
 
重写的原理:AOF文件持续增加而过大时,会fork出一个新进程来将文件重写(先写临时文件最后再rename),遍历新进程的内存中的数据,没记录有一条set语句,重写aof文件的操作,并没有读取aof文件,而是将整个内存中的数据用命令的方式重写一个新的aof文件,这其实和rdb一样
AOF的触发机制:Redis会记录上次重写时AOF的大小,默认配置是当AOF文件大小是上次rewriter后大小的一倍且文件大小大于64MB

五,AOF的优势和劣势

优势:
灵活配置
  1. 每秒同步:appendfsync always 
  2. 每修改同步:appendfsync everysec
  3. 不同步:appendfsync no 
劣势:
  1. 相同数据集而言aof文件远大于rdb文件,恢复速度慢于rdb
  2. aof运行效率慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

三,Redis的事务

一,redis事务的基本概述

redis事务的概念:可以一次执行多个命令,本质上是一组命令的集合,一个事务中的所有命令都会被序列化,按顺序的串行化执行而不被其他命令插入,不允许加塞
 
redis的事务的作用:本质上它是一个队列,一次性,顺序性,排他性的执行一系列的命令

二,redis事务的基础操作命令

1,multi:开启事务
 
2,exec:提交事务
 
3,discard:取消事务
 
4,watch:监听一个或者多个key,如果再事务执行之前这个key被其他命令改动,那么事务将被打断
 
5,unwatch:取消watch对key的监听

三,redis事务的几种操作

一,正常执行

第一步:multi:开启事务
 
第二步:操作命令(会加入到队列中)
 
第三步:exec :提交事务
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379> get wql //执行操作
QUEUED  //入队
127.0.0.1:6379> exec //提交事务,输出每条命令的结果
1) "123456wql"//输出get wql的结果

二,放弃事务

再事务中使用discard放弃当前事务
第一步:multi:开启事务
第二步:操作命令(会加入到队列中)
第三步:取消事务:取消后,已经没有事务,exec再提交会报错
127.0.0.1:6379> multi //开启事务
OK
127.0.0.1:6379> get wql
QUEUED
127.0.0.1:6379> set wql wqllovefq
QUEUED
127.0.0.1:6379> discard //关闭当前事务
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI //报错没有可提交的事务

三,全体失败

但开启事务后有一条命令是错误命令(类似于java的编译时就报错),入队失败,那么整个事务都会报错,exec提交会失败
 
注:全体失败一定是错误的指令,再redis中是不存在的或者无法解析的,不能加入队列的,如果一条命令redis可以解析(类似于运行时错误),入队也成功,但运行时会报错,那么不会全体失败,而是
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get wql
QUEUED
127.0.0.1:6379> setfet wql  //这条命令不存在
(error) ERR unknown command `setfet`, with args beginning with: `wql`,
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.//提交报错

四,部分失败

部分失败指提交事务时部分命令运行失败,但其他命令依旧运行(相当于java程序运行时失败,当之前的会依旧运行)
 
部分失败也反映了redis和传统sql数据库的不同,没有原子性的概念,部分失败命令可以被跳
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get wql 
QUEUED
127.0.0.1:6379> incr wql //wql不是数值型的加1会报错
QUEUED
127.0.0.1:6379> get luoqin
QUEUED
127.0.0.1:6379> exec //incr报错其他依旧执行
1) "123456wql"
2) (error) ERR value is not an integer or out of range
3) "1234"

五,watch监听

一,watch的概念

 
悲观锁和乐观锁:悲观和乐观是心理上概念,悲观锁和乐观锁其实也是
  • 悲观锁:顾名思义,就是很悲观,每次拿数据的时候都有妄想症认为别人会修改自己的数据,所有每次都会加锁,这样别人想拿这个数据只能等锁释放直到拿到锁,传统关系性数据库中都用到这种锁机制,比如:表锁,行锁,读写锁等,再操作时都先加上锁,等操作完成再释放,下一个用户才能获取数据并操作
  • 乐观锁:顾名思义,就是很悲观,每一次拿数据时都认为别人不会修改,所有不会加锁,但在更新时会判断在此期间有没有人去更新这个数据,可以使用版本号等机制,判断数据是否在操作时被人修改,乐观锁适合多读的应用类型,可以提高吞吐量
乐观锁的策略:提交版本必须大于当前版本(能判断是否被人更新过)
悲观锁的策略:用户操作时直接加锁,其他用户访问不了,操作完再释放锁,给其他用户访问
乐观锁的版本策略:在每一个字段都会加一个版本号,用户读取数据时,版本号不会变,多用户可以并发访问,当数据被修改时,版本号加1,每次只能允许一个用户更新,下一个用户想在此更新需要再次获取当前版本号
watch与其说是监听不如说它是一把锁(乐观锁),它监听一个key就是锁做一个key,当事务中的数据被其他用户修改,事务提交就会失败

二,watch的操作

不加塞:用户再操作数据时,其他用户没有修改
127.0.0.1:6379> watch wql
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set wql 123
QUEUED
127.0.0.1:6379> get wql
QUEUED
127.0.0.1:6379> exec //提交成功
1) OK
2) "123"
加塞:用户再操作数据时,同时数据被另一个用户修改
客户端1:
127.0.0.1:6379> set wql 23

OK

127.0.0.1:6379>
客户端2:
127.0.0.1:6379> watch wql 加上监听,如果不加监听数据会被被覆盖
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set wql 123
QUEUED
127.0.0.1:6379> get wql
QUEUED
127.0.0.1:6379> exec
(nil) //数据被修改exec提交失败返回nil
注:一旦加了unwatch或者执行了exec之后之前加的监控锁都会被取消
总结:
  • watch指令,类似于乐观锁,事务提交时,如果key值已被别的客户端改变,整个事务都不会被执行
  • watch指令监听多个key,倘若再watch后有任何一个key被改变,exec命令执行的事务都会被放弃返回nil通知事务执行失败

一,主从复制

一,主从复制的概述

主从复制的概念:主机的数据更新后根据配置和策略,自动同步到备机的master/slaver机制,master以写为主,slaver以读为主
 
 
主从复制的作用:
  • 读写分离:再mater进行写操作,slaver进行读操作
  • 容灾恢复:mater和slaver都有数据,一台机宕掉可以用其他机器恢复

二,主从复制的实现

 
主从复制配从不配主,主库无需配置
 
从库的命令配置:slaveof 主库IP 主库端口号
 
修改配置文件操作:
  • 拷贝多个redis.conf做为从库的配置文件:cp redis.conf 文件名
  • 开启daemonize yes守护线程:daemonize yes
  • 修改PID文件名字避免冲突:pidfile 自定义文件名
  • 修改端口号避免冲突:port 自定义端口号
  • 修改log文件名称:logfile 自定义文件名
  • 修改默认rdb文件名字避免冲突:dbfilename 自定义rdb文件名
例:我们用一台主机两台从机
把所有的配置文件修改好后

三,redis主从复制的三大关系

一,一主多从

一个主机两个从机