一.持久化
一.RBD持久化
1.rdb文件
在指定的时间间隔内,执行数据集的时间点快照 (snapshot)。
快照会生成一个RDB文件,RDB保存到磁盘中的文件为dump.rdb。
默认的snapshot配置为:
-
save 900 1:每隔900s(15min),如果有超过 1 个key发生了变化,就写一份新的RDB文件 -
save 300 10:每隔300s(5min),如果有超过 10 个key发生了变化,就写一份新的RDB文件 -
save 60 10000:每隔60s(1min),如果有超过 10000 个key发生了变化,就写一份新的RDB文件
2.操作
首先需要指定rdb文件的存储路径,在redis@version.conf中寻找dir字段,(此处@version需要根据自身redis版本确定),并更改dir的内容:
1
dir /myredis/dumpfiles
更改的内容是自定义的。
手动备份
通过Save或BGSAVE可以实现手动备份。
save
redis无法同时处理save与其他操作。因此在主程序中执行save操作会阻塞当前redis服务器。
也因此,线上禁止使用save指令。
bgsave
bgsave会产生一个子进程,并由子进程来复制持久化过程,不会影响主进程的操作。
lastsave
lastsave可以快速获取上次备份的时间点。
修复命令
通过redis-check-rdb加上rdb文件的相对路径,可以实现使用rdb文件修复当前redis服务器。
二.AOF持久化
RDB持久化的基本原理是存储内存中的数据,而AOF持久化则是直接存储非读取操作语句。
默认情况下,redis并没有开启AOF持久化,需要在redis.conf中启动appendonly yes
AOF持久化保存的文件为appendonly.aof,且保存路径与rdb的保存路径一致。
1.写回策略
AOF默认有三种写回策略:Always 、everysec、no。
| 策略 | 介绍 |
|---|---|
| always | 每次执行命令后立刻同步AOF文件 |
| everysec | 执行完命令后传入缓冲区,每秒向AOF文件同步一次 |
| no | 每次写入执行命令后都只读入缓冲区,由操作系统决定何时同步AOF文件 |
默认的写回策略为everysec。
2.数据恢复
正常的恢复操作,只需要重启redis然后重新加载,便可以自动加载AOF文件的内容。
如果aof文件出现问题,可以通过fix指令可以修复aof文件
1
redis-check-aof --fix
上述指令加上aof文件的路径即可,如:
1
redis-check-aof --fix appendonly.aof.1.incr.aof
3.重写
当AOF文件的大小超过某个设定峰值后,Redis就会自动启动文件内容压缩。
也可以手动使用bgrewriteaof来重写。
4.混合持久化
Redis会优先采用AOF,其优先级高于RDB持久化。
且RDB的数据不是实时的。
混合持久化要求,RDB镜像做全量持久化,而AOF做增量持久化。即满足重写策略时,AOF会将最新的数据存储为RDB记录。
即混合持久化时,AOF文件 = 此前操作的RDB文件 + 新操作的AOF文件。
二.事务
一.ACID
事务是数据库操作语句中满足ACID特性的一组代码。
ACID分别指代的是原子性、一致性、隔离性与持久性。
在mysql中,事务需要使用begin与end包裹,且严格满足ACID特性。
而Redis只能满足一下特征:
- 单独的隔离操作,仅保证事务里的操作会被连续独占的执行。
- 没有隔离级别的概念,事务提交前任何指令都不会被实际执行,而是存在命令队列中。
- 不保证原子性,不能保证所有指令一定同时成功或同时失败。
- 不会被其他命令插入。
因此,Redis中的事务不能称为真正意义上的事务。
二.操作
1.事务命令
| 命令 | 描述 |
|---|---|
| DISCARD | 取消事务,放弃执行事务块内的所有命令。 |
| EXEC | 执行所有事务块内的命令。 |
| MULTI | 标记—个事务块的开始。 |
| UNWATCH | 取消WATCH命令对所有key的监视。 |
| WATCH | 监视一个(或多个) key ,如果在事务执行之前这个(或这些)key被其他命令所改动,那么事务将被打断。 |
通过MULTI与EXEC的包裹,我们可以实现事务操作
1
2
3
4
5
6
7
8
9
MULTI
SET K1 V1
SET K2 V2
SET K3 V3
MGET K1 K2 K3
EXEC
// value :
OK ; OK ; OK ; V1 ; V2 ; V3
通过将EXEC改为DISCARD,我们可以取消此前设定的事务块命令。
1
2
3
4
5
6
MULTI
SET K1 V1
SET K2 V2
SET K3 V3
MGET K1 K2 K3
DISCARD
如果事务块中一个语句的语法出错,则所有命令都不会执行。
1
2
3
4
5
6
7
8
9
10
MULTI
SET K1 V1
SET K2 V2
SET K3
EXEC
MGET K1 K2 K3
// value :
error ... ; QUEUED
但如果语法没错而是逻辑出错,则Redis会执行没有逻辑错误的语句,而不执行有逻辑错误的语句。
这种行为违反了原子性特征,也印证了Redis的事务不是真正意义上的事务。
三.管道
管道(pipeline)可以一次性发送多条命令给服务端。
服务端依次处理完完毕后,通过一条响应一次性将结果返回,通过减少客户端与redis的通信次数来实现降低往返延时时间。
pipeline实现的原理是队列,先进先出特性就保证数据的顺序性。
其目的是减少网络交互,提高交互效率。
此处介绍一种实现管道的方法。
在linux系统中使用如下命令行:
myredis> cat cmd.txt
set k1 v1
set k2 v2
set k3 v3
lpush list 1 2 3 4 5
myredis> cat cmd.txt | redis-cli -a "password" --pipe
// 返回值:
errors: 0, replies: 4
其中|为linux中的管道操作符。
原生批量命令与管道的区别是:
- 原生批量命令是原子性(例如:
mset,mget),pipeline是非原子性 - 原生批量命令一次只能执行一种命令,
pipeline支持批量执行不同命令 - 原生批量命令是服务端实现,而
pipeline需要服务端与客户端共同完成
四.发布订阅
消息中间件内容,请关注kafka、rabbitMQ等。