欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

《Redis开发与运维》学习笔记3:主从复制,哨兵和集群

时间:2023-05-21

这篇主要整理第六章,第九章和第十章的内容,聚焦于Redis的分布式和集群部分,转载注明出处:https://blog.csdn.net/Koikoi12

复制

复制可以在分布式系统中实现相同数据的多个Redis副本,满足故障恢复和负载均衡等需求,是高可用的。

主节点有多个从节点,但每个从节点只能有一个主节点

关键命令:

slaveof {masterHost} {masterPort}从节点发起,目标是主节点slaveof no one从节点断开与主节点的关系


建立主从关系后,主节点会自动同步数据到从节点,从节点默认是只读模式,随意修改从节点数据会造成主从不一致。安全性和传输延迟问题可以按需配置


主从可以分为三种结构:

一主一从一主多从,主写,从读树状主从,写压力过大时,可以降低主节点负担,数据会向下复制


复制原理:全量/部分复制,偏移量机制,心跳机制,书上写了很多,感兴趣的自行深入。【Redis 开发与运维】复制

开发中的常见问题:主从可以配置不同,如aof主关闭从开启,但内存必须设置一致(因为主从数据一致);避免全量复制和频繁复制,解决方案是采用树形主从结构分摊主节点压力

哨兵

哨兵Sentinel的主要作用是故障转移:在主节点发生故障的时候,选举出新的leader。像zookeeper等分布式都用到了相似的选举过程。

Sentinel作为若干个节点存在,通过对Redis节点进行一一监控,且完全自动化

故障转移的4个步骤:

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

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

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

4.Sentinel调度各个节点,整个过程自动化使用了slaveof指令进行转移

转移后结构如图,实际上故障转移的工作只需一个Sentinel节点来完成即可(也就是leader)

实现原理:

1、Redis Sentinel的三个定时任务

每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构每隔2秒,每个Sentinel节点会向Redis数据节点的__sentinel__:hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息。作用:1.发现新的Sentinel节点,2.Sentinel节点之间交换主节点的状态每隔1秒,每个Sentinel节点会向主节点、从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达。

2、主观下线和客观下线

主观下线:Sentinel节点发送ping命令做心跳检测,当这些节点超过down-after-milliseconds没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线。客观下线: 当Sentinel主观下线的节点是主节点时,该Sentinel节点会通过sentinel ismaster-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过个数,Sentinel节点认为主节点确实有问题。如果大部分Sentinel节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。

3、领导者Sentinel节点选举和故障转移

使用了Raft算法进行选举通过过滤选举出最好的从节点进行故障转移,原故障节点更新为从节点,并保持监控

部署,API,客户端Jedis操作Sentinel三个模块本篇不整理,去看这篇:《Redis开发与运维》---- 哨兵(Redis Sentinel)

最后讲下如何实现高可用读写分离,正常情况下一个客户端对应一个slave,如果slave1挂了,Sentinel不会故障转移从节点,client1就会失联。高可用的解决如下图,可以加一个资源池,所有从节点放在里面,Sentinel客户端实时感知其状态,将其添加或删除

总结:

Sentinel可以故障转移,配置中心,客户端通知。尽可能在不同物理机上部署Sentinel节点节点个数最好大于等于3且为奇数(对主,从,其余Sentinel节点进行监控) 集群

为了解决内存,并发,流量等瓶颈,可以采用Redis集群方案

1.分区规则

数据量过大的时候,可以通过分区规则,分成多个子集来组成集群

分区方式上Redis集群用的是哈希分布

1.节点取余分区

使用特定的数据,如 Redis 的键或者用户ID,再根据节点数量 N 使用公式:hash(key) % N 计算出哈希值,用来决定数据映射到哪一个节点上。 这种方案存在一个问题:当节点数量变化时,如扩容或搜索节点,数据节点映射关系需要重新计算,会导致数据的重新迁移。

个人感觉和mysql分库分表通过id取余的思想很像

2.一致性哈希分区

实现思路是为系统中每个节点分配一个 token ,这些 token 构成一个哈希环。数据读写执行节点查找操作时,先根据 key 计算 hash 值,然后顺时针找到第一个大于等于该哈希值的 token 节点。

这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其他节点无影响。但还存在几个问题:

加减节点会造成哈希环中部分数据无法命中,需要手动处理或者忽略这部分数据,因此一致性哈希常用语缓存场景当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案普通的一致性哈希分区在增减节点时需要增加一倍或减去一半节点才能保证数据和负载的均衡

3.虚拟槽分区

虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中,整数定义为槽(slot)。这个范围一般远远大于节点数,比如 Redis Cluster 槽范围是 0 ~ 16383。

槽是集群内数据管理和迁移的基本单位。采用大范围槽的目的是为了方便数据拆分和集群扩展,每个节点负责一定数量的槽。假如当前集群有 5 个节点,则每个节点平均大约负责 3276 个槽。

2.Redis 数据分区

Redis 采用虚拟槽分区,所有的键根据哈希函数映射到 0 ~ 16383 整数槽内,计算公式:slot = CRC16(key) & 16383。

虚拟机槽的分区特点:

解耦数据和节点之间的关系,简化了节点扩容和搜索难度节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景 3.集群功能限制

Redis集群相比单机在功能上存在一些限制,需要开发人员提前了解:

key 批量操作支持有限。如 mset、mget,目前只支持具有相同 slot 值的key 执行批量操作。对于映射为不同 slot 值的 key,由于执行mset、mget 等操作可能存在于多个节点上,因此不被支持。key 事务操作支持有限。同理只支持多 key 在同一节点上的事务操作,当多个 key 分布在不同的节点上时无法使用事务功能。key 作为数据分区的最小粒度,因此不能将一个大的键值对象如 hash、list 等映射到不同的节点。不支持多数据库空间。单机下的 Redis 可以支持 16 个数据库,集群模式下只能使用一个数据库空间,即 db 0。复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。 4.搭建集群

环境搭建这里略过,按照书上步骤走更便于理解:【Redis 开发与运维】Redis Cluster 集群(一)

总共三步骤:1.准备节点,2.节点握手,3.分配槽。分配槽是重点:

或者用 redis-trib.rb 搭建集群(采用Ruby实现的集群管理工具,能快速搭建集群)

后面几个模块偏运维,哪些部分重要回头再细看:读书笔记:redis开发与运维 集群篇。稍微总结下:

集群是可以去中心化的,节点之间采用 P2P 的 Gossip 协议,通过ping/pong/meet/fail 进行通信,且支持灵活伸缩和故障转移

主从复制和集群的区别

主从复制为了数据备份,哨兵为了高可用,主服务器挂了通过哨兵切换集群是为了解决单机Redis容量有限的问题,将数据按一定的规则(分配槽)分配到多台机器,提高并发量

最后总结下三者:

主从复制:读写分离,备份,一个Master可以有多个Slaves。

哨兵Sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从Slaves中重新选举一个主服务器。

集群Redis Cluster:为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群,具有高扩展性。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。