Redis 集群化4 种方案对比

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

之前我们提到,为了保证 Redis 的高可用,主要需要以下几个方面:

  • 数据持久化

  • 主从复制

  • 自动故障恢复

  • 集群化

我们简单理一下这几个方案的特点,以及它们之间的联系。

数据持久化本质上是为了做数据备份,有了数据持久化,当 Redis 宕机时,我们可以把数据从磁盘上恢复回来,但在数据恢复之前,服务是不可用的,而且数据恢复的时间取决于实例的大小,数据量越大,恢复起来越慢。

而主从复制则是部署多个副本节点,多个副本节点实时复制主节点的数据,当主节点宕机时,我们有完整的副本节点可以使用。另一方面,如果我们业务的读请求量很大,主节点无法承受所有的读请求,多个副本节点可以分担读请求,实现读写分离,这样可以提高 Redis 的访问性能。

但有个问题是,当主节点宕机时,我们虽然有完整的副本节点,但需要手动操作把从节点提升为主节点继续提供服务,如果每次主节点故障,都需要人工操作,这个过程既耗时耗力,也无法保证及时性,高可用的程度将大打折扣。如何优化呢?

有了数据持久化、主从复制、故障自动恢复这些功能,我们在使用 Redis 时是不是就可以高枕无忧了?

答案是否定的,如果我们的业务大部分都是读请求,可以使用读写分离提升性能。但如果写请求量也很大呢?现在是大数据时代,像阿里、腾讯这些大体量的公司,每时每刻都拥有非常大的写入量,此时如果只有一个主节点是无法承受的,那如何处理呢?

这就需要集群化!简单来说实现方式就是,多个主从节点构成一个集群,每个节点存储一部分数据,这样写请求也可以分散到多个主节点上,解决写压力大的问题。同时,集群化可以在节点容量不足和性能不够时,动态增加新的节点,对进群进行扩容,提升性能。

从这篇文章开始,我们就开始介绍 Redis 的集群化方案。当然,集群化也意味着 Redis 部署架构更复杂,管理和维护起来成本也更高。而且在使用过程中,也会遇到很多问题,这也衍生出了不同的集群化解决方案,它们的侧重点各不相同。

这篇文章我们先来整体介绍一下 Redis 集群化比较流行的几个解决方案,先对它们有整体的认识,后面我会专门针对我比较熟悉的集群方案进行详细的分析。

集群化方案

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

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

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

业界主流的 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 Cluster 也提供了在线数据迁移、节点扩容缩容等功能,内部还内置了哨兵完成故障自动恢复功能,可见它是一个集成所有功能于一体的 Cluster。因此它在部署时非常简单,不需要部署过多的组件,对于运维极其友好。

Redis Cluster 在节点数据迁移、扩容缩容时,对于客户端的请求处理也做了相应的处理。当客户端访问的数据正好在迁移过程中时,服务端与客户端制定了一些协议,来告知客户端去正确的节点上访问,帮助客户端订正自己的路由规则。

虽然 Redis Cluster 提供了在线数据迁移的功能,但它的迁移性能并不高,迁移过程中遇到大 key 时还有可能长时间阻塞迁移的两个节点,这个功能相较于 Codis 来说,Codis 数据迁移性能更好。这里先了解一个大概就好,后面我会专门针对 Codis 和 Redis Cluster 在线迁移功能的性能对比写一些文章。

现在越来越多的公司开始采用 Redis Cluster,有能力的公司还在它的基础上进行了二次开发和定制,来解决 Redis Cluster 存在的一些问题,我们期待 Redis Cluster 未来有更好的发展。

总结

比较完了这些集群化方案,下面我们来总结一下。

业界主流的集群化方案就是以上这些,并对它们的特点和区别做了简单的介绍,我们在开发过程中选择自己合适的集群方案即可,但最好是理解它们的实现原理,在使用过程中遇到问题才可以更从容地去解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值