Redis事务与持久化

1. 事务描述

(1)什么是事务

事务,就是把一堆事情绑在一起,按顺序的执行,都成功了才算完成,否则恢复之前的样子

事务必须服从ACID原则,ACID原则分别是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)

原子性:操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态

一致性:事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定

隔离性:在该事务执行的过程中,无论发生的任何数据的改变都应该只存在于该事务之中,对外界不存在影响,只有在事务确认提交之后们才会显示该事务对数据的改变,其他事务才能获取到这些改变后的数据

持久性:当事务正确完成后,它对于数据的改变是永久性的
  
(2)什么是事务

第一类丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖

脏读:一个事务读取到另一个事务未提交的更新数据

幻读:一个事务执行两次查询,第二次结果集包含第一次中没有或某些行已经被删除的数据,造成两次结果不一致,只是另一个事务在这两次查询中间插入或删除了数据造成的

不可重复读:一个事务两次读取同一行的数据,结果得到不同状态的结果,中间正好另一个事务更新了该数据,两次结果相异,不可被信任

第二类丢失更新:是不可重复读的特殊情况。如果两个事物都读取同一行,然后两个都进行写操作,并提交,第一个事物所做的改变就会丢失

2. redis事务特征

1、 在事务中的所有命令都将会被串行化的顺序执行,事务执行期间,Redis不会再为其它客户端的请求提供任何服务,从而保证了事物中的所有命令被原子的执行

2、 和关系型数据库中的事务相比,在Redis事务中如果有某一条命令执行失败,其后的命令仍然会被继续执行

3、 我们可以通过MULTI命令开启一个事务,有关系型数据库开发经验的人可以将其理解为"BEGIN TRANSACTION"语句。在该语句之后执行的命令都将被视为事务之内的操作,最后我们可以通过执行EXEC/DISCARD命令来提交/回滚该事务内的所有操作。这两个Redis命令可被视为等同于关系型数据库中的COMMIT/ROLLBACK语句。

4、 在事务开启之前,如果客户端与服务器之间出现通讯故障并导致网络断开,其后所有待执行的语句都将不会被服务器执行。然而如果网络中断事件是发生在客户端执行EXEC命令之后,那么该事务中的所有命令都会被服务器执行。

5、 当使用Append-Only模式时,Redis会通过调用系统函数write将该事务内的所有写操作在本次调用中全部写入磁盘。然而如果在写入的过程中出现系统崩溃,如电源故障导致的宕机,那么此时也许只有部分数据被写入到磁盘,而另外一部分数据却已经丢失。Redis服务器会在重新启动时执行一系列必要的一致性检测,一旦发现类似问题,就会立即退出并给出相应的错误提示。此时,我们就要充分利用Redis工具包中提供的redis-check-aof工具,该工具可以帮助我们定位到数据不一致的错误,并将已经写入的部分数据进行回滚。修复之后我们就可以再次重新启动Redis服务器了。

3. redis事务处理

    redis事务通过MULTI、WATCH、UNWAYCH、EXEC、DISCARD五个命令实现
                           multi、watch、unwaych、exec、discard、

MUTIL命令:用于开启一个事务,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行,它总是返回OK

WATCH命令:对键进行监视,直到用户执行EXEC命令的这段时间里面,如果其他客户端抢先对任何被监视的键进行了替换、更新或删除等操作,那么当用户舱室执行EXEC命令的时候,事务将失败并返回一个错误(之后用户可以选择重试或者放弃事务)

UNWATCH命令:在WATCH命令执行之后,EXEC命令执行之前对链接进行重置

EXEC命令:执行事务命令

DISCARD命令:客户端可以取消WATCH命令名清空所有已入队命令

4. 持久化(RDB,AOF)

\1. 为什么要持久化

Redis是内存数据库。他将自己的数据库存储状态存储在内存中,如果不想方法把数据库状态保存到磁盘中,一旦服务进程退出,服务器中的数据库状态也将消失不见。

\2. 解决方法:redis提供了RDB持久化功能,这个功能将redis内存中的数据库状态保存到磁盘中,避免数据意外丢失。

\3. RDB持久化:

RDB持久化功能产生一个RDB文件(经过压缩的二进制文件)可还原成数据库状态。

保存在硬盘里,存在即可还原。

RDB文件的创建与载入:

两个redis命令用于生成RDB文件:SAVE ,BGSAVE。

Save命令:会阻塞redis服务进程,直到RDB文件创建完成。服务器阻塞期间,服务器不能处理任何命令请求。

redis> SAVE //等待生成RDB文件

ok

BGSAVE命令会派生一个子进程,然后由子进程负责创建RDB文件,服务父进程继续处理命令。

保存条件

[redis]$ more /usr/local/redis/conf/redis.conf

save 900 1 #服务器900秒内,对数据库至少修改一次

save 300 10 #服务器300秒内,对数据库至少10次修改

save 60 10000 #服务器60秒内,对数据库至少10000次修改

dbfilename “dump.rdb” #持久化文件名称

dir "/data/dbs/redis/ #持久化数据文件存放的路径

满足任意三个条件之一,bgsave就会执行。

4.AOF持久化

RDB持久化是通过保存数据库中的键值对来记录数据的状态不同,AOF持久化是通过保存redis服务器所执行的写命令来记录数据库状态的。
例子:

redis> set msg “hello”

ok

redis> sadd fruits “apple” “banana” “cherry”

(integer) 3

redis>rpush numbers 128 256 512

(interger) 3

AOF持久化的方法是将服务器执行的set ,sadd,rpush三个命令保存到AOF文件中

而,RDB持久化是将msg,fruits,numbers三个键的键值对保存到RDB文件。

5.2AOF载入:

服务器启动时通过载入和执行AOF文件中的命令还原数据库状态。

5.3AOF持久化的实现:

1.命令追加 2.文件写入3.文件同步 三个步骤

命令追加:

当AOF持久化功能处于打开状态时,服务器在执行一个写命令之后,会以协议格式将被执行的写命令追加到服务器的aof_buf缓存区的末尾:

例子:

redis>set key value

ok

服务器在执行完整个set命令之后会将以下协议内容追加到aof_buf缓冲区末尾:

*3\e\n$3…\r\n

然后执行:

redis>rpush numbers one two three

(integer ) 3

那么服务器在执行rpush命令之后将以下协议内容追加到aof_buf缓冲区末尾:

*5\r\n$3…\r\n

文件写入与同步:

Redis的服务器进程就是一个事件循环(loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复,而时间事件是负责执行定时运行函数(serverContron)。

因为服务器处理文件事件会执行写命令,使一些内容追加到aof_buf缓冲区里,所以服务器每次在结束一个事件循环之前,都会调用flushAppendOnlyFile函数,考虑是否将aof_buf缓冲区的内容写入和保存到Aof文件里。

AOF文件的载入与数据还原:
在这里插入图片描述

5.面试题:简单介绍AOF持久化和AOF文件与RDB持久化的区别.:

  因为AOF文件的更新频率比RDB文件的更新频率高,所以:

1.如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。

2.只有在AOF持久化功能处于关闭状态的时候,服务器才会使用RDB文件来还原数据库状态。
在这里插入图片描述

发布了18 篇原创文章 · 获赞 0 · 访问量 832

猜你喜欢

转载自blog.csdn.net/qq_45122010/article/details/104006009