当前位置: 首页 > news >正文

【第109期】4种 Redis 集群方案介绍+优缺点对比

9b8eb0194df90385909f5d875e2e0639.gif

来自:掘金,作者:有盐先生

链接:https://blog.csdn.net/Seky_fei/article/details/107239765

在服务开发中,单机都会存在单点故障的问题,及服务部署在一场台服务器上,一旦服务器宕机服务就不可用,所以为了让服务高可用,分布式服务就出现了,将同一服务部署到多台机器上,即使其中几台服务器宕机,只要有一台服务器可用服务就可用。

redis也是一样,为了解决单机故障引入了主从模式,但主从模式存在一个问题:master节点故障后服务,需要人为的手动将slave节点切换成为maser节点后服务才恢复。redis为解决这一问题又引入了哨兵模式,哨兵模式能在master节点故障后能自动将salve节点提升成master节点,不需要人工干预操作就能恢复服务可用。

但是主从模式、哨兵模式都没有达到真正的数据sharding存储,每个redis实例中存储的都是全量数据,所以redis cluster就诞生了,实现了真正的数据分片存储。但是由于redis cluster发布得比较晚(2015年才发布正式版 ),各大厂等不及了,陆陆续续开发了自己的redis数据分片集群模式,比如:Twemproxy、Codis等。

1、主从模式

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

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

e233278ba736d0c61d8ae1e1d4ccd453.png

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

主从模式优缺点

  1. 优点: 主从结构具有读写分离,提高效率、数据备份,提供多个副本等优点。

  2. 不足: 最大的不足就是主从模式不具备自动容错和恢复功能,主节点故障,集群则无法进行工作,可用性比较低,从节点升主节点需要人工手动干预。

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

  1. 在从数据库中使用SLAVE NO ONE命令将从数据库提升成主数据继续服务。

  2. 启动之前崩溃的主数据库,然后使用SLAVEOF命令将其设置成新的主数据库的从数据库,即可同步数据。

2、哨兵模式

第一种主从同步/复制的模式,当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用,这时候就需要哨兵模式登场了。

哨兵模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来。

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

3d6d7ac77290ea2d54f275774808c04f.png

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

2f6b37be1647c95320f4752cce4147f6.png
(1)哨兵模式的作用:

监控所有服务器是否正常运行:通过发送命令返回监控服务器的运行状态,处理监控主服务器、从服务器外,哨兵之间也相互监控。

故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。

(2)哨兵实现原理

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

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

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

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

  1. 订阅主数据库_sentinel_:hello频道以获取同样监控该数据库的哨兵节点信息

  2. 定期向主数据库发送info命令,获取主数据库本身的信息。

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

(1)每隔10s向master和 slave发送info命令。作用是获取当前数据库信息,比如发现新增从节点时,会建立连接,并加入到监控列表中,当主从数据库的角色发生变化进行信息更新。

(2)每隔2s向主数据里和从数据库的_sentinel_:hello频道发送自己的信息。作用是将自己的监控数据和哨兵分享。每个哨兵会订阅数据库的_sentinel:hello频道,当其他哨兵收到消息后,会判断该哨兵是不是新的哨兵,如果是则将其加入哨兵列表,并建立连接。

(3)每隔1s向所有主从节点和所有哨兵节点发送ping命令,作用是监控节点是否存活。

(3)主观下线和客观下线

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

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

  • 选出领头哨兵。

  • 领头哨兵所有的slave选出优先级最高的从数据库。优先级可以通过slave-priority选项设置。

  • 如果优先级相同,则从复制的命令偏移量越大(即复制同步数据越多,数据越新),越优先。

  • 如果以上条件都一样,则选择run ID较小的从数据库。

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

(4)哨兵模式优缺点

1.优点

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

2.不足-问题

  • 是一种中心化的集群实现方案:始终只有一个Redis主机来接收和处理写请求,写操作受单机瓶颈影响。

  • 集群里所有节点保存的都是全量数据,浪费内存空间,没有真正实现分布式存储。数据量过大时,主从同步严重影响master的性能。

  • Redis主机宕机后,哨兵模式正在投票选举的情况之外,因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机。

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

3、各大厂的Redis集群方案

Redis在3.0版本前只支持单实例模式,虽然Redis的开发者Antirez早在博客上就提出在Redis 3.0版本中加入集群的功能,但3.0版本等到2015年才发布正式版。各大企业等不急了,在3.0版本还没发布前为了解决Redis的存储瓶颈,纷纷推出了各自的Redis集群方案。这些方案的核心思想是把数据分片(sharding)存储在多个Redis实例中,每一片就是一个Redis实例。

(1)客户端分片

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

4d44ca9bf84716b41debaa8d9420c854.png

客户端分片的优缺点:

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

1.一致性哈希算法:

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

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

2.实现方式:一致性hash算法,比如MURMUR_HASH散列算法、ketamahash算法

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

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

不足:

  • 这是一种静态的分片方案,需要增加或者减少Redis实例的数量,需要手工调整分片的程序。

  • 运维成本比较高,集群的数据出了任何问题都需要运维人员和开发人员一起合作,减缓了解决问题的速度,增加了跨部门沟通的成本。

  • 在不同的客户端程序中,维护相同的路由分片逻辑成本巨大。比如:java项目、PHP项目里共用一套Redis集群,路由分片逻辑分别需要写两套一样的逻辑,以后维护也是两套。

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

(2)代理分片

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

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

b98c08e4a1c1eaf0ac217a2bcddfc2a6.png
Twemproxy的优点:
  • 客户端像连接Redis实例一样连接Twemproxy,不需要改任何的代码逻辑。

  • 支持无效Redis实例的自动删除。

  • Twemproxy与Redis实例保持连接,减少了客户端与Redis实例的连接数。

Twemproxy的不足:
  • 由于Redis客户端的每个请求都经过Twemproxy代理才能到达Redis服务器,这个过程中会产生性能损失。

  • 没有友好的监控管理后台界面,不利于运维监控。

  • Twemproxy最大的痛点在于,无法平滑地扩容/缩容。对于运维人员来说,当因为业务需要增加Redis实例时工作量非常大。

Twemproxy作为最被广泛使用、最久经考验、稳定性最高的Redis代理,在业界被广泛使用。

(3)Codis

Twemproxy不能平滑增加Redis实例的问题带来了很大的不便,于是豌豆荚自主研发了Codis,一个支持平滑增加Redis实例的Redis代理软件,其基于Go和C语言开发,并于2014年11月在GitHub上开源。

01872a3447f27fc4a9996a566a9323fe.png

在Codis的架构图中,Codis引入了Redis Server Group,其通过指定一个主CodisRedis和一个或多个从CodisRedis,实现了Redis集群的高可用。当一个主CodisRedis挂掉时,Codis不会自动把一个从CodisRedis提升为主CodisRedis,这涉及数据的一致性问题(Redis本身的数据同步是采用主从异步复制,当数据在主CodisRedis写入成功时,从CodisRedis是否已读入这个数据是没法保证的),需要管理员在管理界面上手动把从CodisRedis提升为主CodisRedis。

如果手动处理觉得麻烦,豌豆荚也提供了一个工具Codis-ha,这个工具会在检测到主CodisRedis挂掉的时候将其下线并提升一个从CodisRedis为主CodisRedis。

Codis中采用预分片的形式,启动的时候就创建了1024个slot,1个slot相当于1个箱子,每个箱子有固定的编号,范围是1~1024。slot这个箱子用作存放Key,至于Key存放到哪个箱子,可以通过算法“crc32(key)%1024”获得一个数字,这个数字的范围一定是1~1024之间,Key就放到这个数字对应的slot。

例如,如果某个Key通过算法“crc32(key)%1024”得到的数字是5,就放到编码为5的slot(箱子)。1个slot只能放1个Redis Server Group,不能把1个slot放到多个Redis Server Group中。1个Redis Server Group最少可以存放1个slot,最大可以存放1024个slot。因此,Codis中最多可以指定1024个Redis Server Group

Codis最大的优势在于支持平滑增加(减少)Redis Server Group(Redis实例),能安全、透明地迁移数据,这也是Codis 有别于Twemproxy等静态分布式 Redis 解决方案的地方。Codis增加了Redis Server Group后,就牵涉到slot的迁移问题。

例如,系统有两个Redis Server GroupRedis Server Group和slot的对应关系如下。

6df2fab229bfccb32fea961776a4fb09.png

当增加了一个Redis Server Group,slot就要重新分配了。Codis分配slot有两种方法:

第一种:通过Codis管理工具Codisconfig手动重新分配,指定每个Redis Server Group所对应的slot的范围,例如:可以指定Redis Server Group和slot的新的对应关系如下。

80398608bc76e7d93fcbc74983147c79.png

第二种:通过Codis管理工具Codisconfig的rebalance功能,会自动根据每个Redis Server Group的内存对slot进行迁移,以实现数据的均衡。

4、Redis Cluster

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

  • 哨兵模式下每台 Redis 服务器都存储相同的数据,很浪费内存空间;数据量太大,主从同步时严重影响了master性能。

  • 哨兵模式是中心化的集群实现方案,每个从机和主机的耦合度很高,master宕机到salve选举master恢复期间服务不可用。

  • 哨兵模式始终只有一个Redis主机来接收和处理写请求,写操作还是受单机瓶颈影响,没有实现真正的分布式架构。

redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。

Redis Cluster是一种服务器Sharding技术(分片和路由都是在服务端实现),采用多主多从,每一个分区都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。

96116c9bdea05928b34d0bf88a2f95e4.png

如上图,官方推荐,集群部署至少要 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节点负责维护一部分槽以及槽所映射的键值数据。

RECOMMEND

推荐阅读

96cff84eb7134f2f562715f72bd56a1d.png

01

Redis设计与实现

5f7e744cb2dfb038a7423d16712c337d.jpeg

黄健宏 著

推荐理由

Redis领域畅销NO.1著作系统而全面地描述了 Redis 内部运行机制。图示丰富,描述清晰,并给出大量参考信息,是NoSQL数据库开发人员案头必备,包括大部分Redis单机特征,以及所有多机特性。

6fe623c8d2b0d7f4b0c7eab69aaafab5.png

02

《Redis使用手册》

176e7873fb581b832c3476c7cd553257.jpeg

黄健宏 著

推荐理由

量示意图例的形式呈现,以求让读者在最短的时间内,以最舒服的方式,获得最核心的知识。本书系统化介绍Redis命令及其应用场景,内容深入,图文并茂,巨细靡遗,是掌握Redis的案头必备参考书。

e2ff6deea4bab8913c5b93feeb6b0713.png

03

Redis开发与运维》

e898eeec965947bf3e08fedd6be31763.jpeg

付磊、张益军 著 

推荐理由

从开发、运维两个角度总结了Redis实战经验,深入浅出地剖析底层实现,包含大规模集群开发与运维的实际案例、应用技巧。全面覆盖Redis 基本功能及应用,图示丰富,讲解细腻。

a6892f075aaaf369f09cea981e5ed544.png

04

Redis 5设计与源码分析》

370ccc8e9e84217351c04dbb6c88faa7.jpeg

陈雷 等著 

推荐理由

多名专家联袂推荐,资深专家联合撰写,深入理解Redis 5设计精髓

系统讲解Redis 5设计、数据结构、底层命令实现,以及持久化、主从复制、集群。

福利时间

第108期赠书活动中奖名单公布

e79aba4f5c34dfde5b5617835455f41e.jpeg

b50a40bd4c508e1860ddd32f9ddffcf7.jpeg

赠书规则

送书规则:感谢大家对华章图书的信任与支持。在留言区谈谈你想要哪本书及理由。小编会在留言池随机捞2条锦鲤,分别包邮送出1本正版书籍。本推文中的图书可任选一本。

截止日期:2022年7月8日下午16:00

特别注意

1、请按规则结合自身工作与学习的经历留言请规避百度式名词解释式言论,走心留言优先。

2、阅读最多、分享最多者优先。参与活跃者优先。同一人每月最多获赠一本书。

特别说明:本活动无任何内幕,最终解释权归华章分社所有。

6ffd3f02880cf459aacce15af01e27c4.gif

012e8d74d4c7732f83a3131d8ace8d55.jpeg

扫码关注【华章计算机】视频号

每天来听华章哥讲书

2c1876bdda3215fa4c673822ad412b7c.gif

更多精彩回顾

资讯 |《Java核心技术》基于Java 17全面升级!

干货 |再见了Java8,Java17:我要取代你

资讯 | Java核心技术大会2022 · 重磅发布

书单 |今天,Java27岁了!

新书 | 红蓝攻防:构建实战化网络安全防御体系

书讯 |7月书讯 | 12本新书如期而至!

每周赠书 | 【第108期】技术大牛都在看的10本书,找到了

新书 | 分布式算法精髓

干货 |详解大数据、数据存储和边缘计算技术在元宇宙中的应用

资讯 |Marcus再战三巨头,一场关于深度学习前景的辩论


d5b234693421a36dafacad0686f65eee.gif

相关文章:

  • 【Java核心技术大会 PPT分享】余洲:基于Smart Connect的跨地域数据复制
  • 这几年爆火的智能物联网(AIoT),到底前景如何?
  • 【Java核心技术大会 PPT分享】张家驹:云原生时代的Java — Quarkus及其最新进展...
  • 云计算发展的 4 个阶段,终于有人讲明白了
  • 【Java核心技术大会 PPT分享】陈阳:深入理解 Java 虚拟机编译原理
  • 学习 CSAPP 对工作有帮助吗?一切从底层逻辑开始!
  • 【Java核心技术大会 PPT分享】林子熠:GraalVM的静态编译和静态分析技术
  • 2022大数据十大关键词,重磅发布!
  • 第110期:成为架构师的路上,必看的经典好书
  • 用户运营方法论:解析不同时期的拉新策略
  • 运维数据治理,构筑智能运维的基石
  • 运营其实很重要
  • 万字长文:盘点2022全球10大数据泄漏事件(红蓝攻防角度)
  • 分布式数据库:如何正确选择分片键?
  • 企业数字化转型最难的是什么?就这两个字
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 2019年如何成为全栈工程师?
  • Making An Indicator With Pure CSS
  • Promise初体验
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • web标准化(下)
  • 阿里云应用高可用服务公测发布
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 缓存与缓冲
  • 排序算法之--选择排序
  • 入手阿里云新服务器的部署NODE
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 阿里云重庆大学大数据训练营落地分享
  • 积累各种好的链接
  • 说说我为什么看好Spring Cloud Alibaba
  • #android不同版本废弃api,新api。
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (二)正点原子I.MX6ULL u-boot移植
  • (六)软件测试分工
  • ./和../以及/和~之间的区别
  • .cfg\.dat\.mak(持续补充)
  • .chm格式文件如何阅读
  • .NET gRPC 和RESTful简单对比
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET 使用 XPath 来读写 XML 文件
  • .NET关于 跳过SSL中遇到的问题
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ 代码审计篇 ] 代码审计案例详解(一) SQL注入代码审计案例
  • [383] 赎金信 js
  • [C++] Boost智能指针——boost::scoped_ptr(使用及原理分析)
  • [IOI2018] werewolf 狼人
  • [Linux] Boot分区满了的处理方法 The volume boot has only 0 bytes disk space remaining
  • [linux] GFLOPS和TFLOPS的换算
  • [Linux版本Debian系统]安装cuda 和对应的cudnn以cuda 12.0为例
  • [one_demo_8]十进制转二进制