Redis高级篇(一)分布式缓存

一、单点redis问题:

1、数据丢失问题

实现redis数据持久化

2、并发问题

搭建主从集群,实现读写分离

3、故障恢复问题

搭建redis哨兵,实现监控监测和自动恢复

4、存储能力问题

搭建分片集群,利用插槽机制实现动态扩容

二、Redis持久化

1、定义

利用永久性存储介质将数据进行保存,在特定的时间将保存的数据恢复的工作机制称为持久化。
(持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。)
Redis高级篇(一)分布式缓存_第1张图片

2、RDB持久化

(1)定义

  • RDB全称Redis Database Backup file(Redis数据备份文件),也叫Redis数据快照。是把内存中的所有数据记录到磁盘中。
  • 当redis实例故障重启后,从磁盘中读取快照文件,恢复数据。
  • 快照文件称为RDB文件,默认保存在当前运行文件。

(2)命令

  • save
    由Redis主进程来执行RDB,会阻塞所有命令。服务端正常停止,会执行一次。
    Redis高级篇(一)分布式缓存_第2张图片
  • bgsave
    开启子进程执行RDB,避免主进程受影响。
    Redis高级篇(一)分布式缓存_第3张图片
    Redis高级篇(一)分布式缓存_第4张图片
  • redis.conf配置

修改redis.conf文件中的save指令,redis会按照命令自动执行(bgsave)。

			#900秒内,至少有1个key被修改,则执行bgsave
			save 900 1 
			#文件保存的路径目录
			dir ./
			#RDB文件名称
			dbfilename dump.rdb

(3)底层原理

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后,读取内存数据写入Rdb文件,如下图:
Redis高级篇(一)分布式缓存_第5张图片

  • 所有的进程都不能直接操作物理内存,而是由操作系统给每个进程分配一个虚拟内存,主进程只能操作虚拟内存。操作系统会维护一个物理内存与虚拟内存之间映射关系表,即页表。
  • 主进程操作虚拟内存,而虚拟内存基于页表的映射关系,到物理内存真正的存储地址。
  • fork的过程是把页表进行拷贝给子进程。

问题:
由于bgsave是异步的,子进程在生成rdb文件时,主进程接收请求对数据进行修改。主进程写,子进程读,冲突,怎么办?
回答:
fork采用copy-on-write技术:
·当主进程执行读操作时,访问共享内存;
·当主进程执行写操作时,则会拷贝一份数据执行写操作

(4)优缺点

Redis高级篇(一)分布式缓存_第6张图片

(5)总结

Redis高级篇(一)分布式缓存_第7张图片

3、AOF持久化

(1)定义

AOF全称Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件中,可以看做是命令日志文件。
Redis高级篇(一)分布式缓存_第8张图片

(2)conf文件

AOF默认是关闭的,需要在redis.conf文件开启

//是否开启AOF功能,默认是no
	appendonly yes
//AOF文件名称
	appendfilename "appendonly.aof"
//AOF命令记录的频率
	//1、表示每执行一次写命令,都记录到AOF文件
		appendfsync always 
	//2、写命令执行完,先放入AOF缓存区中,然后每隔一秒将缓存区数据写入AOF文件(默认)
		appendfsync everysec 
	//3、写命令执行完,先放入AOF缓存区中,由操作系统决定何时写入磁盘
		appendfsync no 

Redis高级篇(一)分布式缓存_第9张图片

(3)AOF文件重写

因为是记录命令,AOF文件会比RDB文件大的多;AOF会记录同一个key的多次写操作,但只有最后一次有意义 bgrewriteaof

//重写文件
	bgrewriteaof
//AOF文件比上次文件 增长超过多少百分比才触发重写
	auto-aof-rewrite-percentage 100
//AOF文件体积最小在64m以上才触发重写
	auto-aof-rewrite-min-size 64mb

作用:降低磁盘占用量;提高持久化效率;提高数据恢复效率

4、RDB和AOF区别

Redis高级篇(一)分布式缓存_第10张图片

三、Redis主从架构

1、定义

单节点Redis的并发能力是有上限,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。
Redis高级篇(一)分布式缓存_第11张图片
主节点master,负责写操作;从节点slave,负责读操作,一主多从,增大读的能力;master数据同步slave节点

2、搭建主从集群

(1)创建目录
mkdir 7001 7002 7003
(2)复制redis.conf文件
cp redis-6.1.4/redis.conf 7001

修改port,dir
添加 声明ip replica-announce-ip 162.168.150.101

(3)配置主从

  • 从节点修改配置文件(永久生效)
    在redis.conf中添加replicaof/slaveof

  • 使用redis-cli客户端连接redis服务时,执行replicaof命令(重启后失效)

  • 查看情况 info replication

3、数据同步原理

(1)主从第一次同步是全量同步

Redis高级篇(一)分布式缓存_第12张图片

问题: master如何判断slave是第一次来同步数据?
  • Replication Id:简称replid,是数据集的标记,id一致则说明是统一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。
  • offset:偏移量。随着记录在master节点中的repl_baklog中的数据增多而逐渐增大。slave节点在同步时,也会记录offset。如果slave的offset小于master的offset,说明slave落后于master,需要更新

Redis高级篇(一)分布式缓存_第13张图片

总结:简述全量同步的流程
  1. slave节点请求增量同步
  2. master节点判断replid,发现不一致,拒绝增量同步
  3. master将完整内存数据生成RDB,发送RDB到slave
  4. slave清空本地数据,加载master的RDB
  5. master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
  6. slave执行接收到的命令,保持与slave之间的同步

(2)增量同步

如果slave重启后同步,则执行增量同步。
Redis高级篇(一)分布式缓存_第14张图片
Redis高级篇(一)分布式缓存_第15张图片

4、优化

Redis高级篇(一)分布式缓存_第16张图片

5、总结

(1)简述全量同步和增量同步的区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。
  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave。

(2)什么时候执行全量同步?

  • slave节点第一次连接master节点时
  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖

(3)什么时候执行增量同步?

slave节点断开又恢复,并且在repl_baklog中能找到offset时。

四、Redis哨兵(Sentinel)

1、哨兵的作用和原理

Redis高级篇(一)分布式缓存_第17张图片

(1)作用:实现主从集群的自动故障恢复。
(2)功能:
  • 监控:Sentinel会不断检查master和slave状态【如何获取节点状态?】。
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障恢复后,也是以新的master为主。
    选择slave依据是什么?】【如何实现故障转移
  • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将消息推送给Redis客户端
(3)获取节点状态:(判断一个redis实例是否健康)

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令

  • 主观下线:如果sentinel节点发现某Redis实例未在规定时间响应则认为该实例主观下线。
  • 客观下线:如果超过指定数量的sentinel都认为该实例主观下线,则该实例客观下线。数量值最好超过sentinel节点数量的一半。
  • Redis高级篇(一)分布式缓存_第18张图片
(4)选择slave依据:(故障转移步骤有哪些)
  • 首先会判断slave节点与master节点断开时间长短,如果超过指定值down-after-milliseconds * 10,则会排除该节点

  • 判断salve节点的slave-priority,值越小优先级越高,如果是0,则永不参与

  • 判断salve节点的offset值,值越大说明数据越新,优先级越高【最重要】

  • 判断slave节点的运行id大小,越小优先级越高

(5)如何实现故障转移:

当选择一个slave节点作为新的master后,故障转移步骤如下:

  • sentinel给备选的slave节点发送slaveof no one 命令,让该节点成为master节点

  • sentinel给所有其他的slave发送slaveof 【ip】【port】命令,让这些slave成为新master的从节点,开始从新的master上同步数据。

  • sentinel将故障节点标记为slave,执行slaveof命令,当故障恢复后,自动成为slave节点。

2、搭建哨兵集群

(1)mkdir s1 s2 s3
(2)在s1下新建sentinel.conf文件
Redis高级篇(一)分布式缓存_第19张图片

(3)启动
redis-sentinel s1/sentinel.conf

3、RedisTemplate的哨兵模式

(1)在pom文件中引入spring-boot-starter-data-redis
在这里插入图片描述
(2)application.yml指定sentinel相关信息
Redis高级篇(一)分布式缓存_第20张图片
(3)配置主从读写分离
Redis高级篇(一)分布式缓存_第21张图片

五、分片集群

主从和哨兵可以解决高可用、高并发读的问题,但是不能解决海量数据存储和高并发写的问题。

特征:

  1. 集群中有多个master,每个master保存不同数据
  2. 每个master都可以有多个slave节点。(主从)
  3. master之间通过ping监测彼此监控状态(哨兵)
  4. 客户端请求key访问集群任意节点,最终都会转发到正确节点
    Redis高级篇(一)分布式缓存_第22张图片

1、搭建

(1)mkdir 7001 7002 7003 8001 8002 8003
(2)redis.conf文件
Redis高级篇(一)分布式缓存_第23张图片
(3)复制文件到文件夹下,并修改
(4)启动
查看状态ps -ef|grep redis
(5)创建集群
redis-cli --cluster create --cluster-replicas 1 ip1:port1 ip2:port2 …
命令说明:

  1. redis-cli --cluster:集群操作命令
  2. create:创建集群
  3. –replicas 1或 --cluster-replicas 1 :指定集群中每个master的副本个数为1,此时 n = 节点总数 / (replicas + 1) 得到的就是master的数量。因此前n个是master,其他的是slave节点。

(6)测试
redis-cli -p 7001 cluster nodes

2、散列插槽

  • Redis会把每一个master节点映射到0~16383共16384个插槽(hash slot)上。
    Redis高级篇(一)分布式缓存_第24张图片

  • 根据key的有效部分计算hash值,在对16384取余,得到的结果就是slot值。
    在这里插入图片描述

  • 数据key不是与节点绑定,而是与插槽绑定。【为什么?】

  • 将同一类数据固定的保存在同一个Reids实例中,需要数据使用相同的有效数据,如key都已{typeId}为前缀

Redis高级篇(一)分布式缓存_第25张图片

3、集群收缩

(1)添加节点
redis-cli --cluster add-node 192.168.150.101:7004 192.168.150.101:7001
(2)分 插槽
redis-cli --cluster reshard 192.168.150.101:7001

4、故障转移

master宕机发生什么?
答:首先是该实例与其他实例失去连接;然后是疑似宕机,最后是确定下线,自动提升一个slave成为新的master
Redis高级篇(一)分布式缓存_第26张图片
Redis高级篇(一)分布式缓存_第27张图片

5、RedisTemplate访问

(1)引入redis的starter依赖
在pom文件中引入spring-boot-starter-data-redis
(2)配置分片集群地址
Redis高级篇(一)分布式缓存_第28张图片

(3)配置读写分离
在这里插入图片描述

你可能感兴趣的:(Redis,redis,缓存,数据库)