Redis学习笔记(高级篇)(自用)
本文根据黑马程序员的课程资料与百度搜索的资料共同整理所得,仅用于学习使用,如有侵权,请联系删除
文章目录
1.Redis持久化
1.1RDB
Redis Database Backup file(Redis数据备份文件):把内存中的所有数据记录到磁盘中,
故障重启时读取快照文件即可恢复数据,Redis停机时会自动执行RDB
- RDB保存命令:
save # Redis主进程执行RDB,会阻塞所有命令
bgsave # 开启子进程执行RDB
- (原理)bgsave基本流程:
1.fork主进程得到子进程,共享内存空间
2.子进程读取内存数据并写入RDB文件
3.用新的RDB文件替换旧的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q4YEYg8y-1666326381189)(C:\Users\29851\Desktop\学习笔记\Redis学习笔记\image\RDB.png)]
- RDB配置:
redis.conf:
save 900 1 # 900s,如果有一个key被修改,则执行bgsave(save "" # 禁用RDB,时间建议不要太短)
rdbcompression yes #是否压缩,建议不开启(压缩消耗cpu)
dbfilename test.rdb # RDB文件名称
dir ./ # 保存路径
-
RDB何时进行?默认服务停止时
-
缺点:执行间隔长(数据丢失风险)、bgsave较耗时
1.2 AOF
AOF(Append Only File 追加文件),可看作命令日志文件
- AOF配置
appendonly yes # 是否开启AOF功能,默认为no
appendfilename "xxx.aof"
appendfsync everysec # 刷盘时机,默认方案
# appendfsync always
# appendfsync no
- 刷盘时机
配置项 | 刷盘时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步 | 可靠性高,几乎不会丢数据 | 性能影响大 |
everysec | 每秒 | 性能适中 | 最多丢1s数据 |
no | 操作系统控制 | 性能最好 | 可靠性差,可能丢失大量数据 |
- 重写AOF(bgrewriteaof)
许多set xxx xxx ===》 mset xxx aaa bbb
auto-aof-rewrite-percentage 100 # 比上一次文件,增长超过多少百分比则触发重写
auto-aof-rewrite-min-size 64mb # 最小多大以上触发重写
1.3 对比
RDB | AOF | |
---|---|---|
持久化方式 | 定时对内存做快照 | 记录每一次执行的命令 |
文件大小 | 较小(有压缩) | 大 |
系统资源占用 | 高(大量CPU内存消耗) | 低(主要为磁盘IO资源,但AOF重写占用高) |
宕机恢复速度 | 快 | 慢 |
数据完整性 | 不完整,两次备份间会丢失 | 相对完整(取决于刷盘策略) |
数据恢复优先级 | 低 | 高 |
使用场景 | 追求更快的启动速度,可容忍数分钟的数据丢失 | 对数据安全性要求高 |
2. 主从架构
2.1主从集群
-
读写分离:向master写,从slave/replica读
-
实操:
1.拷贝配置文件到每个实例目录中
2.修改每个实例的端口(port)、工作目录(dir)
3.修改每个实例的声明命令(replica-announce-ip xxx)
- 开启主从关系:
(永久生效)配置文件修改
slaveof <masterip> <masterport>
(临时生效)
redis-cli -p xxxx
x.x.x.x:xxxx > slaveof <masterip> <masterport>
2.2 全量同步
第一次同步、断开时间过长(repl_backlog的offset被覆盖)
-
Replication_id(replid):id一致说明时同一数据集、每个master都有唯一的id、slave会继承master的id
-
offset(偏移量):repl_baklog数据越多越大、slave完成同步会记录当前的offset、若offset小说明落后于master
-
流程:
1.slave发起请求(psync replid offset) 2.master判断id(不一致拒绝增量同步)
3.master将完整内存数据生成RDB,发送 4.slave清空本地数据、加载来自master的RDB
5.master将RDB期间发生的后续命令记录于repl_baklog,持续将log中的命令发给slave
6.slave接受命令,保持同步
2.3 增量同步
断开又恢复
-
repl_backlog大小有上限(环形结构),写满后就会覆盖之前的数据,导致不得不全量同步
-
流程:
1.slave发起请求 2.master判断id(一致进行增量同步)
3.master回复continue 4.在repl_backlog中获取offset后的数据
5.持续将log中的命令发给slave
优化Redis主从集群:
1.在master中配置repl-diskless-sync yes启用无磁盘复制,即直接从内存中往网络中发,避免全量同步时的磁盘IO。
2.Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO。
3.适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步。
4.限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力。(如下图所示)
3.哨兵机制(哨兵集群)
3.1 监控
每隔1s发ping
-
主观下线:未在规定时间内响应
-
quorum:最好超过哨兵总量的一半
-
客观下线:超过quorum的哨兵都认为master主观下线了
3.2 自动故障恢复(选举换主)
1.判断slave与master断开时间长短,超过指定值(down-after-milliseconds * 10)则会被排除
2.slave-priority 越小优先级越高(0表示不参与选举)
3.若优先级一样,判断slave节点的offset值,越大代表越新,越优先
4.最后根据运行id判断,越小越优先
3.3 通知(故障转移)
1.给备选节点发送slaveof no one命令,成为master
2.向其他节点发送slaveof x.x.x.x(newmaster ip) xxxx(newmaster port)命令,使其他的成为新master的从节点
3.将故障节点标记为slave,故障节点恢复后成为slave
3.4 实操
sentinel.conf:
port 26379 # 此Sentinel实例运行的端口
sentinel announce-ip <ip>
sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel down-after-milliseconds <master-name> <milliseconds> # 主观下线时间(默认5000)
sentinel failover-timeout <master-name> <milliseconds> # 指定故障转移超时(以毫秒为单位)(默认60000)
dir "" # 目录
启动:
redis-sentinel sentinel.conf
3.5 RedisTemplate哨兵机制
spring:
redis:
sentinel:
master: mymaster # master名称
nodes:
- x.x.x.x:xxxx
- x.x.x.x:xxxx # 集群信息
读写分离:
@Bean
public LettuceClientConfigurationBuilderCustomizer{
return new LettuceClientConfigurationBuilderCustomizer(){
@Override
public void customize(LettuceClientConfiguration.LettuceClientConfigurationBuilder clientConfigurationBuilder){
clientConfigurationBuilder,readForm(ReadFrom.REPLICA_PREFERRED);
}
}
}
@Bean
public LettuceClientConfigurationBuilderCustomizer configurationBuilderCustomizer(){
return configBuilder->configBuilder.readForm(ReadFrom.REPLICA_PREFERRED);
}
MASTER 主节点读取
MASTER_PREFERED 优先主节点,不可用后用副节点
REPLICA 副节点读取
REPLICA_PREFERED 优先副节点,不可用后用主节点
4.分片集群结构
-
多个master,每个保存不同数据,每个master有多个slave
-
master之间通过ping监测彼此状态
-
客户端可访问集群任意节点,最终转发到正确节点
4.1 设置
cluster-enabled yes # 开启集群功能
cluster-config-file /tmp/6379/nodes.conf # 集群配置文件名称(不需要创建,redis自己维护)
cluster-node-timeout 5000 # 节点心跳失败超时时间
启动:
redis-cli --cluster create --cluster-replicas 1 x.x.x.x:xxxx x.x.x.x:xxxx ...(所有ip端口)
# --cluster-replicas 1 每个集群的副本数量
# 节点数/(replicas + 1) = master数 6/2 = 3 前为主,后为从
redis-cli -p 7001(端口) cluster nodes
# 查看集群状态
4.2 散列插槽
master节点映射到16384个插槽(hash slot)中,key与插槽绑定
(key有效部分{}或整个,利用CRC16算法得出hash值,16384取余得到slot)
(将同一类数据保存在同一个Redis实例中:使用相同有效部分,以{typeId}为前缀)
4.3 集群伸缩
添加一个节点
redis-cli --cluster help
redis-cli --cluster add-node x.x.x.x:xxxx(要添加的) x.x.x.x:xxxx(主节点)
redis-cli --cluster reshard x.x.x.x:xxxx # 移动插槽=拷贝数据
-
故障转移:同主从
-
数据迁移:cluster failover 手动让给集群中的某个master
4.4 RedisTemplate哨兵机制访问分片集群
spring:
redis:
cluster:
nodes:
- x.x.x.x:xxxx
- x.x.x.x:xxxx # 集群信息