一、Redis持久化
RDB快照(snapshot)
默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。可以对 Redis 进行设置(save N M),让它在“ N 秒内数据集至少有 M 个改动 ”这一条件被满足时, 自动保存一次数据集(当前时刻的整个内存)为 RDB 文件。也可以进入 Redis 客户端,手动执行命令 save 或 bgsave 立即生成 dump.rdb 快照文件(默认存放路径为 dump.rdb)。如果需要关闭 RDB 快照,只需要将 redis.conf 文件的 save 60 10000 等配置注释即可、
- save 生成 RDB 快照时,会阻塞正在进行 Redis 操作命令
- bgsave 默认的持久化文件机制 写时复制(COW)机制,不会阻塞正在进行 Redis 操作命令。 Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常处理写命令。bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据,子进程开始读取内存数据并写入 RDB 文件后,此时,如果有新的操作命令,会进行在内存中执行,然后会生成一块新的该数据的副本数据写入到 RDB 文件中。这个过程中主线程依旧可以修改原来的数据。
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
是否阻塞redis其它命令 | 是 | 否(在生成子进程执行调用fork函数时会有短暂阻塞) |
复杂度 | O(n) | O(n) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork子进程,消耗内存 |
- RDB 快照的优点:文件体积小,恢复数据速度快
- RDB 快照的缺点:如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据
AOF 持久化(append-only file)
AOF 持久化就是将修改的每一条指令记录追加进文件 appendonly.aof 中(先写入os cache,每隔一段时间 fsync 到 磁盘)。在 redis.conf 中配置(appendonly yes、appendfilename “appendonly.aof”),和 RDB 快照一样,默认存放路径为 /data/3306/appendonly.aof
该操作有三个配置项:
appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全
appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据
appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性
AOF 重写: AOF 中有些命令是没有用的,比如累加某一个数据项,不需要将每次累加的记录,AOF 可以自动重写为最后一条 SET 命令,AOF 也有两个默认配置
# aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就 很快,重写的意义不大
# auto‐aof‐rewrite‐min‐size 64mb
# aof文件自上一次重写后文件大小增长了100%则再次触发重写
# auto‐aof‐rewrite‐percentage 100
- AOF 的优点:数据安全性比 RDB 高
- AOF 的缺点:命令过多时体积过大,恢复数据速度慢,安全性根据策略决定**
命令 | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 (更安全) |
文件体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 容易丢失数据 | 由策略决定 |
Redis 4.0 混合持久化
AOF在重写时,不再是单纯将内存数据转换为 RESP 命令写入 AOF 文件,而是将重写这一刻之前的内存做 RDB 快照处理,并且将 RDB 快照内容和增量的 AOF 修改内存数据的命令存在一起,都写入新的 AOF 文件,新的文件一开始不叫 appendonly.aof,等到重写完新的 AOF 文件才会进行改名,覆盖原有的 AOF 文件,完成新旧两个 AOF 文件的替换。开启配置命令如下(必须先开启 AOF):
# aof‐use‐rdb‐preamble yes
Redis 数据备份策略
- 写 crontab 定时调度脚本,每小时都 copy 一份 rdb 或 aof 的备份到一个目录中去,仅仅保留最近 48 小时的备份
- 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份
- 每次 copy 备份的时候,删除太旧的备份
- 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏
注意: 停掉 Redis 之前会自动做一次持久化文件,当 Redis 重启时,如果目录下存在 RDB 或 AOF 文件,就会自动将数据恢复到 Redis 中
二、Redis 主从架构
主节点写数据,从节点备份数据,也可以进行一些读操作,缓解主节点压力。主从架构需要自己写代码将读、写操作分配到对应的主节点与从节点,如果是哨兵或者集群架构可以自动分发。
主从架构搭建步骤:
1、复制一份主节点的 redis.conf 文件
2.修改 redis.conf 相关配置
port 6380 #从节点使用端口
pidfile /var/run/redis_6380.pid #把pid进程号写入pidfile配置的文件
logfile "6380.log" #日志文件
dir /usr/local/redis‐5.0.1/data/6380 #指定数据存放目录
protected-mode no #关闭保护模式,开启仅本机可访问
# 注释掉 bind,它绑定当前及其ip,表示客户端运行哪些网卡ip去访问,内网一般不需要配置
# bind 127.0.0.1
3.配置主从复制
replicaof 192.168.56.10 6379 #从本机6379的redis复制数据,Redis 5.0之前使用slaveof
replica‐read‐only yes # 配置从节点只读
4.启动从节点
redis‐server redis.conf
5.连接从节点
redis‐cli ‐p 6380
#如果需要配置更多的从节点,可以继续复制一份配置文件,添加即可
主从复制原理:
主从复制风暴: 主从复制过程中可能出现从节点较多,多个从节点同时从主节点进行复制,造成主节点压力过大,可以让将部分从节点搭建到从节点上,使其从从节点同步数据
三、Redis 哨兵高可用架构
客户端连接哨兵,第一次访问时从哨兵找出 Redis 的主节点,后续就直接访问 Redis 的主节点。哨兵动态监听所有的节点,主节点挂了,哨兵自动选举新的主节点,并把新的主节点推送给客户端(Redis 的 client 端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)。
哨兵架构缺点:
- 主节点挂掉后,重新选举会有几秒甚至十几秒的不可用
- 只有一个节点作为写节点,并发量最大也就 10W左右
- 最大内存推荐10个G,再大影响性能(持久化文件过大,影响数据恢复或主从同步的效率)
推荐三个哨兵,哨兵搭建好后,哨兵会主动写到配置文件,哨兵架构搭建步骤如下:
1、复制一份sentinel.conf文件
cp sentinel.conf sentinel‐6399.conf
2、修改setinel.conf文件相关配置
port 6399
daemonize yes #后台启动
pidfile "/var/run/redis‐sentinel‐6399.pid"
logfile "6399.log"
dir "/usr/local/redis‐5.0.3/data"
# sentinel monitor <master‐redis‐name> <master‐redis‐ip> <master‐redis‐port> <quorum>
# quorum是一个数字,指明当多少个sentinel认为一个master失效时,该master才算真正失效
# 该值一般为:sentinel总数/2 + 1
# masterName随便取
sentinel monitor [masterName] 192.168.56.10 6379 2
3、启动sentinel哨兵实例
src/redis‐sentinel sentinel‐26379.conf
sentinel 集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去,如果之前有配置过,最后一条最新的才是生效的配置
# 启动完成后,可以连接Redis后使用Info命令查看sentinel信息,配置多个,添加sentinel即可
src/redis‐cli ‐p 6399
info
#info命令执行后如下
#代表redis主节点的从节点信息
sentinel known‐replica masterTest 192.168.56.10 6380
#代表感知到的其它哨兵节点
sentinel known‐sentinel masterTest 192.168.56.10 6399 xxxxxxxx
SpringBoot 整合 Redis 并使用哨兵架构
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons‐pool2</artifactId>
</dependency
2.配置文件
spring:
redis:
database: 0
timeout: 3000
sentinel: #哨兵模式
master: masterTest #主服务器所在集群名称
nodes: 192.168.56.10:6379,192.168.56.10:26380:26380,192.168.56.10:6381
lettuce:
pool: #连接池想信息
max-idle: 50
min-idle: 10
max-actice: 800
max-wait: 800