Redis-事务
Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证:
- 事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
- 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行
事务的上个步骤:
- 开启事务:以MULTI开启一个事务
- 命令入队:将多个命令添加到命令队列中,接到这些命令不会立即执行,而是放到等待执行的事务队列中
- 执行事务:有EXEC执行事务。(或者DISCARD取消执行)
事务相关指令:
|
执行事务出现的四种情况:
- 正常执行:队列中所有的指令全部会被执行。
- 全部取消:队列中的所有指令全部会被取消。
- 全体连坐:如果指令集中有一条在加入队列时报错,则队列中的所有指令全部取消。
- 冤头债主:如果指令已经加入到队列中,但执行失败,只有当前指令失败,其它继续执行。
redis事务的三个特性:
- 单独的隔离性:事务中的所有的命令都会序列化,按顺序执行,事务在执行过程中,不会被其它客户端发送过来的命令请求所打断
- 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新。
- 不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
watch监控
watch监控表示对需要操作的key添加一个乐观锁,防止另一个用户进行修改,导致结果错误。
- 悲观锁
- 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会被block直到它拿到锁。传统的关系型数据库里面就用到了很多这种锁,比如行锁,表锁,读锁,写锁等,都是在操作之前先上锁。
- 乐观锁
- 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。提交的版本号必须大于当前版本号才可以提交
在访问以写入为目的数据的时候(SOL中的SELECT FOR UPDATE),关系数据库会对被访同的数据行进行加锁,直到事务被提交(Commit)
或者被回滚(ROLLBACK)为止,如果有其他客户端试图对被加锁的数据行进行写入,那么该客户端将被阻塞、直到第一个事务执行完毕为止。加锁在实际使用中非常有效,基本上所有关系数据库都实现了这种加锁功能,它的缺点在于,持有锁的客户端运行越慢,等待解锁的客户端被阻塞的时间就越长。因为加锁有可能会造成长时间的等待,所以Redis为了尽可能地减少客户端的等待时间,并不会在执行WATCH命令时对数据进行加锁,相反地,Redis只会在数据已经被其他客户端抢先修改了的情况下,通知执行了WATCH命令的客户端,
Redis-主从复制
什么是主从复制?
主从复制,是用来建立一个和主数据库(master)完全一样的数据库环境,称为从数据库(slave)。
主从复制的作用和使用场合一般有几个:
- 容灾恢复,主数据库服务器故障后,可迅速从从数据库恢复
- 读写分离、主数据库主要做写的操作,从数据库做读的操作
主从复制应用场景
- 电子商务网站上的商品,一般都是一次上传,无数次浏览的,说专业点也就是”多读少写”。
- 对于这种场景,我们可以使如下这种架构
我们将一台Redis服务器作主库(Matser),其他三台作为从库(Slave),主库只负责写数据,每次有数据更新都将更新的数据同步到它所有的从库,而从库只负责读数据。这样一来,就有了两个好处:
- 数据被复制成了了好几份,就算有一台机器出现故障,也可以使用其他机器的数据快速恢复。
- 读写分离,不仅可以提高服务器的负载能力,并且可以根据读请求的规模自由增加或者减少从库的数量,棒极了;
注意事项:
在Redis主从模式中,一台主库可以拥有多个从库,但是一个从库只能隶属于一个主库
主从复制实现方式
- 一主二仆
- 薪火相传
- 反客为主
一主二仆
一个Master两个或多个Slave