作者: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个槽位,在解决读写申请时,采纳crc32
Hash算法计算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开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!