- redis是支持事务的
- redis事务是基于队列实现的,创建一个事务队列,然后将事务操作都放入队列中,最后依次执行
#开启事务 multi #添加命令 sadd user:1001:follow 1002 sadd user:1002:follow 1001 sadd user:1001:fans 1002 sadd user:1002:fans 1002 #执行事务 exec # 取消事务 discardredis事务处理机制
redis对于命令执行错误处理,有两种解决方式:
- 语法错误(编译)
- 执行错误(运行)
-
语法错误
语法错误:执行命令的语法不正确
#开启事务 multi #命令 set name zhangsan set age seterror sex male #执行事务 exec #获取正确指令数据 get name
此时整个事务队列中,存在一条正确指令,两条语法错误指令, 当执行exec后,会直接返回错误,正确的命令也不会执行。
-
执行错误
执行错误:命令在运行过程中出现错误
#开启事务 multi #命令 set lesson java rpush lesson eureka feign nacos set lesson redis #执行事务 exec #获取数据 get lesson
通过上面事务执行可以看到,语法本身是没有问题的,所以运行之前redis无法发现错误,但是在执行时出现了错误,因此只会错误的命令不执行, 而正确的命
Redis将数据保存在内存中。一旦服务器宕机重启,内存中的数据就会丢失。当出现这种情况后,为了能够让Redis进行数据恢复,因此Redis提供了持久化机制,将内存中的数据保存到磁盘中,避免数据意外丢失。
Redis提供了两种持久化机制:RDB、AOF。 根据不同的场景,可以选择只使用其中一种或一起使用。
RDBRDB(Redis Database)是Redis默认存储方式。其基于快照思想,当符合一定条件(手动或自动触发)时,Redis会将这一刻的内存数据进行快照并保存在磁盘上,产生一个经过压缩的二进制文件,文件后缀名.rdb。
因为RDB文件是保存在磁盘上的,因此即使Redis进程退出,甚至服务器宕机重启。只要RDB文件存在,就可以利用它来还原Redis数据。
-
符合配置文件中的快照规则
在redis.conf文件中配置了一些默认触发机制
save "" # 不使用RDB存储 不能主从 # 记忆 save 3600 1 #表示1小时内至少1个键被更改则进行快照。 save 300 100 #表示5分钟(300秒)内至少100个键被更改则进行快照。 save 60 10000 #表示1分钟内至少10000个键被更改则进行快照。
-
手动执行save或者bgsave命令
在redis客户端执行save或bgsave命令,手动触发RDB快照。
#进入客户端 bin/redis-cli #执行save命令(同步执行) save #执行bgsave命令(异步子线程执行) bgsave
那么这两个命令都会触发快照的话,他们两个又有什么区别呢?
- **save:**同步处理,阻塞Redis服务进程,服务器不会处理任何命令,直到RDB文件保存完毕。
- **bgsave:**会fork一个和主线程一致的子线程负责操作RDB文件,不会阻塞Redis服务进程,操作RDB文件的同时仍然可以处理命令。
Redis默认使用的是 bgsave 来保存快照数据。
-
执行过程
1)Redis服务进程判断,当前是否有子线程在执行save或bgsave。
2)如果有,则直接返回,不做任何处理。
3)如果没有,则以阻塞式创建子线程,在创建子线程期间,Redis不处理任何命令。
4)创建完子线程后,取消阻塞,Redis服务继续响应其他命令。
5)同时基于子线程操作RDB文件,将此刻数据保存到磁盘。
优缺点- 优点
- 基于二进制文件完成数据备份,占用空间少,便于文件传输
- 能够自定义规则,根据redis繁忙状态进行数据备份
- 缺点
- 无法保证数据完整性,会丢失最后一次快照后的所有数据
- bgsave在fork子线程时会阻塞redis服务进程,频繁执行影响系统吞吐率
RDB方式会出现数据丢失的问题,对于这个问题,可以通过Redis中另外一种持久化方式解决:AOF。
AOF(append only file)是Redis提供了另外一种持久化机制。与RDB记录数据不同,当开启AOF持久化后,Redis会将客户端发送的所有更改数据的命令,记录到磁盘中的AOF文件。 这样的话,当Redis重启后,通过读取AOF文件,按顺序获取到记录的数据修改命令,即可完成数据恢复。
基础使用AOF方式需要手动开启,修改redis.conf
# 是否开启AOF,默认为no appendonly yes #设置AOF文件名称 appendfilename appendonly.aof执行原理
AOF功能实现的整个执行过程可以分为三个部分:命令追加、文件写入、文件同步。
1)客户端向Redis发送写命令。
2)Redis将接收到的写命令保存到缓冲文件aof_buf的末尾。 这个过程是命令追加。
3)redis将缓冲区文件内容写入到AOF文件,这个过程是文件写入。
4)redis根据策略将AOF文件保存到磁盘,这个过程是文件同步。
5)何时将AOF文件同步到磁盘的策略依据就是redis.conf文件中appendfsync属性值:always、everysec、no
- always:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,并将AOF文件同步到磁盘。该方式效率最低,安全性最高。
- everysec:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中。 并且每隔一秒会由子线程将AOF文件同步到磁盘。该方式兼备了效率与安全,即使出现宕机重启,也只会丢失不超过两秒的数据。
- no:每次执行写入命令都会将aof_buf缓冲区文件全部内容写入到AOF文件中,但并不对AOF文件进行同步磁盘。 同步操作交由操作系统完成(每30秒一次),该方式最快,但最不安全。
| 模式 | aof_buf写入到AOF是否阻塞 | AOF文件写入磁盘是否阻塞 | 宕机重启时丢失的数据量 | 效率 | 安全 |
|---|---|---|---|---|---|
| always | 阻塞 | 阻塞 | 最多只丢失一个命令的数据 | 低 | 高 |
| everysec | 阻塞 | 不阻塞 | 不超过两秒的数据 | 中 | 中 |
| no | 阻塞 | 阻塞 | 操作系统最后一次对AOF写入磁盘的数据 | 高 | 低 |
AOF会将对Redis操作的所有写命令都记录下来,随着服务器的运行,AOF文件内保存的内容会越来越多。这样就会造成两个比较严重的问题:占用大量存储空间、数据还原花费的时间多。
为了解决AOF文件巨大的问题,Redis提供了AOF文件重写功能。 当AOF文件体积超过阈值时,则会触发AOF文件重写,Redis会开启子线程创建一个新的AOF文件替代现有AOF文件。 新的AOF文件不会包含任何浪费空间的冗余命令,只存在恢复当前Redis状态的最小命令集合。
触发配置那么AOF文件达到多大时,会对其进行重写呢? 对于重写阈值的配置,可以通过修改redis.conf进行配置。
#当前aof文件大小超过上一次aof文件大小的百分之多少时进行重写。如果之前没有重写过,以 启动时aof文件大小为准 auto-aof-rewrite-percentage 100 #限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化 auto-aof-rewrite-min-size 64mb
除了让Redis自动执行重写外,也可以手动让其进行执行:bgrewriteaof
RDB与AOF对比- RDB默认开启,AOF需手动开启。
- RDB性能优于AOF。
- AOF安全性优于RDB。
- AOF优先级高于RDB。
- RDB存储某个时刻的数据快照,AOF存储写命令。
- RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF默认使用everysec,每秒保存一次,最多丢失两秒以内的数据。
- 如当前只追求高性能,不关注数据安全性,则关闭RDB和AOF,如redis宕机重启,直接从数据源恢复数据。
- 如需较高性能且关注数据安全性,则开启RDB,并定制触发规则。
- 如更关注数据安全性,则开启AOF。



