搜索
首页数据库RedisRedis集群实例分析

一、Why K8s

1、资源隔离

当前的Redis Cluster部署在物理机集群上,为了提高资源利用率节约成本,多业务线的Redis集群都是混布的。由于没有做CPU的资源隔离,经常出现某Redis节点CPU使用率过高导致其他Redis集群的节点争抢不到CPU资源引起时延抖动。因为不同的集群混布,这类问题很难快速定位,影响运维效率。K8s容器化部署可以指定 CPU request 和 CPU limit ,在提高资源利用率的同时避免了资源争抢。

2、自动化部署

当前Redis Cluster在物理机上的部署过程十分繁琐,需要通过查看元信息数据库查找有空余资源的机器,手动修改很多配置文件再逐个部署节点,最后使用redis_trib工具创建集群,新集群的初始化工作经常需要一两个小时。

K8s通过StatefulSet部署Redis集群,使用configmap管理配置文件,新集群部署时间只需要几分钟,大大提高了运维效率。

二、How K8s

客户端通过LVS的VIP统一接入,通过Redis Proxy转发服务请求到Redis Cluster集群。这里我们引入了Redis Proxy来转发请求。

Redis集群实例分析

1、Redis Cluster部署方式

Redis部署为StatefulSet,作为有状态的服务,选择StatefulSet最为合理,可以将节点的RDB/AOF持久化到分布式存储中。当节点重启漂移到其他机器上时,可通过挂载的PVC(PersistentVolumeClaim)拿到原来的RDB/AOF来同步数据。

Ceph块服务是我们所选择的持久化存储PV(PersistentVolume)。Ceph的读写性能较本地硬盘差,会导致读写延迟增加100~200毫秒。分布式存储的读写延迟并没有影响服务,因为Redis的RDB/AOF写出是异步的。

Redis集群实例分析

2、Proxy选型

开源的Redis Proxy有很多,常见的开源Redis Proxy如下:

我们希望能够继续使用Redis Cluster来管理Redis集群,所以Codis和Twemproxy不再考虑。redis-cluster-proxy是Redis官方在6.0版本推出的支持Redis Cluster协议的Proxy,但是目前还没有稳定版,暂时也无法大规模应用。

备选就只有Cerberus和Predixy两种。下面是我们在K8s环境中对Cerberus和Predixy进行的性能测试结果:

测试环境

测试工具: redis-benchmark

Proxy CPU: 2 core

Client CPU: 2 core

Redis Cluster: 3 master nodes, 1 CPU per node

测试结果

Redis集群实例分析

Redis集群实例分析

Predixy在相同的工作负载和配置下,能够获得更高的QPS,而其延迟也与Cerberus相当接近。综合来看,Predixy比Cerberus的性能要高33%~60%,并且数据的key/value越大,Predixy优势越明显,所以最后我们选择了Predixy。

为了适应业务和K8s环境,在上线前我们对Predixy做了大量的改动,增加了很多新的功能,比如动态切换后端Redis Cluster、黑白名单、异常操作审计等。

3、Proxy部署方式

由于其无状态轻量化的部署特性,使用代理(Proxy)作为部署方式,经由负载均衡(LB)提供服务,能够轻松地实现动态的扩容和缩容。同时,我们为Proxy开发了动态切换后端Redis Cluster的功能,可实现在线添加和切换Redis Cluster。

4、Proxy自动扩缩容方式

我们使用K8s原生的HPA(Horizontal Pod Autoscaler)来实现Proxy的动态扩缩容。当Proxy所有pod的平均CPU使用率超过一定阈值时,会自动触发扩容,HPA会将Proxy的replica数加1,之后LVS就会探测到新的Proxy pod并将一部分流量切过去。当CPU使用率超过规定的阈值后进行扩容,若仍未达到要求则会持续触发扩容逻辑。但是在扩容成功5分钟内,不论CPU使用率降到多低,都不会触发缩容逻辑,这样就避免了频繁的扩缩容给集群稳定性带来的影响。

HPA可配置集群的最少(MINPODS)和最多(MAXPODS)pod数量,集群负载再低也不会缩容到MINPODS以下数量的pods。建议客户自行判断其实际业务状况以确定MINPODS和MAXPODS的取值。

三、Why Proxy

1、Redis pod重启可导致IP变化

使用Redis Cluster的Redis客户端,都需要配置集群的部分IP和Port,用于客户端重启时查找Redis Cluster的入口。对于物理机集群部署的Redis节点,即便遇到实例重启或者机器重启,IP和Port都可以保持不变,客户端依然能够找到Redis Cluster的拓扑。但是部署在K8s上的Redis Cluster,pod重启是不保证IP不变的(即便是重启在原来的K8s node上),这样客户端重启时,就可能会找不到Redis Cluster的入口。

通过在客户端和Redis Cluster之间加上Proxy,就对客户端屏蔽了Redis Cluster的信息,Proxy可以动态感知Redis Cluster的拓扑变化,客户端只需要将LVS的IP:Port作为入口,请求转发到Proxy上,即可以像使用单机版Redis一样使用Redis Cluster集群,而不需要Redis智能客户端。

2、Redis处理连接负载高

在6.0版本之前,Redis都是单线程处理大部分任务的。当Redis节点的连接较高时,Redis需要消耗大量的CPU资源处理这些连接,导致时延升高。有了Proxy之后,大量连接都在Proxy上,而Proxy跟Redis实例之间只保持很少的连接,这样降低了Redis的负担,避免了因为连接增加而导致的Redis时延升高。

3、集群迁移切换需要应用重启

在使用过程中,随着业务的增长,Redis集群的数据量会持续增加,当每个节点的数据量过高时,BGSAVE的时间会大大延长,降低集群的可用度。同时QPS的增加也会导致每个节点的CPU使用率增高。这都需要增加扩容集群来解决。目前Redis Cluster的横向扩展能力不是很好,原生的slots搬移方案效率很低。新增节点后,有些客户端比如Lettuce,会因为安全机制无法识别新节点。另外迁移时间也完全无法预估,迁移过程中遇到问题也无法回退。

当前物理机集群的扩容方案是:

  •  按需创建新集群;

  •  使用同步工具将数据从老集群同步到新集群;

  •  确认数据无误后,跟业务沟通,重启服务切换到新集群。

整个过程繁琐而且风险较大,还需要业务重启服务。

有了Proxy层,可以将后端的创建、同步和切换集群对客户端屏蔽掉。新老集群同步完成之后,向Proxy发送命令就可以将连接换到新集群,可以实现对客户端完全无感知的集群扩缩容。

4、数据安全风险

Redis是通过AUTH来实现鉴权操作,客户端直连Redis,密码还是需要在客户端保存。使用代理,客户端只需要通过代理的密码来访问Redis,而不必知道Redis的密码。Proxy还限制了FLUSHDB、CONFIG SET等操作,避免了客户误操作清空数据或修改Redis配置,大大提高了系统的安全性。

同时,Redis并没有提供审计功能。我们已经在代理服务器上添加了高风险操作的日志记录功能,不会影响整体性能的前提下,提供了审计能力。

四、Proxy带来的问题

1、多一跳带来的时延

Proxy在客户端和Redis实例之间,客户端访问Redis数据需要先访问Proxy再访问Redis节点,多了一跳,会导致时延增加。根据测试结果,增加一跳会导致时延增加0.2~0.3ms,但通常对于业务来说这是可接受的。

2、Pod漂移造成IP变化

在K8s上,代理(Proxy)通过部署(deployment)实现,因此同样存在节点重启导致IP变化的问题。我们K8s的LB方案可以感知到Proxy的IP变化,动态的将LVS的流量切到重启后的Proxy上。

3、LVS带来的时延

在下表所示的测试中,不同数据长度的get/set操作引入的LVS时延都小于0.1ms。

Redis集群实例分析

五、K8s带来的好处

1、部署方便

通过运维平台调用K8s API部署集群,大大提高了运维效率。

2、解决端口管理问题

目前小米在物理机上部署Redis实例是通过端口来区分的,并且下线的端口不能复用,也就是说整个公司每个Redis实例都有唯一的端口号。目前65535个端口已经用到了40000多,按现在的业务发展速度,将在两年内耗尽端口资源。而通过K8s部署,每一个Redis实例对应的K8s pod都有独立的IP,不存在端口耗尽问题和复杂的管理问题。

3、降低客户使用门槛

对应用来说,只需要使用单机版的非智能客户端连接VIP,降低了使用门槛,避免了繁琐复杂的参数设置。应用程序无需自行处理Redis Cluster的拓扑,因为VIP和端口是静态固定的。

4、提高客户端性能

使用非智能客户端还可以降低客户端的负载,因为智能客户端需要在客户端对key进行hash以确定将请求发送到哪个Redis节点,在QPS比较高的情况下会消耗客户端机器的CPU资源。当然,为了让客户端应用迁移更加容易,我们还让Proxy支持了智能客户端协议。

5、动态升级和扩缩容

Proxy支持动态添加切换Redis Cluster的功能,这样Redis Cluster的集群升级和扩容切换过程可以做到对业务端完全无感知。例如,业务方使用30个节点的Redis Cluster集群,由于业务量的增加,数据量和QPS都增长的很快,需要将集群规模扩容两倍。如果在原有的物理机上扩容,需要以下过程:

  •  协调资源,部署60个节点的新集群;

  •  手动配置迁移工具,将当前集群的数据迁移到新集群;

  •  验证数据无误后,通知业务方修改Redis Cluster连接池拓扑,重启服务。

虽然Redis Cluster支持在线扩容,但是扩容过程中slots搬移会对线上业务造成影响,同时迁移时间不可控,所以现阶段很少采用这种方式,只有在资源严重不足时才会偶尔使用。

在新的K8s架构下,迁移过程如下:

  •  通过API接口一键创建60个节点的新集群;

  •  同样通过API接口一键创建集群同步工具,将数据迁移到新集群;

  •  验证数据无误后,向Proxy发送命令添加新集群信息并完成切换。

整个过程对业务端完全无感知。

集群升级也很方便:如果业务方能接受一定的延迟毛刺,可以在低峰时通过StatefulSet滚动升级的方式来实现;如果业务对延迟有要求,可以通过创建新集群迁移数据的方式来实现。

6、提高服务稳定性和资源利用率

利用K8s自带的资源隔离功能,使不同类型的应用程序可以混合部署。这不仅可以提高资源利用率,还能确保服务的稳定性。

六、遇到的问题

1、Pod重启导致数据丢失

K8s的pod碰到问题重启时,由于重启速度过快,会在Redis Cluster集群发现并切主前将pod重启。如果pod上的Redis是slave,不会造成什么影响。但如果Redis是master,并且没有AOF,重启后原先内存的数据都被清空,Redis会reload之前存储的RDB文件,但是RDB文件并不是实时的数据。之后slave也会跟着把自己的数据同步成之前的RDB文件中的数据镜像,会造成部分数据丢失。

在部署StatefulSet时,Pod名称遵循一定的命名格式,包含固定的编号,因此StatefulSet是一种有状态服务。我们在初始化Redis Cluster时,将相邻编号的pod设置为主从关系。在重启pod时,通过pod名确定它的slave,在重启pod前向从节点发送cluster failover命令,强制将活着的从节点切主。这样在重启后,该节点会自动以从节点方式加入集群。

LVS映射时延

Proxy的pod是通过LVS实现负载均衡的,LVS对后端IP:Port的映射生效有一定的时延,Proxy节点突然下线会导致部分连接丢失。为了最小化Proxy运维对业务的影响,我们已在Proxy的部署模板中添加了以下选项:

lifecycle:    preStop:      exec:        command:        - sleep        - "171"

对于正常的Proxy pod下线,例如集群缩容、滚动更新Proxy版本以及其它K8s可控的pod下线,在pod下线前会发消息给LVS并等待171秒,这段时间足够LVS将这个pod的流量逐渐切到其他pod上,对业务无感知。

2、K8s StatefulSet无法满足Redis Cluster部署要求

K8s原生的StatefulSet不能完全满足Redis Cluster部署的要求:

在Redis Cluster中,不能将具有主备关系的节点部署在同一台机器上。这个很好理解,如果该机器宕机,会导致这个数据分片不可用。

2)Redis Cluster不允许集群超过一半的主节点失效,因为如果超过一半主节点失效,就无法有足够的节点投票来满足gossip协议的要求。因为Redis Cluster的主备是可能随时切换的,我们无法避免同一个机器上的所有节点都是主节点这种情况,所以在部署时不能允许集群中超过1/4的节点部署在同一台机器上。

为了满足上面的要求,原生StatefulSet可以通过 anti-affinity 功能来保证相同集群在同一台机器上只部署一个节点,但是这样机器利用率很低。

因此我们开发了基于StatefulSet的CRD:RedisStatefulSet,会采用多种策略部署Redis节点。在RedisStatefulSet中添加了一些用于管理Redis的功能。这些我们将会在其他文章中来继续详细探讨。

七、总结

数十个Redis集群已经在K8s上部署并运行了六个月以上,这些集群涉及到集团内部的多个业务。得益于K8s的快速部署和故障迁移能力,这些集群的运维工作量比物理机上的Redis集群低很多,稳定性也得到了充分的验证。

在运维过程中我们也遇到了不少问题,文章中提到的很多功能都是根据实际需求提炼出来的。在接下来的过程中,仍需要逐步解决许多问题,以提升资源利用效率和服务质量。

1、混布 Vs. 独立部署

物理机的Redis实例是独立部署的,单台物理机上部署的都是Redis实例,这样有利于管理,但是资源利用率并不高。Redis实例使用了CPU、内存和网络IO,但存储空间基本都是浪费的。在K8s上部署Redis实例,其所在的机器上可能也会部署其他任意类型的服务,这样虽然可以提高机器的利用率,但是对于Redis这样的可用性和时延要求都很高的服务来说,如果因为机器内存不足而被驱逐,是不能接受的。这就需要运维人员监控所有部署了Redis实例的机器内存,一旦内存不足,就切主和迁移节点,但这样又增加运维的工作量。

如果混合部署中还有其他高网络吞吐量的应用程序,那么也可能会对Redis服务产生负面影响。虽然K8s的anti-affinity功能可以将Redis实例有选择地部署到没有这类应用的机器上,但是在机器资源紧张时,还是无法避免这种情况。

2、Redis Cluster管理

Redis Cluster是一个P2P无中心节点的集群架构,依靠gossip协议传播协同自动化修复集群的状态,节点上下线和网络问题都可能导致Redis Cluster的部分节点状态出现问题,例如会在集群拓扑中出现failed或者handshake状态的节点,甚至脑裂。对这种异常状态,我们可以在Redis CRD上增加更多的功能来逐步解决,进一步提高运维效率。

3、审计与安全

Redis仅仅提供了Auth密码认证保护功能,缺乏权限管理,因此安全性相对较低。通过Proxy,我们可以通过密码区分客户端类型,管理员和普通用户使用不同的密码登录,可执行的操作权限也不同,这样就可以实现权限管理和操作审计等功能。

4、支持多Redis Cluster

单个Redis Cluster由于gossip协议的限制,横向扩展能力有限,集群规模在300个节点时,节点选主这类拓扑变更的效率就明显降低。同时,由于单个Redis实例的容量不宜过高,单个Redis Cluster也很难支持TB以上的数据规模。通过Proxy,我们可以对key做逻辑分片,这样单个Proxy就可以接入多个Redis Cluster,从客户端的视角来看,就相当于接入了一个能够支持更大数据规模的Redis集群。

以上是Redis集群实例分析的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:亿速云。如有侵权,请联系admin@php.cn删除
REDIS:超越SQL- NOSQL的观点REDIS:超越SQL- NOSQL的观点May 08, 2025 am 12:25 AM

Redis超越SQL数据库的原因在于其高性能和灵活性。1)Redis通过内存存储实现极快的读写速度。2)它支持多种数据结构,如列表和集合,适用于复杂数据处理。3)单线程模型简化开发,但高并发时可能成瓶颈。

REDIS:与传统数据库服务器的比较REDIS:与传统数据库服务器的比较May 07, 2025 am 12:09 AM

Redis在高并发和低延迟场景下优于传统数据库,但不适合复杂查询和事务处理。1.Redis使用内存存储,读写速度快,适合高并发和低延迟需求。2.传统数据库基于磁盘,支持复杂查询和事务处理,数据一致性和持久性强。3.Redis适用于作为传统数据库的补充或替代,但需根据具体业务需求选择。

REDIS:功能强大的内存数据存储的简介REDIS:功能强大的内存数据存储的简介May 06, 2025 am 12:08 AM

Redisisahigh-performancein-memorydatastructurestorethatexcelsinspeedandversatility.1)Itsupportsvariousdatastructureslikestrings,lists,andsets.2)Redisisanin-memorydatabasewithpersistenceoptions,ensuringfastperformanceanddatasafety.3)Itoffersatomicoper

Redis主要是数据库吗?Redis主要是数据库吗?May 05, 2025 am 12:07 AM

Redis主要是一个数据库,但它不仅仅是数据库。1.作为数据库,Redis支持持久化,适合高性能需求。2.作为缓存,Redis提升应用响应速度。3.作为消息代理,Redis支持发布-订阅模式,适用于实时通信。

REDIS:数据库,服务器还是其他?REDIS:数据库,服务器还是其他?May 04, 2025 am 12:08 AM

redisisamultifaceTedToolThatServesAsAdatabase,server和more.itfunctionsasanin-memorydatastrustore,supportsvariousDataStructures,and CanbeusedAsacache,MessageBroker,sessionStorage,sessionStorage,sessionstorage,andford forderibedibedlocking。

REDIS:揭示其目的和关键应用程序REDIS:揭示其目的和关键应用程序May 03, 2025 am 12:11 AM

Redisisanopen-Source,内存内部的库雷斯塔氏菌,卡赫和梅斯吉级,excellingInsPeedAndVersatory.itiswidelysusedforcaching,Real-Timeanalytics,Session Management,Session Managements,and sessighterboarderboarderboardobboardotoitsssupportfortfortfortfortfortfortfortfortorvortfortfortfortfortfortforvortfortforvortforvortforvortfortforvortforvortforvortforvortdatastherctuct anddatataCcessandcessanddataaCces

REDIS:键值数据存储的指南REDIS:键值数据存储的指南May 02, 2025 am 12:10 AM

Redis是一个开源的内存数据结构存储,用作数据库、缓存和消息代理,适合需要快速响应和高并发的场景。1.Redis使用内存存储数据,提供微秒级的读写速度。2.它支持多种数据结构,如字符串、列表、集合等。3.Redis通过RDB和AOF机制实现数据持久化。4.使用单线程模型和多路复用技术高效处理请求。5.性能优化策略包括LRU算法和集群模式。

REDIS:缓存,会话管理等REDIS:缓存,会话管理等May 01, 2025 am 12:03 AM

Redis的功能主要包括缓存、会话管理和其他功能:1)缓存功能通过内存存储数据,提高读取速度,适用于电商网站等高频访问场景;2)会话管理功能在分布式系统中共享会话数据,并通过过期时间机制自动清理;3)其他功能如发布-订阅模式、分布式锁和计数器,适用于实时消息推送和多线程系统等场景。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具