一 :Redis 集群方式
Redis 有三种模式:分别是主从复制、哨兵模式、Cluster
模式 | 版本 | 优点 | 缺点 |
主从模式 | redis2 .8之前 | 1、解决数据备份问题 2、做到读写分离,提高服务器性能 | 1、master故障,无法自动故障转移, 需人工介入 2、master无法实现动态扩容 |
哨兵模式 | redis2 .8级之 后的模 式 | 1、Master状态监测 2、master节点故障,自动切换主从,故 障自愈 3、所有slave从节点,随之更改新的 master节点 | 1、slave节点下线,sentinel不会对 一进行故障转移,连接从节点的客户端 因为无法获取到新的可用从节点 2、master无法实行动态扩容 |
redis cluster模 式 | redis3 .0版本 之后 | 1、有效的解决了redis在分布式方面的 需求 2、遇到单机内存,并发和流量瓶颈等问 题时,可采用Cluster方案达到负载均 衡的目的 3、可实现动态扩容 4、P2P模式,无中心化 5、通过Gossip协议同步节点信息 6、自动故障转移、Slot迁移中数据可用 7、自动分割数据到不同的节点上 8、整个集群的部分节点失败或者不可达 的情况下能够继续处理命令 | 1、架构比较新,最佳实践较少 2、为了性能提升,客户端需要缓存路 由表信息 3、节点发现、reshard操作不够自动 化 4、不支持处理多个keys的命令,因 为这需要在不同的节点间移动数据 5、Redis集群不像单机Redis那样 支持多数据库功能,集群只使用默认 的 0 号 数 据 库 , 并 且 不 能 使 用 SELECT index命令 |
二:集群模式简介
集群,即Redis Cluster,是 Redis 3.0开始引入的分布式存储方案。集群由多个节点(Node)组成 ,Redis 的数据分布在这些节点中。集群中的节点分为主节点和从节点;只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。
redis 集群没有统一的入口,客户端连接集群的时候,连接集群中的任意节点即可。
Redis 集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。Redis 集群不需要 sentinel 哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种 集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000 个 节点)。redis 集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。redis 集群的 运用主要是针对海量数据+高并发+高可用的场景。
三:数据分片方式
对象保存到redis 之前先经过CRC16哈希到一个指定的Node 上,这个过程即redis cluster 的分片,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis nstance负责其中的一部分 的Slot 的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot 的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由(HASH_SLOT=CRC16(key)mod16384)决定。只有master节点会被分配槽位,slave节点不会分配槽位。
Redis Cluster 通过哈希算法将数据分散到多个节点上,实现数据的分片。每个节点负责管理一部分 数据,并提供相应的读写操作。分片机制可以将数据均匀地分布在多个节点上,提高系统的并发处理能力。 当某个节点发生故障时,只会影响该节点上的数据,而不会影响整个系统的可用性。
1: 客户端分片
客户端分片方案是将分片工作放在业务程序端。程序代码根据预先设置的路由规则,直接对多个 Redis 实例进行分布式访问。这样的好处是,群集不依赖于第三方分布式中间件,实现方法和代码都自己掌控,可随时调整,不用担心踩到坑。这实际上是一种静态分片技术,Redis 实例的增减,都得手工调整 分片程序。基于此分片机制的开源产品,现在仍不多见。
这种分片机制的性能比代理式更好(少了一个中间分发环节),但缺点是升级麻烦,对研发人员的个人依赖性强,需要有较强的程序开发能力做后盾。如果主力程序员离职,可能新的负责人会选择重写一遍。所以这种方式下可运维性较差,一旦出现故障,定位和解决都得研发人员和运维人员配合解决,故障时间变长。因此这种方案,难以进行标准化运维,不太适合中小公司。
2: 代理分片
代理分片方案是将分片工作交给专门的代理程序来做。代理程序接收到来自业务程序的数据请求,根 据路由规则,将这些请求分发给正确的 Redis 实例并返回给业务程序。
(1) Twemproxy 代理分片机制
客户端直接连接服务器方式,性能上有所损耗,实测性能效果降低了 20%左右。
(2)Codis 代理分片机制
Codis 由豌豆荚于2014年11月开源,基于 Go 语言和 C 语言开发,是近期涌现的、国人开发的 优秀开源软件之一,现已广泛用于豌豆荚的各种 Redis 业务场景。从各种压力测试来看,Codis 的稳定 性符合高效运维的要求。实测 Codis 集群业务处理性能改善很多,最初集群处理数据性能要比Twemproxy 差20% 左右,现在比Twemproxy 好很多。并且Codis 具有可视化运维管理界面。因此综合方面会优于 Twemproxy 很多。目前越来越多的公司选择 Codis。Twemproxy 是一种代理分片机制,由 Twitter 开源。Twemproxy 作为代理,可接受来自多个程序 的访问,按照路由规则,转发给后台的各个 Redis 服务器,再原路返回。这个方案顺理成章地解决了单 个 Redis 单实例问题。当然Twemproxy 本身也是单点,需要用Keepalived 做高可用方案。在很长的 时间内,Twemproxy 是应用范围最广、稳定性最高、最久经考验的分布式中间件。
3: 服务器端分片
服务器端分片是 Redis 官方的集群分片技术。Redis-Cluster 将所有 Key 映射到16384个 slot 中,集群中每个 Redis 实例负责一部分,业务程序是通过集成的 Redis-Cluster 客户端进行操作。客 户端可以向任一实例发出请求,如果所需数据不在该实例中,则该实例引导客户端自动去对应实例读写数 据。Redis-Cluster 成员之间的管理包括节点名称、IP 、端口、状态、角色等,都通过节点与之间两两 通讯,定期交换信息并更新。
四:负载均衡的实现
客户端路由:在Redis Cluster中,客户端需要根据数据的键名选择正确的节点进行读写操作。Redis Cluster 使用哈希槽(hash slot)来划分数据,并将每个哈希槽映射到相应的节点上。客户端可以根据键名的哈希值,将请求发送到对应的节点上,实现负载均衡。
自动迁移: Redis Cluster具有自动迁移功能,当节点加入或离开集群时,系统会自动重新分配数据,保持各个节点上哈希槽的均衡。当节点加入集群时,系统会将一部分哈希槽从其他节点迁移到新节点上;当节点离开集群时,系统会将该节点上的哈希槽重新分配给其他节点。这种机制可以在节点数目变化时,自动调整数据的分布,实现负载均衡。
故障检测与恢复: Redis Cluster具有故障检测和自动恢复的机制。集群中的节点会相互监控,检 测节点的健康状态。当某个节点被检测到不可用时,系统会自动将该节点标记为下线,并将该节点上的哈 希槽重新分配给其他节点。当节点恢复正常时,系统会将其重新加入集群,并进行数据迁移,保持数据的一致性。
五:故障的处理
1: 故障转移
当从节点发现自己的主节点变为已下线(FAIL)状态时,便尝试进 Failover, 以期成为新的主。 以下是故障转移的执行步骤:
(1)从下线主节点的所有从节点中选中一个从节点
(2)被选中的从节点执行SLAVEOF NONOE 命令,成为新的主节点
(3)新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己 (4)新的主节点对集群进行广播PONG消息,告知其他节点已经成为新的主节点
(5)新的主节点开始接收和处理槽相关的请求
(6)集群slots 是否必须完整才能对外提供服务
2: 多slave 选举
在多个slave 情况下如果一个master 宕机,需要基于Raft 协议选举方式来实现的新主的选举。步 骤如下:
( 1 ) 当 从 节 点 发 现 自 己 的 主 节 点 进 行 已 下 线 状 态 时 , 从 节 点 会 广 播 一 条CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST 消息,要求所有收到这条消息,并且具有投票权的主节点向这个从节点投票。
(2)如果一个主节点具有投票权,并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条,CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新 的主节点。
(3)每个参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK 消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持。
(4)如果集群里有N个具有投票权的主节点,那么当一个从节点收集到大于等于集群N/2+1张支持票时,这个从节点就成为新的主节点。
(5)如果在一个选举周期没有从能够收集到足够的支持票数,那么集群进入一个新的选举周期,并再次进 行选主,直到选出新的主节点为止。