阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Codis与RedisCluster的原理详解

128次阅读
没有评论

共计 3209 个字符,预计需要花费 9 分钟才能阅读完成。

背景介绍

我们先来看一下为什么要做集群,如果我们要部署一个单节点 Redis,很明显会遇到单点故障的问题。

Codis 与 RedisCluster 的原理详解

首先能想到解决单点故障的方法,就是做主从,但是当有海量存储需求时,单一的主从结构就会出问题,说问题之前要先了解一下主从之间是如何复制的。

Codis 与 RedisCluster 的原理详解

我们把 Redis 分为三个部分,分别是客户端、主节点以及从节点,如果从节点要同步主节点的数据,它首先会发 Sync 指令给主节点,主节点收到指令之后会执行 BGSAVE 命令生成 RDB 文件,这个 RDB 文件指的是快照文件,它是 Redis 两种备份方式的其中一种,另一种叫 AOF,它的原理是将所有的写入指令存入文件,MySQL 的 binlog 原理是一样的。

如果主节点在生成 RDB 的过程当中,客户端发来了写入指令,这个时候主节点会把指令全部写入缓冲区,等 RDB 生成完了,会把 RDB 文件发送给从节点,最后再把缓冲区的指令发送给从节点。这样就完成了整个的复制。

我们刚才说单纯地做主从是有缺陷的,这个缺陷就是如果我们要存储海量的数据,那么 BGSAVE 指令生成的 RDB 文件会非常巨大,这个文件传送给从节点也会非常慢,如果缓冲区命令很多的话,从节点同步数据时也会执行很久,所以,要解决单点问题和海量存储问题,还是要考虑做集群。

Codis 与 RedisCluster 的原理详解

Redis 常见集群方案

Redis 集群方案目前主流的有三种,分别是 Twemproxy、Codis 和 Redis Cluster。

Codis 与 RedisCluster 的原理详解

Twemproxy,是推特开源的,它最大的缺点就是无法平滑的扩缩容,而 Codis 解决了 Twemproxy 扩缩容的问题,而且兼容了 Twemproxy,它是由豌豆荚开源的,和 Twemproxy 都是代理模式。其实 Codis 能发展起来的一个主要原因是它是在 Redis 官方集群方案漏洞百出的时候率先成熟稳定的。以现在的 Redis 官方集群方案,这两个好像没有太大差别了,不过我也没有去做性能测试,不清楚哪个最好。

Redis Cluster 是由官方出品的,用去中心化的方式实现,不属于代理模式,今天主要讲 codis,redis cluster 后面也会过一下。下面,来看一下 Codis 的实现原理。

Codis 原理

我们换一种方式去讲,就按照 Codis 的架构演进一下,这样理解会比较清晰一点,假如现在只有一个 Redis Server,怎么让它变得高可用?

Codis 与 RedisCluster 的原理详解

开篇的时候也有讲,首先,能想到的就是做主从,这样就算主宕机了,从节点也能马上接替主节点的位置。

Codis 与 RedisCluster 的原理详解

我们现在已经做成主从结构了,那到底是谁来负责主从之间的切换?

Codis 与 RedisCluster 的原理详解

就是它,Sentinel,中文名叫哨兵,它呢,在 Redis 里面主要负责监控主从节点,如果主节点挂了,就会把从拉起来。但是哨兵本身也存在单点问题,所以它也需要做集群。

Codis 与 RedisCluster 的原理详解

那么问题来了,哨兵是如何做主从切换呢?来看下哨兵的运行机制。

Codis 与 RedisCluster 的原理详解

假如有三个哨兵和一主两从的节点,下面是一主多从,哨兵之间会互相监测运行状态,并且会交换一下节点监测的状态,同时哨兵也会监测主从节点的状态。

Codis 与 RedisCluster 的原理详解

如果检测到某一个节点没有正常回复,并且距离上次正常回复的时间超过了某个阈值,那么就认为该节点为主观下线。

这个时候其他哨兵也会来监测该节点是不是真的主观下线,如果有足够多数量的哨兵都认为它确实主观下线了,那么它就会被标记为客观下线,这个时候哨兵会找下线节点的从节点,然后与其他哨兵协商出一个从节点做主节点,并将剩余的从节点指向新的主节点。

Codis 与 RedisCluster 的原理详解

关于主从节点的切换有两个环节,第一个是哨兵要选举出领头人来负责下线机器的故障转移,第二是从 Slave 中选出主节点,领头人的选举规则是谁发现客观下线谁就可以马上要求其他哨兵认自己做老大,其他哨兵会无条件接受第一个发过来的人,并告知老大,如果超过一半人都同意了,那他老大的位置就坐实了。

关于从节点选举,一共有四个因素影响选举的结果,分别是断开连接时长、优先级排序、复制数量、进程 id,如果连接断开的比较久,超过了某个阈值,就直接失去了选举权,如果拥有选举权,那就看谁的优先级高,这个在配置文件里可以设置,数值越小优先级越高,如果优先级相同,就看谁从 master 中复制的数据最多,选最多的那个,如果复制数量也相同,就选择进程 id 最小的那个。

Codis 与 RedisCluster 的原理详解

现在继续回过来,刚才讲痛点的时候说了,如果有存储海量数据的需求,同步会非常缓慢,所以我们应该把一个主从结构变成多个,把存储的 key 分摊到各个主从结构中来分担压力。

Codis 与 RedisCluster 的原理详解

就像这样,代理通过一种算法把要操作的 key 经过计算后分配到各个组中,这个过程叫做分片,我们来看一下分片的实现原理。

Codis 与 RedisCluster 的原理详解

分片算法

Codis 与 RedisCluster 的原理详解

在 Codis 里面,它把所有的 key 分为 1024 个槽,每一个槽位都对应了一个分组,具体槽位的分配,可以进行自定义,现在如果有一个 key 进来,首先要根据 CRC32 算法,针对 key 算出 32 位的哈希值,然后除以 1024 取余,然后就能算出这个 KEY 属于哪个槽,然后根据槽与分组的映射关系,就能去对应的分组当中处理数据了。

CRC 全称是循环冗余校验,主要在数据存储和通信领域保证数据正确性的校验手段,我去看了这个算法的原理,还没理解透彻,这里就先不讲了,省得误导大家。

我们继续回过来,刚才所讲的槽位和分组的映射关系就保存在 codis proxy 当中,但是 codis proxy 它本身也存在单点问题,所以需要对 proxy 做一个集群。

Codis 与 RedisCluster 的原理详解

部署好集群之后,有一个问题,就是槽位的映射关系是保存在 proxy 里面的,不同 proxy 之间怎么同步映射关系?

在 Codis 中使用的是 Zookeeper 来保存映射关系,由 proxy 上来同步配置信息,其实它支持的不止 zookeeper,还有 etcd 和本地文件。在 zookeeper 中保存的数据格式就是这个样子。除了这个还会存储一些其他的信息,比如分组信息、代理信息等,感兴趣可以自己去了解一下。

Codis 与 RedisCluster 的原理详解

现在还有一个问题,就是 codis proxy 如果出现异常怎么处理,这个可能要利用一下 k8s 中 pod 的特性,在 k8s 里面可以设置 pod 冗余的数量,k8s 会严格保证启动的数量与设置一致,所以只需要一个进程监测 Proxy 的异常,并且把它干掉就可以了,k8s 会自动拉起来一个新的 proxy。

Codis 与 RedisCluster 的原理详解

codis 给这个进程起名叫 codis-ha,codis-ha 实时监测 proxy 的运行状态,如果有异常就会干掉,它包含了哨兵的功能,所以豌豆荚直接把哨兵去掉了。

Codis 与 RedisCluster 的原理详解

但是 codis-ha 在 Codis 整个架构中是没有办法直接操作代理和服务,因为所有的代理和服务的操作都要经过 dashboard 处理。所以部署的时候会利用 k8s 的亲和性将 codis-ha 与 dashboard 部署在同一个节点上。

Codis 与 RedisCluster 的原理详解

除了这些,codis 自己开发了集群管理界面,集群管理可以通过界面化的方式更方便的管理集群,这个模块叫 codis-fe,我们可以看一下这个界面。

Codis 与 RedisCluster 的原理详解

最后就是 redis 客户端了,这个没什么好讲的,客户端是直接通过代理来访问后端服务的。

Codis 与 RedisCluster 的原理详解

Redis Cluster 原理

下面来看一下 redis cluster 的原理,它和 codis 不太一样,Codis 它是通过代理分片的,但是 Redis Cluster 是去中心化的没有代理,所以只能通过客户端分片,它分片的槽数跟 Codis 不太一样,Codis 是 1024 个,而 Redis cluster 有 16384 个,槽跟节点的映射关系保存在每个节点上,每个节点每秒钟会 ping 十次其他几个最久没通信的节点,其他节点也是一样的原理互相 PING,PING 的时候一个是判断其他节点有没有问题,另一个是顺便交换一下当前集群的节点信息、包括槽与节点映射的关系等。客户端操作 key 的时候先通过分片算法算出所属的槽,然后随机找一个服务端请求。

Codis 与 RedisCluster 的原理详解

但是可能这个槽并不归随机找的这个节点管,节点如果发现不归自己管,就会返回一个 MOVED ERROR 通知,引导客户端去正确的节点访问,这个时候客户端就会去正确的节点操作数据。

Codis 与 RedisCluster 的原理详解

这是 RedisCluster 大概的原理,下面看一下 Codis 跟 RedisCluster 简要的区别。

Codis 与 RedisCluster 的原理详解

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计3209字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中