当前位置: 首页 > 科技观察

Redis 集群化的 3 种方案对比

时间:2023-03-12 06:41:10 科技观察

Redis集群三种方案对比< titlesplit >之前我们提到为了保证Redis的高可用,主要需要以下几个方面:数据持久化主从复制自动故障恢复集群下面简单了解一下这几种方案的特点,以及它们之间的联系。数据持久化本质上是为了数据备份。有了数据持久化,当Redis宕机时,我们可以从磁盘恢复数据,但是在数据恢复之前,服务是不可用的,数据恢复的时间取决于实例的大小,数据量越大,恢复得越慢。Redis的持久化过程可以参考:Redis是如何持久化的?RDB和AOF的对比分析。主从复制是部署多个副本节点,多个副本节点实时复制主节点的数据。当主节点宕机时,我们有一个完整的副本节点可以使用。另一方面,如果我们的业务有大量的读请求,而master节点无法承担所有的读请求,那么多个replica节点可以共享读请求,实现读写分离,可以提高Redis的访问性能。Redis6.0集群搭建实践但是有个问题就是当master节点宕机的时候,我们虽然有一个完整的replica节点,但是我们需要手动将slave节点升级为主节点才能继续提供服务。如果主节点每次都出现故障,需要人工操作,这个过程费时费力,时效性得不到保证,高可用度也会大大降低。如何优化呢?有了数据持久化、主从复制、故障自动恢复等功能,我们用Redis是不是就可以高枕无忧了?答案是不。如果我们的大部分业务是读请求,我们可以使用读写分离来提高性能。但是,如果写入请求量也很高怎么办?现在是大数据时代。像阿里巴巴、腾讯这样的大公司,任何时候都有非常大的写入量。如果此时只有一个主节点无法承受,如何处理?这需要集群!简单来说,实现方式就是多个主从节点组成一个集群,每个节点存储一部分数据,这样写请求也可以分布到多个主节点上,解决写压力大的问题。同时,集群可以在节点容量和性能不足时动态添加新节点,扩大组的容量,提高性能。从这篇文章开始,我们开始介绍Redis的集群方案。当然,集群化也意味着Redis的部署架构更加复杂,管理维护成本也更高。而且在使用过程中会遇到很多问题,这也导致了不同的集群解决方案各有侧重。在这篇文章中,我们先从整体上介绍几种比较流行的Redis集群方案。首先,我们对他们有一个整体的了解。后面我会专门详细分析一下我熟悉的集群方案。集群方案中为了实现集群,必须部署多个主节点,每个主节点可能有多个从节点。由这样的部署结构组成的集群,可以更好的承载更大的流量请求,存储更多的数据。能够承载更大的流量是集群最基本的功能。通用的集群方案还包括前面提到的数据持久化、数据复制、故障自动恢复等功能。这些技术用于保证集群的高性能和高可用。此外,优秀的集群方案还实现了在线水平扩展功能。当节点数量不足时,可以动态添加新的节点来提高整个集群的性能。而且,这个过程是在没有任何业务意识的情况下在线完成的。业界主流的Redis集群方案主要有以下几种:ClientshardingCodisTwemproxyRedisCluster也可以按照是否中心化来划分。其中clientsharding和RedisCluster属于非中心化集群方案,Codis和Tweproxy属于中心化集群方案。中心化是指客户端是直接访问多个Redis节点还是通过中间代理访问。直接访问是一种非中心化的方案,通过中间代理访问是一种中心化的方案,它们各有优缺点,下面分别介绍。ClientshardingClientsharding主要是指我们只需要部署多个Redis节点,这些节点如何使用主要是在客户端进行。客户端使用固定的Hash算法为不同的key计算出对应的Hash值,然后读写到不同的Redis节点。Clientshardingclustermodeclientsharding需要业务开发人员提前评估业务请求量和数据量,然后让DBA部署足够多的节点供开发人员使用。该方案的优点是部署非常方便。业务需要多少节点的DBA都可以直接部署交付。剩下的,需要业务开发人员根据节点数编写关键的请求路由逻辑,制定规则。一般使用固定的Hash。算法,将不同的key写入不同的节点,然后按照这个规则读取数据。可以看出其缺点是业务开发者使用Redis的成本高,需要编写路由规则代码才能使用多个节点,而且如果事先没有准确预估业务的数据量,后期扩容和迁移成本非常高,因为节点数量变化后,Hash算法对应的节点不再是之前的节点。所以后来又衍生出一致性哈希算法,尽可能解决节点数量变化时的数据迁移和性能问题。这种客户端分片方案一般用于业务数据量比较稳定,后期不会有大幅增长的业务场景。只需要评估前期的业务数据量。Codis随着业务和技术的发展,人们越来越觉得,当我需要使用Redis的时候,我们并不想去关心集群背后有多少个节点。我们希望我们使用的Redis是一个大集群。当我们的业务量增加时,这个Large集群可以增加新的节点来解决容量和性能问题。这种方法是服务端分片方案。客户端不需要关心集群后面有多少Redis节点。它只需要像Redis一样操作集群。该解决方案将大大降低开发人员的成本。开发者可以只需要关注业务逻辑,不需要关心Redis的资源。开发者如何像操作Redis一样使用由多个节点组成的集群?这涉及到如何组织多个节点来提供服务。一般我们会在客户端和服务端之间加一个代理层。客户端只需要操作这个代理层。代理层实现特定的请求转发规则,然后将请求转发到后面的多个节点,所以这种方式也称为集中式集群方案,Codis就是这样实现的集群方案。Proxy集群模式Codis架构图Codis由原中国豌豆荚大师开发,采用集中式集群方案。因为需要代理层Proxy来转发所有的请求,所以对Proxy的性能要求非常高。Codis采用Go语言开发,兼顾开发效率和性能。Codis包括多个组件:codis-proxy:主要负责转发读写请求codis-dashbaord:集数据转发规则、自动故障恢复、在线数据迁移、节点扩缩容、自动化运行DimensionAPI为一体的统一控制中心等功能codis-group:基于Redis3.2.8版本二次开发的RedisServer,增加异步数据迁移功能codis-fe:管理多集群的UI界面。可见Codis的组件还是很多的,功能也很全面。除了请求转发功能外,还实现了在线数据迁移、节点扩缩容、故障自动恢复等功能。Codis的Proxy是负责请求转发的组件。它内部维护着请求转发的具体规则。Codis将整个集群划分为1024个槽。在处理读写请求时,使用crc32Hash算法计算key的hash值,然后根据Hash值对1024槽取模,最终找到具体的Redis节点。Codis最大的特点是可以在线扩容,扩容期间不影响客户端的访问,也就是不需要宕机。这对于企业用户来说是非常方便的。当集群的性能不够时,可以动态添加节点来提高集群的性能。为了在迁移过程中实现在线扩展,保证数据的可靠性能,Codis对Redis进行了改造,增加了异步迁移数据的相关命令。基于Redis3.2.8开发,上层配合Dashboard和Proxy组件完成业务的无损数据迁移和扩展功能。因此,如果要使用Codis,就必须使用其内置的Redis,也就是说,Codis中的Redis能否跟上官方最新版本的特性可能无法保证。这取决于Codis的维护者。目前Codis已经不再维护,所以使用Codis时只能使用Redis3.2.8版本,这是一个痛点。另外,由于集群需要部署多个节点,因此集群的运行不能像运行单个Redis那样完全实现所有功能,主要是多节点运行可能出现问题的命令被禁用或限制。详情请参考Codis。支持的命令列表。但是这并不影响它是一个优秀的集群解决方案。由于我们公司较早使用Redis集群方案,当时RedisCluster还不够成熟,所以我们公司使用的Redis集群方案是Codis。目前,我的工作主要围绕Codis展开。我们公司对Codis进行了定制,对Redis做了一些修改,使Codis支持跨多个数据中心的数据同步。因此,我熟悉Codis代码。后面会写一些文章分析Codis的实现原理,学习它的原理,对我们理解分布式存储有很大的帮助!TwemproxyTwemproxy是Twitter的开源集群解决方案。它可以用作Redis代理和Memcached代理。它的功能比较简单,只实现请求路由转发。它没有Codis那样完善的在线扩展功能。其解决方案的重点是将client分片的逻辑统一到Proxy层,不对其他功能做任何处理。Tweproxy推出时间最长。在早期没有好的服务端分片集群方案的时候,它的应用范围很广,性能也非常稳定。但它的痛点在于无法在线进行扩缩容,运维起来非常不方便,也没有友好的运维UI可以使用。Codis就是在这样的背景下衍生出来的。当RedisCluster采用中间加一层Proxy的中心化模式时,对Proxy的要求很高,因为一旦失效,所有运行这个Proxy的客户端都无法处理。Proxy要实现高可用,需要另外一种机制,比如Keepalive。而且,增加一层Proxy进行转发,必然会有一定的性能损失。那么除了上面提到的客户端分片和中心化方案之外,还有没有更好的方案呢?Redis官方推出的RedisCluster则另辟蹊径。它没有采用中心化的Proxy方案,而是将请求转发逻辑一部分放在客户端,一部分放在服务端,它们相互配合完成请求处理。RedisCluster是在Redis3.0中推出的。早期的RedisCluster因为没有经过严格的测试和生产验证,并没有得到广泛推广。也正是在这样的背景下,业界衍生出了上述的中心化集群解决方案:Codis和Tweproxy。不过随着Redis的版本迭代,官方的RedisCluster也越来越稳定,越来越多的人开始采用官方的集群方案。正是因为正式上线,才能保证其持续维护,比那些第三方开源方案更有优势。RedisCluster没有中间代理层,那么如何转发请求呢?Redis将请求转发逻辑放在SmartClient中。使用RedisCluster需要升级ClientSDK。本SDK内置请求转发逻辑,业务开发者无需自己编写转发规则。RedisCluster使用16384个slot进行路由规则转发。没有代理层转发,客户端可以直接操作对应的Redis节点,减少了代理层转发的性能损失。RedisCluster还提供了在线数据迁移、节点扩缩容等功能,它还内置了sentinel来完成故障的自动恢复功能。可以看出它是一个集成了所有功能的Cluster。因此部署非常简单,不需要部署过多的组件,对运维极其友好。RedisCluster在迁移节点数据、扩缩容时,也会对客户端的请求进行相应的处理。当客户端访问的数据在迁移过程中时,服务器和客户端制定一些协议,通知客户端访问正确的节点,帮助客户端修正其路由规则。RedisCluster虽然提供了在线数据迁移的功能,但是其迁移性能并不高。迁移过程中遇到大key时,迁移的两个节点可能会阻塞很长时间。与Codis相比,这个功能,Codis的数据迁移性能更好。最好先在这里有个大概的了解。后面会专门写一些Codis和RedisCluster在线迁移功能性能对比的文章。现在越来越多的公司开始采用RedisCluster,有能力的公司也基于它进行了二次开发和定制,以解决RedisCluster存在的一些问题。期待RedisCluster在未来有更好的发展。小结在对比了这几种集群方案之后,下面总结一下。业界主流的集群方案有以上几种,简单介绍一下它们的特点和区别。我们在开发过程中可以选择自己适合的集群方案,但是最好了解一下它们的实现原理。只有在过程中遇到问题,才能更加从容地去解决。