简单事务控制
- redis是单线程处理所有client的请求
multi
当前client连接进入一个事务上下文, 该连接后续的命令不会立即执行, 而是放到队列(Queue)中, 直到接收到exec
指令后才会按顺序执行
1 | redis 127.0.0.1:6379> multi |
- 使用
discard
命令取消事务, 使其回滚 watch
命令可以监视键值对, 当exec
提交时如果被监视的键值对发生变化, 事务将被取消
复杂事务控制 - 乐观锁
- 基于version版本记录机制实现, 即为数据增加一个版本标识(version字段), 读取时将此版本号一同读出, 之后更新时对此版本号加1
- 如果提交的数据版本号大于数据库当前版本号, 则予以更新, 否则失败
- 即如果session 1和session 2同时对数据库进行操作, 在session 1提交更新之前, session 2已经完成提交, 那么数据库版本号已经+1, 则session 1提交失败
- redis只能保证事务的每个命令连续执行, 如果事务中的一个命令失败了, 并不会回滚其他命令
持久化机制
redis是支持持久化的内存数据库, 需要经常将内存中的数据同步到磁盘来保证持久化; 有snapshotting快照(默认)和append-only file (aof) 两种方式
snapshooting
将内存中的数据以快照的方式写入到二进制文件, 默认文件名dump.rdb; 可以修改redis配置来实现
1 | save 900 1 # 900秒内如果超过1个key被修改, 则发起快照保存 |
也可以使用save
或bgsave
命令通知redis做一次快照持久化(不推荐), 这种方式会阻塞所有client请求;
另外需要注意, 每次快照持久化都是将内存数据完整写入磁盘一次, 如果数据量大时, 会造成大量的磁盘io操作, 严重影响性能
append-only file
由于每次snapshooting之间有间隔, 如果redis意外down掉, 会丢失最后一次快照前的所有修改. 避免这种情况可以使用aof方式持久化
aof方式下, redis会通过write函数追加到文件中(默认是appendonly.aof)
配置文件:
1 | appendonly yes # 启用aof持久化方式 |
使用aof方式的问题是, 其持久化文件会变得越来越大。 为了压缩, redis提供了bgrewriteaof
命令; 收到此命令后, redis将使用与快照类似的方式将内存中的数据以命令的形式保存到临时文件中, 最后替换原来的文件.