2.5 AOF同步频率设置
1. appendfsync always
始终同步,每次Redis的写入都会立刻记入日志,性能较差但数据完整性比较好。
2. appendfsync everysec
每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
3. appendfsync no
redis不主动进行同步,把同步时机交给操作系统。
2.6 Rewrite
1. AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
例:设置k1为0,然后incr 进行了4次,k1对应的值会是4,其实就相当于set k1 4
2. 重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
四、Redis事务
1 Redis事务简介
1. Redis事务是一组命令的集合,一个事务中的所有命令都将被序列化,按照一次性、顺序性、排他性的执行一系列的命令。
2. Redis单条命令保证原子性,但是事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。
3. Redis事务没有隔离级别的概念。批量操作在执行前被放入缓存队列,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。
4. Redis事务的三个阶段:
- 开始事务
- 命令入队
- 执行事务
2 Redis事务基本操作
2.1 Multi、Exec、discard
事务从输入Multi命令开始,输入的命令都会依次压入命令缓冲队列中,并不会执行,直到输入Exec后,Redis会将之前的命令缓冲队列中的命令依次执行。组队过程中,可以通过discard来放弃组队。
例1:
multi 开始事务 set k1 v1 进行组队,并不执行 set k2 v2 进行组队,并不执行 exec 执行队列命令,依次设置k1 k2
例2:
multi 开始事务 set k3 v3 进行组队,并不执行 set k4 v4 进行组队,并不执行 discard 取消组队,都不执行
2.2 事务的错误处理
1. 组队阶段某个命令出现了错误,整个队列中的命令都不执行。
例:整个命令缓存队列都不会执行。
2. 执行阶段某个命令出现了错误,只有报错的命令不会执行,其他正常执行。
例:只有报错的命令没有执行。
3 悲观锁与乐观锁
3.1 事务应用场景
- 一个请求想给余额减8000
- 一个请求想给余额减5000
- 一个请求想给余额减1000
3.2 悲观锁(Pessimistic Lock)
每次去拿数据的时候都认为别人会修改,所以在每次拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞,直到它拿到锁。传统关系型数据库就用到很多悲观锁,比如行锁、表锁等。
3.3 乐观锁(Optimistic Lock)
每次去拿数据的时候都认为别人不会修改,所以不会上锁,但在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制。乐观锁适用于多读的应用类型,可以提高吞吐量。Redis就是乐观锁机制实现事务的。
4 Redis中的乐观锁
4.1 watch key [key……]
在执行multi之前,先执行watch监视一个或多个key,如果在事务执行之前这个(或这些)key被其它命令所改动,那么事务将被打断。
例:开启两个客户端
1号客户端 set money 10000 设置一个money的key watch money 监视money multi 开启事务 set money 100 修改money,暂时不执行事务 2号客户端 watch money 监视money multi 开启事务 set money 110 修改money,暂时不执行事务 1号客户端 exec 执行事务,返回成功 2号客户端 exec 执行事务,更新失败
1号客户端
2号客户端
4.2 unwatch
取消watch命令对所有key的监视
如果在执行watch命令之后,exec命令或discard命令先执行的话,那么就不需要再执行unwatch。