Redis中的事务与持久化
事务可以一次执行多个命令,并带有两个重要的保证:
1、 事务中的所有命令都被序列化并按顺序执行。Redis执行事务期间,不会被其它客户端发送的命令打断,事务中的所有命令都作为一个隔离操作顺序执行。
2、 Redis事务是原子操作,或者执行所有命令或者都不执行。
通过Multi
开始事务,输入的命令依次加入命令队列中但不会依次执行。通过Exec
命令使队列中的命令依次执行。组队过程中可以通过discard
命令终止组队。
例如:我们输入multi,Redis客户端会返回一个OK,开启事务。
紧接着,我们输入exec,以上命令就会顺序执行:
我们可以用discard
不执行:
如果在组队有一个命令出错(往往是语法错误,而不是逻辑错误),那么所有命令都不会被执行。但是,如果是执行阶段某个命令错误,则只会执行正确的命令,跳过错误的命令。
事务冲突
采用悲观锁(每次操作前先上锁使别人不能操作)或者乐观锁(给操作数据加上“版本号”来确定是否能操作)解决事务冲突问题。
我们可以通过watch [key]
来给对应的key加锁,这是一种乐观锁加锁命令。我们可以利用unwatch [key]
来解开乐观锁。
Redis事务三特性
- 单独的隔离操作:事务的所有命令都会序列化,按顺序地执行,事务在执行过程中,不会被其他客户端发送来的命令请求所打断
- 没有隔离级别的概念:队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行
- 不保证原子性:事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
RDB(Redis DataBase)
在指定的时间间隔内将内存中的数据集快照写入到硬盘中。 通过bgsave
命令让操作系统fork()
一个子进程,然后让持久化过程由子进程负责(如果发现已经创建好的持久化子进程则直接返回)。时间间隔到达后,子进程会创建RDB文件(根据父进程内存生成的临时快照文件进行原子替换)。其流程如图所示:
RDB的优点:
- RDB是一种紧凑的二进制压缩文件,适合备份,全量复制
- 加载RDB恢复数据远快于AOF
RDB的缺点:
- 最后一次持久化的数据可能丢失
- 无法做到实时、秒级持久化
- 版本兼容可能会有问题
AOF
以日志的形式记录每个写操作。AOF会把指令,数据记录下来追加(不允许改写)到文件中。AOF默认不开启。我们需要把redis.conf文件中appendonly.aof
的值改为yes才能开启。若AOF和RDB同时开启,系统会默认读取AOF的数据。
- 所有写入命令会追加到aof_buf(缓冲区)中
- AOF缓冲区根据对应的策略向硬盘做同步操作
- 定期对AOF文件进行重写来达到压缩的目的
- Redis服务器重启后可以加载AOF文件进行数据恢复
命令写入的内容是文本协议格式。Redis提供了很多AOF的缓冲区同步文件策略。
可配置值 | Description |
---|---|
always | 使用fsync() 写入到同步文件 |
everysec | 先调用write() ,完成后线程返回。fsync() 由专门线程每秒调用一次 |
no | 只利用write() 写入到同步文件 |
fsync()
与write()
相比,虽然依旧要写入到缓冲区,但必须等到成功写入到磁盘后才返回,所以比较适合数据库操作。