Redis 集群化的 3 种方案对比

集群化方案

=====

要想实现集群化,就必须部署多个主节点,每个主节点还有可能有多个从节点,以这样的部署结构组成的集群,才能更好地承担更大的流量请求和存储更多的数据。

可以承担更大的流量是集群最基础的功能,一般集群化方案还包括了上面提到了数据持久化、数据复制、故障自动恢复功能,利用这些技术,来保证集群的高性能和高可用。

另外,优秀的集群化方案还实现了在线水平扩容功能,当节点数量不够时,可以动态增加新的节点来提升整个集群的性能,而且这个过程是在线完成的,业务无感知。

业界主流的Redis集群化方案主要包括以下几个:

  • 客户端分片

  • Codis

  • Twemproxy

  • Redis Cluster

它们还可以用是否中心化来划分,其中客户端分片、Redis Cluster属于无中心化的集群方案,Codis、Tweproxy属于中心化的集群方案。

是否中心化是指客户端访问多个Redis节点时,是直接访问还是通过一个中间层Proxy来进行操作,直接访问的就属于无中心化的方案,通过中间层Proxy访问的就属于中心化的方案,它们有各自的优劣,下面分别来介绍。

客户端分片

=====

客户端分片主要是说,我们只需要部署多个Redis节点,具体如何使用这些节点,主要工作在客户端。

客户端通过固定的Hash算法,针对不同的key计算对应的Hash值,然后对不同的Redis节点进行读写。

客户端分片集群模式

客户端分片需要业务开发人员事先评估业务的请求量和数据量,然后让DBA部署足够的节点交给开发人员使用即可。

这个方案的优点是部署非常方便,业务需要多少个节点DBA直接部署交付即可,剩下的事情就需要业务开发人员根据节点数量来编写key的请求路由逻辑,制定一个规则,一般采用固定的Hash算法,把不同的key写入到不同的节点上,然后再根据这个规则进行数据读取。

可见,它的缺点是业务开发人员使用Redis的成本较高,需要编写路由规则的代码来使用多个节点,而且如果事先对业务的数据量评估不准确,后期的扩容和迁移成本非常高,因为节点数量发生变更后,Hash算法对应的节点也就不再是之前的节点了。

所以后来又衍生出了一致性哈希算法,就是为了解决当节点数量变更时,尽量减少数据的迁移和性能问题。

这种客户端分片的方案一般用于业务数据量比较稳定,后期不会有大幅度增长的业务场景下使用,只需要前期评估好业务数据量即可。

Codis

=====

随着业务和技术的发展,人们越发觉得,当我需要使用Redis时,我们不想关心集群后面有多少个节点,我们希望我们使用的Redis是一个大集群,当我们的业务量增加时,这个大集群可以增加新的节点来解决容量不够用和性能问题

这种方式就是服务端分片方案,客户端不需要关心集群后面有多少个Redis节点,只需要像使用一个Redis的方式去操作这个集群,这种方案将大大降低开发人员的使用成本,开发人员可以只需要关注业务逻辑即可,不需要关心Redis的资源问题。

多个节点组成的集群,如何让开发人员像操作一个Redis时那样来使用呢?这就涉及到多个节点是如何组织起来提供服务的,一般我们会在客户端和服务端中间增加一个代理层,客户端只需要操作这个代理层,代理层实现了具体的请求转发规则,然后转发请求到后面的多个节点上,因此这种方式也叫做中心化方式的集群方案,Codis就是以这种方式实现的集群化方案。

Proxy集群模式

Codis架构图

Codis是由国人前豌豆荚大神开发的,采用中心化方式的集群方案。因为需要代理层Proxy来进行所有请求的转发,所以对Proxy的性能要求很高,Codis采用Go语言开发,兼容了开发效率和性能。

Codis包含了多个组件:

  • codis-proxy:主要负责对请求的读写进行转发

  • codis-dashbaord:统一的控制中心,整合了数据转发规则、故障自动恢复、数据在线迁移、节点扩容缩容、自动化运维API等功能

  • codis-group:基于Redis 3.2.8版本二次开发的Redis Server,增加了异步数据迁移功能

  • codis-fe:管理多个集群的UI界面

可见Codis的组件还是挺多的,它的功能非常全,除了请求转发功能之外,还实现了在线数据迁移、节点扩容缩容、故障自动恢复等功能

Codis的Proxy就是负责请求转发的组件,它内部维护了请求转发的具体规则,Codis把整个集群划分为1024个槽位,在处理读写请求时,采用crc32Hash算法计算key的Hash值,然后再根据Hash值对1024个槽位取模,最终找到具体的Redis节点。

Codis最大的特点就是可以在线扩容,在扩容期间不影响客户端的访问,也就是不需要停机。这对业务使用方是极大的便利,当集群性能不够时,就可以动态增加节点来提升集群的性能。

为了实现在线扩容,保证数据在迁移过程中还有可靠的性能,Codis针对Redis进行了修改,增加了针对异步迁移数据相关命令,它基于Redis 3.2.8进行开发,上层配合Dashboard和Proxy组件,完成对业务无损的数据迁移和扩容功能。

因此,要想使用Codis,必须使用它内置的Redis,这也就意味着Codis中的Redis是否能跟上官方最新版的功能特性,可能无法得到保障,这取决于Codis的维护方,目前Codis已经不再维护,所以使用Codis时只能使用3.2.8版的Redis,这是一个痛点。

另外,由于集群化都需要部署多个节点,因此操作集群并不能完全像操作单个Redis一样实现所有功能,主要是对于操作多个节点可能产生问题的命令进行了禁用或限制,具体可参考Codis不支持的命令列表。

但这不影响它是一个优秀的集群化方案,由于我司使用Redis集群方案较早,那时Redis Cluster还不够成熟,所以我司使用的Redis集群方案就是Codis。

目前我的工作主要是围绕Codis展开的,我们公司对Codis进行了定制开发,还对Redis进行了一些改造,让Codis支持了跨多个数据中心的数据同步,因此我对Codis的代码比较熟悉,后面会专门写一些文章来剖析Codis的实现原理,学习它的原理,这对我们理解分布式存储有很大的帮助!

Twemproxy

=========

Twemproxy是由Twitter开源的集群化方案,它既可以做Redis Proxy,还可以做Memcached Proxy。

它的功能比较单一,只实现了请求路由转发,没有像Codis那么全面有在线扩容的功能,它解决的重点就是把客户端分片的逻辑统一放到了Proxy层而已,其他功能没有做任何处理。

Twemproxy架构图

Tweproxy推出的时间最久,在早期没有好的服务端分片集群方案时,应用范围很广,而且性能也极其稳定。

但它的痛点就是无法在线扩容、缩容,这就导致运维非常不方便,而且也没有友好的运维UI可以使用。Codis就是因为在这种背景下才衍生出来的。

Redis Cluster

=============

采用中间加一层Proxy的中心化模式时,这就对Proxy的要求很高,因为它一旦出现故障,那么操作这个Proxy的所有客户端都无法处理,要想实现Proxy的高可用,还需要另外的机制来实现,例如Keepalive。

而且增加一层Proxy进行转发,必然会有一定的性能损耗,那么除了客户端分片和上面提到的中心化的方案之外,还有比较好的解决方案么?

Redis官方推出的Redis Cluster另辟蹊径,它没有采用中心化模式的Proxy方案,而是把请求转发逻辑一部分放在客户端,一部分放在了服务端,它们之间互相配合完成请求的处理。

Redis Cluster是在Redis 3.0推出的,早起的Redis Cluster由于没有经过严格的测试和生产验证,所以并没有广泛推广开来。也正是在这样的背景下,业界衍生了出了上面所说的中心化集群方案:Codis和Tweproxy。

但随着Redis的版本迭代,Redis官方的Cluster也越来越稳定,更多人开始采用官方的集群化方案。也正是因为它是官方推出的,所以它的持续维护性可以得到保障,这就比那些第三方的开源方案更有优势。

Redis Cluster没有了中间的Proxy代理层,那么是如何进行请求的转发呢?

Redis把请求转发的逻辑放在了Smart Client中,要想使用Redis Cluster,必须升级Client SDK,这个SDK中内置了请求转发的逻辑,所以业务开发人员同样不需要自己编写转发规则,Redis Cluster采用16384个槽位进行路由规则的转发。

Redis Cluster

没有了Proxy层进行转发,客户端可以直接操作对应的Redis节点,这样就少了Proxy层转发的性能损耗。

回答: Redis集群使用了哈希槽分区的方式来存储数据。集群将整个数据空间分成了16384个槽位,每个节点负责其中一部分槽位的数据存储。槽位的信息存储在每个节点中。\[1\]对于槽位的转移和分派,Redis集群不会自动进行,而是需要人工配置。因此,Redis集群的高可用性依赖于节点的主从复制和主从间的自动故障转移。\[1\] 在Redis集群方案中,推荐使用Redis cluster,除非是超大规模的集群,优先考虑使用Redis cluster。对于旧项目仍在使用codis的情况,可以继续使用,但也推荐迁移到Redis cluster。不建议使用twemproxy,因为它不能平滑地扩容。同时,客户端分片也应当禁止使用,因为扩容复杂,如果有多个服务同时读写,其中一个修改了路由,另一个不修改会出现问题。\[2\] Redis集群采用去中心架构,不依赖外部存储。每个节点都有槽位信息和一部分数据。各个节点之间使用gossip协议交互信息。数据根据分片规则被划分为16384个槽位,每个key根据crc16 % 16384的结果来确定对应的槽位id。每个Redis节点存储了一部分槽位的数据,各个节点共同分担16384个槽位。客户端需要遵守Redis cluster规范来读写数据。当客户端连接到集群时,会得到一份集群的槽位配置信息,并在本地缓存了槽位到节点的映射关系,以便能够直接定位到对应的Redis节点。\[3\] 综上所述,Redis集群使用哈希槽分区的方式来存储数据,每个节点负责一部分槽位的数据。集群的高可用性依赖于节点的主从复制和主从间的自动故障转移。推荐使用Redis cluster作为集群方案,不建议使用twemproxy和客户端分片。集群采用去中心架构,节点之间使用gossip协议交互信息,数据根据分片规则划分为16384个槽位。客户端连接集群时会得到槽位配置信息,并在本地缓存了槽位到节点的映射关系。 #### 引用[.reference_title] - *1* [8.2 Redis集群之数据分布](https://blog.csdn.net/Jgx1214/article/details/115166950)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Redis高可用之3集群方案对比](https://blog.csdn.net/leread/article/details/130216589)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值