Redis三种集群模式详解

2022-05-11 11:15:02 浏览数 (1)

三种集群模式

  • redis有三种集群模式,其中主从是最常见的模式。
  • Sentinel 哨兵模式是为了弥补主从复制集群中主机宕机后,主备切换的复杂性而演变出来的。哨兵顾名思义,就是用来监控的,主要作用就是监控主从集群,自动切换主备,完成集群故障转移。
  • cluster 模式是redis官方提供的集群模式,使用了Sharding 技术,不仅实现了高可用、读写分离、也实现了真正的分布式存储。

一、主从复制

redis主从复制

1、reids主从模式

2、redis复制原理

redis 的复制分为两部分操作 同步(SYNC)和 命令传播(command propagate)

  • 同步(SYNC)用来将从服务器的状态 更新到 和主服务器 一致。白话文解释就是从服务器主动获取 主服务器的数据。保持数据一致。具体实现是,主服务器收到SYNC命令后,生成RDB快照文件,然后发送给从服务器。
  • 命令传播 (command propagate)用于在主服务器数据被修改后,主从不一致,为了让从服务器保持和主服务器状态一致,而做的命令传播。白话文解释就是主服务器收到客户端修改数据命令后,数据库数据发生变化,同时将命令缓存起来,然后将缓存命令发送到从服务器,从服务器通过载入缓存命令来达到主从数据一致。这就是所谓的命令传播。
  • 为什么需要有同步和命令传播的两种复制操作:当只有同步操作时候,那么在从服务器向主服务器发送SYNC命令时候,主服务器在生成RDB快照文件时候,仍然会收到客户端的命令修改数据状态,这部分数据如果不能传达给从服务器,那么就会出现主从数据不一致的现象。这时候就出现了命令传播,主服务器收到从服务器的SYNC命令后,生成RDB快照文件同时,将此段时间内收到的命令缓存起来,然后使用命令传播的操作发送从服务器。来达到主从数据一致。

3、redis主从复制原理

上面介绍了redis复制的两种操作,而redis得主从复制正式基于 同步 和 命令传播 来实现得。下面两张图展示了redis复制的流程:

4、redis主从复制优缺点

优点:

1、实现读写分离,提高了可用性,解决了单机故障2、主从复制期间master和slave都是非阻塞方式,仍然可用。

缺点:

1、master宕机期间,需要手动切换主机,同时会有部分数据不能及时同步从服务器,造成数据不一致(需要人工手动介入)

2、slave宕机后,多个slave恢复后,大量的SYNC同步会造成master IO压力倍增(可以手动规避启动时间)

3、在线扩容较复杂。

总结: redis主从复制的优点主要是提高了可用性缺点

二、Sentinel 哨兵模式

Sentinel 哨兵Sentinel 哨兵介绍 Sentinel 哨兵本质上是一个运行在特殊模式下的Redis实例,只是初始化的过程和工作与普通的Redis不同,本质上也是一个单独的进程。 Sentinel 哨兵 是Redis的高可用解决方案:一个或多个Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在主服务器下线时可以自动切换从服务器升级为主服务器。

1、Sentinel系统

下图是一个简单的Sentinel系统架构图,一个Sentinel系统监视一个主从集群,其中server1是Redis主服务器,server2/3/4是Redis 从服务器。主从之间利用上面的主从复制来达到主从一致。而Sentinel系统监视整个主从集群。

2、Sentinel故障转移

当Sentinel系统察觉到Server1主服务器下线时,就会终止server2/3/4的复制。

同时Sentinel将server2升级为主服务器,server3/4从新的主服务器进行复制。同时等待server1的再次上线。

Sentinel系统也可以主动降级主服务为从服务器,将从服务器升级为主服务器。

2.1、Sentinel 哨兵监控过程

Sentinel 哨兵监控集群过程:

  • 命令 Sentinel哨兵通过发送命令,让redis服务器返回运行状态。发布订阅 当主服务器状态发生变化时,Sentinel哨兵通过
  • 发布订阅模式通知其他从服务器。
2.2、Sentinel 哨兵故障转移

Sentinel 故障转移:

  • 1、Sentinel系统中的Sentinel实例每隔1s就像集群发送PING命令
  • 2、如果集群中有实例的回复Sentinel实例时间超过了 down-after-milliseconds,那么这个实例就会发送PING命令的Sentinel实例被主观下线
  • 3、那么什么时候会客观下线呢?需要Sentinel系统中其他实例也确认集群中该实例主管下线。
  • 如果master主服务器被标记为主观下线,则Sentinel系统中监视master的Sentinel进程需要以每秒一次的频率确认Master是否进入主管下线状态
  • 4、当有足够的Sentinel实例(取决于配置)确认Master进入了主管下线,则Master会被标记为客观下线。
3、Sentinel 哨兵优缺点

优点:

1、哨兵模式基于主从复制,因此主从复制的优点哨兵都具备2、哨兵具备了主从切换和故障转移,因此集群有了更高的可用性

缺点:

1、Redis较难支持在线扩容,在线扩容比较复杂。

总结: sentinel 哨兵主要用来监控redis主从集群,提高了redis 主从集群的可用性。

三、cluster 模式

redis cluster

1、reids cluster

Redis Cluster是一种服务器 Sharding 技术,redis 3.0版本开始正式提供。 Sentinel基本已经实现了高可用,但是每台机器都存储相同内容,很浪费内存,所以Redis Cluster实现了分布式存储。每台机器节点上存储不同的内容。

2、Redis Cluster 数据分片原理

redis 数据分片使用的是hash slot, redis集群有16384个哈希槽,每个Key通过CRC16校验后对16384取模来决定放置哪一个槽。 当存取redis key时候,redis会根据CRC16算法得到一个结果,然后把结果和16384求余,通过这个值去对应得节点获取数据。 这个时候,应用客户端实际上只需要连接其中任意一个节点即可,然后Redis Cluster 中每个节点都保存了其他节点得槽信息。这样当存取key计算完槽之后,通过保存槽信息从配置中获取节点信息,然后再去对应得节点获取数据。

3、Redis Cluster 复制原理

redis-cluster集群引入了主从复制模型,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点 A1 都宕机了,那么该集群就无法再提供服务了

redis哨兵集群不足之处:

资源利用率低,只有一台主库对外提供服务 假如哨兵模式有3个节点,只有其中一个节点对外提供服务,其他两个节点都处于备份状态,这样就会造成资源的浪费,redis将数据都写在内存中,只有主节点工作,那么内存只有主节点上的那点内存,从节点上的内存也就造成了浪费 主库压力比较大,性能有瓶颈 只有主库在工作,所有的写都是主节点完成,这样就会造成主节点的压力比较大,从节点几乎没有压力 哨兵的不足之处就在于集群不是分布式存储,只是单节点去处理,如果集群时分布式存储,那么单点和压力的问题也就解决了

redis cluster适用场景:

当redis遇到单机、内存、并发、流量等瓶颈时,可以采用cluster架构方案达到负载均衡的目的

redis cluster之前的分布式方案:

客户端分区方案,优点分区逻辑可控,缺点是需要自己处理数据路由,高可用和故障转移等。代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点加重架构部署和性能消耗。

redis cluster的数据分布方式: 所有分布式数据库首先要解决把整个数据库集安装分区规则映射到多个节点的问题,也就是把数据集划分到多个节点上,redis cluster采用哈希分片规则,这样就能保证每个节点存储的数据量大致相同

redis cluster原理:

redis cluster会将数据自动进行分片,然后通过hash算法均匀的存放在集群中的每个节点,cluster架构在每台机器上都有一个或多个主节点和从节点,当一个节点上的master挂掉,会自动将这台机器上的某个slave切换为master

cluster架构的redis集群,可以横向扩容,由于cluster是分布式架构,单个机器的内存是32G,那么10个节点就是320G内存的存储

cluster架构数据分片是由hash来进行分配的,均匀的分散在各个节点

cluster架构槽位概念:每个cluster集群都有16384个槽位,这个槽位就是用来存储hash分配的分片,每一个槽位都需要分配到位,有一个槽位没有分配,整个集群都将无法使用,每一个槽位都有一个序号,它们不是顺序存放的,而是在节点一上比如有10-20序列槽位,节点二上有60-70序列的槽位,这两个节点都是10个槽位,序号不一定要顺序,但是数量一定要差不多,允许2%的误差

cluster集群架构图

通过hash分配数据分片到不同的redis主机

在应用端配置redis cluster地址时需要将所有节点的ip和端口都添加上

使用cluster集群创建的key,在哪个节点上创建的只能是自身节点可以查到数据,其他节点看不到

1.2.redis cluster不合理的架构图

不太合理的架构图

cluster集群每个机器上都有多个master和slave,如果master节点的数据备份都在自己主机的slave上,那么当服务器1坏掉后,这个机器上的数据就丢失了,数据丢失整个应用就崩溃了

合理的架构图

每个节点slave都存放在别的主机,即使当前主机挂掉,另一台直接还原数据即可

主从模式

Redis 单节点虽然有通过 RDB 和 AOF 持久化机制能将数据持久化到硬盘上,但数据是存储在一台服务器上的,如果服务器出现硬盘故障等问题,会导致数据不可用,而且读写无法分离,读写都在同一台服务器上,请求量大时会出现 I/O 瓶颈。

为了避免单点故障 和 读写不分离,Redis 提供了复制(replication)功能实现 master 数据库中的数据更新后,会自动将更新的数据同步到其他 slave 数据库上。

Redis 主从结构特点:一个 master 可以有多个 slave 节点;slave 节点可以有 slave 节点,从节点是级联结构。

主从模式优缺点
  • 优点: 主从结构具有读写分离,提高效率、数据备份,提供多个副本等优点。
  • 不足: 最大的不足就是主从模式不具备自动容错和恢复功能,主节点故障,集群则无法进行工作,可用性比较低,从节点升主节点需要人工手动干预。

普通的主从模式,当主数据库崩溃时,需要手动切换从数据库成为主数据库:

  1. 在从数据库中使用 SLAVE NO ONE 命令将从数据库提升成主数据继续服务。
  2. 启动之前崩溃的主数据库,然后使用 SLAVEOF 命令将其设置成新的主数据库的从数据库,即可同步数据。

哨兵模式

第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。哨兵模式是从 Redis 的 2.6 版本开始提供的,但是当时这个版本的模式是不稳定的,直到 Redis 的 2.8 版本以后,这个哨兵模式才稳定下来。

哨兵模式核心还是主从复制,只不过在相对于主从模式在主节点宕机导致不可写的情况下,多了一个竞选机制:从所有的从节点竞选出新的主节点。竞选机制的实现,是依赖于在系统中启动一个 sentinel 进程。

哨兵本身也有单点故障的问题,所以在一个一主多从的 Redis 系统中,可以使用多个哨兵进行监控,哨兵不仅会监控主数据库和从数据库,哨兵之间也会相互监控。每一个哨兵都是一个独立的进程,作为进程,它会独立运行。

哨兵模式的作用:
  • 监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,处理监控主服务器、从服务器外,哨兵之间也相互监控。
  • 故障切换:当哨兵监测到 master 宕机,会自动将 slave 切换成 master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换 master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。
哨兵实现原理:

哨兵在启动进程时,会读取配置文件的内容,通过如下的配置找出需要监控的主数据库:

代码语言:javascript复制
sentinel monitor master-name ip port quorum
# master-name 是主数据库的名字
# ip 和 port 是当前主数据库地址和端口号
# quorum 表示在执行故障切换操作前,需要多少哨兵节点同意。

这里之所以只需要连接主节点,是因为通过主节点的 info 命令,获取从节点信息,从而和从节点也建立连接,同时也能通过主节点的 info 信息知道新增从节点的信息。

一个哨兵节点可以监控多个主节点,但是并不提倡这么做,因为当哨兵节点崩溃时,同时有多个集群切换会发生故障。哨兵启动后,会与主数据库建立两条连接。

  1. 订阅主数据库 _sentinel_:hello 频道以获取同样监控该数据库的哨兵节点信息
  2. 定期向主数据库发送 info 命令,获取主数据库本身的信息。

跟主数据库建立连接后会定时执行以下三个操作:

  • 每隔 10s 向 master 和 slave 发送 info 命令。作用是获取当前数据库信息,比如发现新增从节点时,会建立连接,并加入到监控列表中,当主从数据库的角色发生变化进行信息更新。
  • 每隔 2s 向主数据里和从数据库的 _sentinel_:hello 频道发送自己的信息。作用是将自己的监控数据和哨兵分享。每个哨兵会订阅数据库的_sentinel:hello 频道,当其他哨兵收到消息后,会判断该哨兵是不是新的哨兵,如果是则将其加入哨兵列表,并建立连接。
  • 每隔 1s 向所有主从节点和所有哨兵节点发送 ping 命令,作用是监控节点是否存活。
主观下线和客观下线

哨兵节点发送 ping 命令时,当超过一定时间(down-after-millisecond)后,如果节点未回复,则哨兵认为主观下线。主观下线表示当前哨兵认为该节点已经下线,如果该节点为主数据库,哨兵会进一步判断是够需要对其进行故障切换,这时候就要发送命令(SENTINEL is-master-down-by-addr)询问其他哨兵节点是否认为该主节点是主观下线,当达到指定数量(quorum)时,哨兵就会认为是客观下线。

当主节点客观下线时就需要进行主从切换,主从切换的步骤为:

  • 选出领头哨兵。
  • 领头哨兵所有的 slave 选出优先级最高的从数据库。优先级可以通过 slave-priority 选项设置。
  • 如果优先级相同,则从复制的命令偏移量越大(即复制同步数据越多,数据越新),越优先。
  • 如果以上条件都一样,则选择 run ID 较小的从数据库。

选出一个从数据库后,哨兵发送 slave no one 命令升级为主数据库,并发送slaveof 命令将其他从节点的主数据库设置为新的主数据库。

哨兵模式的优缺点

优点:哨兵模式是基于主从模式的,解决可主从模式中master故障不可以自动切换故障的问题。

缺点:

  • 是一种中心化的集群实现方案:始终只有一个 Redis 主机来接收和处理写请求,写操作受单机瓶颈影响。
  • 集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响 master 的性能。
  • Redis 主机宕机后,哨兵模式正在投票选举的情况之外,因为投票选举结束之前,谁也不知道主机和从机是谁,此时 Redis 也会开启保护机制,禁止写操作,直到选举出了新的 Redis 主机。

主从模式或哨兵模式每个节点存储的数据都是全量的数据,数据量过大时,就需要对存储的数据进行分片后存储到多个 Redis 实例上。此时就要用到 Redis Sharding 技术。

Redis 集群方案

客户端分片

客户端分片是把分片的逻辑放在 Redis 客户端实现,(比如:jedis 已支持 Redis Sharding 功能,即 ShardedJedis),通过 Redis 客户端预先定义好的路由规则(使用一致性哈希),把对 Key 的访问转发到不同的 Redis 实例中,查询数据时把返回结果汇集。

一致性哈希算法:

是分布式系统中常用的算法。比如,一个分布式的存储系统,要将数据存储到具体的节点上,如果采用普通的 hash 方法,将数据映射到具体的节点上,如 mod(key,d),key 是数据的 key,d 是机器节点数,如果有一个机器加入或退出这个集群,则所有的数据映射都无效了。

一致性哈希算法解决了普通余数 Hash 算法伸缩性差的问题,可以保证在上线、下线服务器的情况下尽量有多的请求命中原来路由到的服务器。

一致性哈希算法实现方式:一致性 hash 算法,比如 MURMUR_HASH 散列算法、ketamahash 算法。比如 Jedis 的 Redis Sharding 实现,采用一致性哈希算法(consistent hashing),将 key 和节点 name 同时 hashing,然后进行映射匹配,采用的算法是 MURMUR_HASH。

采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的 rehashing。一致性哈希只影响相邻节点 key 分配,影响量小。

客户端分片的优缺点:

优点:客户端 sharding 技术使用 hash 一致性算法分片的好处是所有的逻辑都是可控的,不依赖于第三方分布式中间件。服务端的 Redis 实例彼此独立,相互无关联,每个 Redis 实例像单服务器一样运行,非常容易线性扩展,系统的灵活性很强。开发人员清楚怎么实现分片、路由的规则,不用担心踩坑。

缺点:

  • 这是一种静态的分片方案,需要增加或者减少 Redis 实例的数量,需要手工调整分片的程序。
  • 运维成本比较高,集群的数据出了任何问题都需要运维人员和开发人员一起合作,减缓了解决问题的速度,增加了跨部门沟通的成本。
  • 在不同的客户端程序中,维护相同的路由分片逻辑成本巨大。比如:java 项目、PHP 项目里共用一套 Redis 集群,路由分片逻辑分别需要写两套一样的逻辑,以后维护也是两套。

客户端分片有一个最大的问题就是,服务端 Redis 实例群拓扑结构有变化时,每个客户端都需要更新调整。如果能把客户端分片模块单独拎出来,形成一个单独的模块(中间件),作为客户端 和 服务端连接的桥梁就能解决这个问题了,此时代理分片就出现了。

代理分片

Redis 代理分片用得最多的就是 Twemproxy,由 Twitter 开源的 Redis 代理,其基本原理是:通过中间件的形式,Redis 客户端把请求发送到 Twemproxy,Twemproxy 根据路由规则发送到正确的 Redis 实例,最后 Twemproxy 把结果汇集返回给客户端。

Twemproxy 通过引入一个代理层,将多个 Redis 实例进行统一管理,使 Redis 客户端只需要在 Twemproxy 上进行操作,而不需要关心后面有多少个 Redis 实例,从而实现了 Redis 集群。

Redis Cluster

Redis 的哨兵模式虽然已经可以实现高可用,读写分离 ,但是存在几个方面的不足:

  • 哨兵模式下每台 Redis 服务器都存储相同的数据,很浪费内存空间;数据量太大,主从同步时严重影响了 master 性能。
  • 哨兵模式是中心化的集群实现方案,每个从机和主机的耦合度很高,master 宕机到 slave 选举 master 恢复期间服务不可用。
  • 哨兵模式始终只有一个 Redis 主机来接收和处理写请求,写操作还是受单机瓶颈影响,没有实现真正的分布式架构。

Redis 在 3.0 上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster 模式为了解决单机 Redis 容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS 不受限于单机,可受益于分布式集群高扩展性。Redis Cluster 是一种服务器 Sharding 技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个 Redis 主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster 集群采用了 P2P 的模式,完全去中心化。

官方推荐,集群部署至少要 3 台以上的 master 节点,最好使用 3 主 3 从六个节点的模式。Redis Cluster 集群具有如下几个特点:

  • 集群完全去中心化,采用多主多从;所有的 redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽。
  • 客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
  • 每一个分区都是由一个 Redis 主机和多个从机组成,分片和分片之间是相互平行的。
  • 每一个 master 节点负责维护一部分槽,以及槽所映射的键值数据;集群中每个节点都有全量的槽信息,通过槽每个 node 都知道具体数据存储到哪个 node 上。

Redis cluster 主要是针对海量数据 高并发 高可用的场景,海量数据,如果你的数据量很大,那么建议就用 Redis cluster,数据量不是很大时,使用 sentinel 就够了。Redis cluster 的性能和高可用性均优于哨兵模式。

Redis Cluster 采用虚拟哈希槽分区而非一致性 hash 算法,预先分配一些卡槽,所有的键根据哈希函数映射到这些槽内,每一个分区内的 master 节点负责维护一部分槽以及槽所映射的键值数据。

简单说一下redis-cluster里面槽?

槽是存放数据,存放是要通过key计算槽位,选择对应的服务器来存储,获取也是同样的算法.

默认16384个槽位要均匀分布到主节点上面

为了槽里面数据安全要对主节点进行1-N从节点备份

简单说一下redis-cluster里面选举投票机制

所有主节点都参与投票,默认半数以上挂点,启动容错机制,提升从节点为主节点.

0 人点赞