1、redis事务三特性
1、单独的隔离操作
事务中的所有命令都会序列化、按顺序执行,事务执行过程中不会被其他客户端发来的命令打断。
2、没有隔离级别的概念
队列中的命令在没有被提交之前都不会被实际执行,事务提交前任何命令都不会被执行
3、不保证原子性
队列中如果有一个命令执行失败,其他命令仍会被执行 不会回滚。
2、事务相关指令
Multi、Exec、discard、Watch
从输入 Multi 开始 ,输入的命令都会依次进入到队列中,但不会被执行 直到输入Exec Redis会将命令队列中的命令依次执行
组队过程中可以通过discard放弃组队
-
事务冲突问题
扣款为例 三个请一个给金额减八千;一个给金额减五千;一个给金额减一千,最后账户会变成一个负数这显然是不合理的。
Redis利用乐观锁机制解决以上问题:
乐观锁就是会保存一个数据版本在修改的时候会对比当前版本和修改之前存储的版本是否一致如果一致就连同版本号一起修改,若不一致说明数据已经被其他人修改过了不能修改,乐观锁适用于多读的场景可以提高吞吐量。Redis就是利用这种check-and-set解决事务冲突问题的。通过命令Watch提供乐观锁功能,在你Exec的时,如果被Watch的键发生过改动,那么事务将会被打断。
Watch实现原理:在每个一数据库的服务端都保存了一个 watched_keys 字典, 字典的键是这个数据库被监视的键, 而字典的值则是一个链表, 链表中保存了所有监视这个键的客户端。
在任何key执行了修改之后 检查数据库的 watched_keys 字典, 看是否有客户端在监视已经被命令修改的键, 如果有程序将所有监视这个 key 的客户端的 REDIS_DIRTY_CAS 选项打开。当客户端发送 EXEC 命令、触发事务执行时, 服务器会对客户端的状态进行检查 如果客户端的REDIS_DIRTY_CAS 已经被打开,说明端监视的键已经被修改了,事务的安全性被破坏。服务器会放弃执行这个事务。
3、Redis持久化策略
redis 有两种持久化策略 aof 和 rdb
- rdb:Redis会单独创建(fork)一个子进程来持久化,会先将数据写入一个临时文件待持久化过程结束再用这个零时文件替换上次持久化好的文件。整个过程主进程是不进行任何IO操作的确保了及高的性能如果需要大规模的数据恢复且对数据完整性要求不是很敏感 那使用rdb持久化会是一个不错的选择。
fork的作用是复制一个与当前进程一样的进程,新进程的所用数据(境变量、变量、环程序计数器等)和原进程一致,但是是一个全新的进程作为原进程的子进程。父进程和子进程会公用同一段物理内存,只有进程空间的各段内容要发生变化时才会将父进程的内存复制一份给子进程 即 写时复制
rdb执行流程:
rdb优点:
1、适合大规模的数据恢复。
2、对数完整性要求不高。
3、节省磁盘空间。
rdb缺点:
1、fork 时内存页中的数据被修改时 会克隆一份当前内存页占用内存空间
2、rdb并非实时持久化,所以如果redis以外宕机会有一部分数据丢失的风险
- aof:以日志的形式记录每一操作(增量保存),将Redis所有非读指令记录下来 只可以追加文件当不可以修改文件,redis启动时会加载该文件重新构建数据将写指令从前向后执行一次以完成数据的恢复工作。
aof执行流程:
1、客户端的写请求命令会被append追加到aof缓冲区内。
2、aof缓冲区根据aof持久化策略(always、everysec、no)将操作sync同步到磁盘的aof文件中。
3、aof文件大小超过重写策略或手动重写时,会对aof文件rewrite重写,压缩aof文件容量。
4、redis重启服务时,会加载 aof 文件的写操作以此来达到数据恢复的目的。
rewrite压缩:
aof采取文件追加的方式,文件会越来越大为了避免这种情况,新增了重写机制,当aof文件的大小超过所设定的阈值时,Redis就会启动aof文件的内容压缩,使用命令bgrewriteaof。
触发机制:
Redis会记录上次重写时的aof大小,默认配置是当aof文件大小是上次rewrite后大小的一倍且文件大于64M是触发
重写原理:
aof文件持续增加过大时,会fork出一条新进程将文件重写(也是先写临时文件然后rename),redis4.0版本后的重写就是把rdb的快照以二进制的形式保存在aof文件中作为已有的历史数据,替换掉原来的命令追加操作。
重写流程:
1、bgrewriteaof触发重写,判断当前是否有bgsave或bgrewriteaof在运行 如果有,则等待该命令执行完成后再执行。
2、主进程fork出子进程执行重写操作,保证主进程不会阻塞。
3、子进程将redis内存中的数据写入临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原aof文件完整以及新aof文件生成期间的数据不会丢失
4、子进程写完新的aof文件后,向主进程发信号,父进程将aof_rewrite_buf中的数据写入到新的aof文件。
5、使用新的aof文件覆盖久的aof文件,完成aof重写。
aof优点:
1、备份机制稳健,丢失数据的概率更低。
2、可读的日志文件,通过aof文件可以处理误操作。
aof缺点:
1、比起rdb占用更多的磁盘空间
2、恢复备份速度比rdb慢
3、若每次读写都同步有一定的性能影响。
- aof:以日志的形式记录每一操作(增量保存),将Redis所有非读指令记录下来 只可以追加文件当不可以修改文件,redis启动时会加载该文件重新构建数据将写指令从前向后执行一次以完成数据的恢复工作。