Redis总结

1. 概述

2. 使用场景

3. Redis Sentinel哨兵

3.1 故障转移过程

3.2 三个定时任务

4. Redis内存管理

4.1 内存消耗划分

4.2 内存回收策略

4.3 存溢出控制策略

5. 缓存击穿、缓存穿透

5.1 缓存击穿

5.2 缓存穿透

6. Redis Cluster集群

6.1 一致性哈希

7. 问题

7.1 Redis为什么是单线程

7.2 rehash过程

7.3 主从复制同步过程

1. 概述

Redis是一种基于键值对(key-value) 的NoSQL数据库

2. 使用场景

缓存

排行榜系统

计算器

社交网络

消息队列

3. Redis Sentinel哨兵

3.1 故障转移过程

1.主节点出现故障, 此时两个从节点与主节点失去连接, 主从复制失败。

2.每个Sentinel节点通过定期监控发现主节点出现了故障。

3.多个Sentinel节点对主节点的故障达成一致, 选举出sentinel-3节点作为领导者负责故障转移。

4.Sentinel领导者节点执行了故障转移

3.2 三个定时任务

1.每隔10秒, 每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。

2.每隔2秒, 每个Sentinel节点会向Redis数据节点的__sentinel__: hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息 , 同时每个Sentinel节点也会订阅该频道, 来了解其他Sentinel节点以及它们对主节点的判断, 所以这个定时任务可以完成以下两个工作:

发现新的Sentinel节点: 通过订阅主节点的__sentinel__: hello了解其他的Sentinel节点信息, 如果是新加入的Sentinel节点, 将该Sentinel节点信息保存起来, 并与该Sentinel节点创建连接。

Sentinel节点之间交换主节点的状态, 作为后面客观下线以及领导者选举的依据

3.每隔1秒, 每个Sentinel节点会向主节点、 从节点、 其余Sentinel节点发送一条ping命令做一次心跳检测, 来确认这些节点当前是否可达。

领导者sentinel节点选举

Raft算法

在从节点列表中选出一个节点作为新的主节点

a.过滤: “不健康”(主观下线、 断线) 、 5秒内没有回复过Sentinel节点ping响应、 与主节点失联超过down-after-milliseconds*10秒。

b.选择slave-priority(从节点优先级) 最高的从节点列表, 如果存在则返回, 不存在则继续。

c.选择复制偏移量最大的从节点(复制的最完整) , 如果存在则返回, 不存在则继续。

d.选择runid最小的从节点。

Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。

Sentinel领导者节点会向剩余的从节点发送命令, 让它们成为新主节点的从节点, 复制规则和parallel-syncs参数有关。

Sentinel节点集合会将原来的主节点更新为从节点, 并保持着对其关注, 当其恢复后命令它去复制新的主节点。

4. Redis内存管理

4.1 内存消耗划分

自身内存+对象内存+缓冲内存+内存碎片

4.2 内存回收策略

删除过期键:惰性删除,定时任务删除

4.3 存溢出控制策略

1) noeviction: 默认策略, 不会删除任何数据, 拒绝所有写入操作并返回客户端错误信息(error) OOM command not allowed when used memory, 此时Redis只响应读操作。

2) volatile-lru: 根据LRU算法删除设置了超时属性(expire) 的键, 直到腾出足够空间为止。 如果没有可删除的键对象, 回退到noeviction策略。

3) allkeys-lru: 根据LRU算法删除键, 不管数据有没有设置超时属性,直到腾出足够空间为止。

4) allkeys-random: 随机删除所有键, 直到腾出足够空间为止。

5) volatile-random: 随机删除过期键, 直到腾出足够空间为止。

6) volatile-ttl: 根据键值对象的ttl属性, 删除最近将要过期数据。 如果没有, 回退到noeviction策略。

5. 缓存击穿、缓存穿透

5.1 缓存击穿

在高并发下,对一个特定的值进行查询,但是这个时候缓存正好过期了,缓存没有命中,导致大量请求直接落到数据库上。

解决方案

缓存预热

缓存不过期

限流

多级缓存

5.2 缓存穿透

在高并发下,查询一个不存在的值时,缓存不会被命中,导致大量请求直接落到数据库上。

解决方案

1.缓存NULL值

2.布隆过滤器

6. Redis Cluster集群

6.1 一致性哈希

将所有的数据当做一个token环,token环中的数据范围是0到2的32次方。然后为每一个数据节点分配一个token范围值,这个节点就负责保存这个范围内的数据。

对每一个key进行hash运算,被哈希后的结果在哪个token的范围内,则按顺时针去找最近的节点,这个key将会被保存在这个节点上。

一致性哈希分区优点:

采用客户端分片方式:哈希 + 顺时针(优化取余) 节点伸缩时,只影响邻近节点,但是还是有数据迁移

一致性哈希分区缺点:

翻倍伸缩,保证最小迁移数据和负载均衡

虚拟槽分区

Redis Cluster中预设虚拟槽的范围为0到16383

步骤:

1.把16384槽按照节点数量进行平均分配,由节点进行管理 2.对每个key按照CRC16规则进行hash运算 3.把hash结果对16383进行取余 4.把余数发送给Redis节点 5.节点接收到数据,验证是否在自己管理的槽编号的范围 如果在自己管理的槽编号范围内,则把数据保存到数据槽中,然后返回执行结果 如果在自己管理的槽编号范围外,则会把数据发送给正确的节点,由正确的节点来把数据保存在对应的槽中

3.1 节点

Redis Cluster是分布式架构:即Redis Cluster中有多个节点,每个节点都负责进行数据读写操作

每个节点之间会进行通信。

3.2 meet操作

节点之间会相互通信

meet操作是节点之间完成相互通信的基础,meet操作有一定的频率和规则

3.3 分配槽

把16384个槽平均分配给节点进行管理,每个节点只能对自己负责的槽进行读写操作

由于每个节点之间都彼此通信,每个节点都知道另外节点负责管理的槽范围

3.4 复制

保证高可用,每个主节点都有一个从节点,当主节点故障,Cluster会按照规则实现主备的高可用性

对于节点来说,有一个配置项:cluster-enabled,即是否以集群模式启动

7. 问题

7.1 Redis为什么是单线程

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

7.2 rehash过程

7.3 主从复制同步过程

从节点 slaveof {mastHost} {mastPort}

slaveof no one来断开与主节点复制关系

1) 保存主节点(master) 地址信息

2) 从节点(slave) 内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后, 会尝试与该节点建立网络连接

3) 发送ping命令。

4) 权限验证。验证密码

5) 同步数据集。 主从复制连接正常通信后, 对于首次建立复制的场景, 主节点会把持有的数据全部发送给从节点, 这部分操作是耗时最长的步骤。

6) 命令持续复制。 当主节点把当前的数据同步给从节点后, 便完成了复制的建立流程。 接下来主节点会持续地把写命令发送给从节点, 保证主从数据一致性。

posted @ 2024-02-21 11:45  April.Chen  阅读(10)  评论(0)    收藏  举报