1. 持久化
Redis提供两种持久化方法:快照(snapshotting RDB)、只追加文件(append only file AOF)。前者可以将某一时刻所有的数据都写入硬盘,后者会在执行写命令时,将被执行的写命令复制到硬盘里。可根据业务场景单独使用,也可一同使用。
- 快照持久化
- bgsave命令,Redis会调用fork来创建一个子进程,子进程负责将快照写入硬盘,父进程继续处理命令请求
- save命令,不会创建进程,接到命令直接处理快照存储硬盘操作,不再接受任何其他命令
- shutdown命令,会在关闭服务器之前执行save操作
- Redis服务器之间复制时,会执行bgsave命令
- 通过配置文件(redis.conf)自动触发bgsave命令
save 60 10000 60秒内 有10000次写入
stop-writes-on-bgsave-error yes 当无法创建快照时 不再执行写命令
rdbcompression yes 通过LZF算法压缩rdb文件
rdbchecksum yes 服务重启后检测rdb文件是否正确
dbfilename dump.rdb 文件名称
dir ./ 文件路径
性能检测:
由于bgsave需要创建子进程且同时父进程还要处理其他命令,所以bgsave比save命令效率会慢很多。同AOF比较,比AOF执行频率低,恢复文件比较快,但不是实时备份,宕机会就是最近一次快照之后的数据。
- AOF持久化
- 通过配置文件(redis.conf)自动触发AOF
appendonly yes 开启aof
支持三个选项:always(每个写命令都同步到硬盘)、everysec(每秒同步一次)、no(操作系统决定同步频率)
appendfsync everysec
appendfilename "appendonly.aof" 文件路径名称
no-appendfsync-on-rewrite no 在RDB持久化数据的时候,此时的aof操作是否停止(考虑效率和数据丢失最好不停止)
当AOF文件大于64M 且比上一次增加了至少1倍的时候 触发重写操作
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
AOF重写:
AOF持久化虽然可以将丢失数据的时间降低到1秒,但同时有一个缺点就是:随着时间的推移AOF文件会越来越大,导致恢复数据时太慢甚至沾满硬盘空间。
假设同一个值做了100次写入的操作,那AOF就会追加这100次写命令,数据恢复时会把所有的命令都执行一遍,为了解决这个问题就有了AOF重写功能。
AOF重写相当于这100次命令我只记录第100次的写命令就可以了,这样会大大减小文件体积,数据恢复也会快很多。
bgrewriteaof(后台aof重写)同bgsave一样。
AOF重写不需要对现有的AOF文件进行任何的读取、分析。AOF重写是通过读取服务器当前数据库的数据来实现的!
AOF载入过程性能检测:
AOF数据不容易丢失,但执行频繁,恢复慢,性能略低。
RDB | AOF |
---|---|
丢失上一次save之后数据 | 丢失一秒数据(甚至不丢失数据) |
持久化key-value二进制文件 恢复快 | 持久化所有写命令 恢复慢 |
save bgsave | bgrewriteaof |
save时忽略过期键 | write时不忽略过期键 |
若RDB/AOF同时使用,以AOF文件为准,RDB文件作废。恢复数据时阻塞所有命令
-
数据恢复
-
redis进程挂掉,重启redis直接基于AOF日志文件恢复。如果AOF文件损坏redis-check-aof fix 命令修复
-
redis进程挂掉且rdb、aof文件损坏,可尝试从当前机器取最近的rdb文件恢复。
修改配置关掉appendaof -> 删除损坏的appendonly.aof -> copy最近的rdb文件 -> 重启Redis -> 命令行开启aof -> 命令行保存修改的配置
分析:关掉appendaof 是因为Redis基于aof文件恢复,如果只是删除损坏的,重启时Redis会自动创建一个空的aof文件,命令行开启aof后需要保存修改配置防止Redis重启后aof未开启。
-
2. 事务
Redis事务涉及到5个命令:multi、exec、discard、watch、unwatch,分别对应开启事务、执行事务、取消事务、监控key、取消监控。
Redis事务是以不可中断的方式依次执行一组缓存命令的队列将结果保存到内存中。具有事务的一致性、隔离性、原子性,因为是存放在内存中故不保证持久性。
事务流程Redis不支持事务嵌套,watch命令相当于乐观锁,将事务改变为有条件提交,watch监控key必须在开启事务之前,当乐观锁校验失败,将丢弃所有队列中的命令退出事务。
Redis单命令是保证原子性的,事务也具备一定的原子性,但事务队列中有些命令执行成功,有些命令可能执行失败,且不提供重试或回滚机制,因为Redis认为事务执行时发生的错误通常是编程造成的不应该发生在生产环境,且这种复杂的功能与Redis追求简单高效的宗旨不符合。SO 运行时命令错误 不会导致事务失败也不会回滚
什么情况下Redis事务会失败?
- discard命令,清除队列,取消事务
- watch中值改变,清除队列,取消事务
- 入列错误,如运用错误的命令,会取消事务
总结:
事务提供了一种将多个命令打包,然后一次有序地执行的机制。Redis为单线程操作所以执行事务之间不会被打断执行其他命令,执行命令顺序为先进先出。
那是一种发自内心深处的孤独感,与他人无关~
网友评论