乐趣区

关于java:Redis-的-3-种集群方案对比写得非常好

作者:Kaito

起源:kaito-kidd.com/2020/07/07/redis-cluster-codis-twemproxy

之前咱们提到,为了保障 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 就是以这种形式实现的集群化计划。

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 反对了跨多个数据中心的数据同步。

Twemproxy

Twemproxy 是由 Twitter 开源的集群化计划,它既能够做 Redis Proxy,还能够做 Memcached Proxy。

它的性能比拟繁多,只实现了申请路由转发,没有像 Codis 那么全面有在线扩容的性能,它解决的重点就是把客户端分片的逻辑对立放到了 Proxy 层而已,其余性能没有做任何解决。

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

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

Redis Cluster 也提供了 在线数据迁徙、节点扩容缩容 等性能,外部还 内置了哨兵实现故障主动复原性能,可见它是一个集成所有性能于一体的 Cluster。因而它在部署时非常简单,不须要部署过多的组件,对于运维极其敌对。

Redis Cluster 在节点数据迁徙、扩容缩容时,对于客户端的申请解决也做了相应的解决。当客户端拜访的数据正好在迁徙过程中时,服务端与客户端制订了一些协定,来告知客户端去正确的节点上拜访,帮忙客户端勘误本人的路由规定。

尽管 Redis Cluster 提供了在线数据迁徙的性能,但它的迁徙性能并不高,迁徙过程中遇到大 key 时还有可能长时间阻塞迁徙的两个节点,这个性能相较于 Codis 来说,Codis 数据迁徙性能更好。

当初越来越多的公司开始采纳 Redis Cluster,有能力的公司还在它的根底上进行了二次开发和定制,来解决 Redis Cluster 存在的一些问题,咱们期待 Redis Cluster 将来有更好的倒退。

总结

比拟完了这些集群化计划,上面咱们来总结一下。

# 客户端分片 Codis Tweproxy Redis Cluster
集群模式 无中心化 中心化 中心化 无中心化
应用形式 客户端编写路由规定代码,直连 Redis 通过 Proxy 拜访 通过 Proxy 拜访 应用 Smart Client 直连 Redis,Smart Client 内置路由规定
性能 有性能损耗 有性能损耗
反对的数据库数量 多个 多个 多个 一个
Pipeline 反对 反对 反对 仅反对单个节点 Pipeline,不反对跨节点
需降级客户端 SDK?
反对在线程度扩容? 不反对 反对 不反对 反对
Redis 版本 反对最新版 仅反对 3.2.8,降级艰难 反对最新版 反对最新版
可维护性 运维简略,开发人员应用老本高 组件较多,部署简单 只有 Proxy 组件,部署简略 运维简略,官网继续保护
故障主动复原 需部署哨兵 需部署哨兵 需部署哨兵 内置哨兵逻辑,无需额定部署

业界支流的集群化计划就是以上这些,并对它们的特点和区别做了简略的介绍,咱们在开发过程中抉择本人适合的集群计划即可,但最好是了解它们的实现原理,在应用过程中遇到问题才能够更从容地去解决。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)

2. 终于靠开源我的项目弄到 IntelliJ IDEA 激活码了,真香!

3. 阿里 Mock 工具正式开源,干掉市面上所有 Mock 工具!

4.Spring Cloud 2020.0.0 正式公布,全新颠覆性版本!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版