写点什么

数万实例数百 TB 数据量,携程 Redis 治理演进之路

  • 2020-05-14
  • 本文字数:5539 字

    阅读完需:约 18 分钟

数万实例数百TB数据量,携程Redis治理演进之路

一、背景

携程自 2013 年开始使用 Redis,旧时期为 Memcached 和 Redis 混用状态。由于 Redis 在处理性能,可储存 key 的多样化上有着显著的优势,2017 年开始,Memcached 全部下线,全公司开始大规模使用 Redis。Redis 实例数量也由刚开始的几十个增长到几万个,数据量达到百 TB 规模。作为 Redis 的运维方,为保证 Redis 的高可用性,DBA 的压力也随 Redis 使用规模的增大而增大,集群的扩容,上下线,实例扩容都面临着不小的挑战。


携程 Redis 并非采用原生的 cluster 或者第三方开源的 proxy,而是使用自主研发的 CRedis Client 组件,部署在所有的应用端。该方案的好处是,Redis 的使用者只需要知道自己的 Redis 名称,就可以访问自己的 Redis,而不需要关心 Redis 的实际部署情况。


这也意味着全部的运维操作都需要在 CRedis 中注册并推送到所有的客户端,为保障 Redis 的持续可用性,DBA 的所有运维操作都是以数据的安全性为第一准则,尽可能做到扩容迁移等操作透明化,保证用户至上。



图 1 CRedis 架构

二、单机多实例时期

Redis 使用早期(2016 年以前),Redis 服务器上线后,由 DBA 在物理服务器上部署多个实例,然后这些实例在 CRedis 中注册,提供给应用访问。资源优化和性能的平衡由 DBA 管理,主要是基于服务器的内存、CPU、网络带宽等指标来手动调节,和 MySQL 的单机多实例类似。DBA 在集群上下线和部署时需要自行在 pool 中寻找合适的机器,当然我们也总结出了一套比较合理的优化算法和方式来管理 Redis 的部署。


在 Redis 的使用爆发增长时期(2016-2018),我们上线了一套 Redis 自动化治理系统 RAT(Redis Administration tools)。Redis 的上下线和扩容从手工时代来到了自动化部署和自动扩容时期,Redis 运维管理难度,随着实例大规模增加而增加。


由于前期对 Redis 的申请和扩容没有做太多限制,物理服务器的使用率一直不太理想,维持在 40%+左右。加上频繁扩容导致的超大实例(20GB+),稍不注意在全量同步时就容易引起实例 OOM,影响业务。为了提高内存效率和降低手动操作风险,DBA 迫切需要一种更先进的部署治理系统来管理 Redis。

三、容器化时期

2018 年开始,随着容器化的流行以及 Kubernetes 成为容器编排的事实标准,我们也开始逐步探索有状态应用容器化。


Redis 的部署由 Kubernetes 根据设定的规则自动化调度部署,DBA 再也不需要操心资源的问题,操作效率提高了几十倍。Redis 的上线和无状态的应用一样接入到了 PaaS 系统中,Redis 的分配也划分了多个可用域(Region),每个 Region 划分多个可用 Pool 满足相关性强的 Redis 集中部署。


Redis 作为一种典型的有状态应用,很多的落地经验可以参考前面的文章《携程Redis容器化实践》。但在当时容器化的规模只有几千个,而目前已经增加了十倍多,还在不断增长,对于如此大规模的实例数,治理策略的调整势在必行。

3.1 二次调度

很多情况下,业务方在申请 Redis 时,并不特别清楚该 Redis 会用到多大,随着业务量的增长或调整,Redis 的使用量可能会远超或远小于原始的分配额度。对于远超额度的,为避免 Key 剔除,以及由此带来的主从切换,影响业务的持续可用性等问题,我们会在 Redis 的使用率(UsedMemory/MaxMemory)达到 90%的时候进行自动扩容处理(修改 Redis 的 MaxMemory),也就是内存超分,但支持内存超分带来的负面效果也很明显:


1)Kubernetes 的 Request 会失去它原先占位作用,因为真实的用量无法感知。


2)因为 Request 无法感知,所以为了防止实际的宿主机内存被打爆,我们必须限制宿主机实例的个数。


3)限制实例个数是根据每个实例分配的平均期望内存来估算,实际分配中会导致资源的利用率并不平衡。


而对于远小于原始分配额度的,缺点也很明显:


1)实例占用了大量的 Request 配额,而实际用的很小。


2)大量的配额无法释放,导致新的实例无法部署到某些很空的宿主机上。


3)某些很空的宿主机无法部署新实例,利用率低下。


由于 Kubernetes 对于这种有状态应用支持的不够完善,而我们的 Redis 集群又有几千台的规模,在处理这些问题时必须分而治之,各个击破。


因为迁移实例需要迁移一组,一组一般是 2 个或更多实例,对于运维来说是个非常重的操作,但迁移实例可以修正 Request 配额,让其适配 UsedMemory。而漂移只需要迁移一个实例,是个相对轻量级的操作。对于 Request 和 UsedMemory 严重不匹配的(一般是 2 倍以上或 1/3 以下的关系),我们通过迁移来修正。而对于 Request 和 UsedMemory 相差不是很大的,我们必须在外围进行二次调度。


二次调度可以认为是宿主机资源 Rebalance 的过程,而在二次调度之前,我们必须要厘清二次调度的目标:


1)对于一个标准的宿主机,为了支持自动扩容,我们认为 Request 100%,内存使用率为 60%-65%为最优状态。


2)每个宿主机上内存使用率尽可能地平均,也就说方差尽可能地小。


3)Node 可用内存小于 35%,禁止调度,大于 45%,开放调度。


对于第三点,在外围有专门的 Job 来检测 Node 的可用内存,来 cordon/uncordon 符合条件的 Node。


对于上面第一第二点的两个目标,我们设计了支持 2 种模式的局部最优平衡算法:


1)预留制


由于 Redis 实例在使用过程中内存使用量不断增长,且增长趋势无序无规律,使得某些宿主机上的内存可用率很低(如图 2 所示宿主机可用率约为 24%-26%)。因此,可以通过将内存不足的宿主机上的实例漂移到闲置或内存充足的宿主机上来缓解源宿主机的内存压力。



图 2 预留制算法下宿主机的二次调度情况


首先,通过选择需要被二次调度的源宿主机以及指定目标内存可用率(如图 2 为 50%),预留制算法可将源宿主机上需要被调度的实例漂移到闲置宿主机上,或是调用已经实现的 bestnode 接口,自动为源宿主机上需要被调度的实例选择符合调度条件的目标宿主机,且二次调度后目标宿主机以及闲置宿主机的内存可用率不低于指定的目标内存可用率。


bestnode 是已经实现的一种二次调度的策略,可为实例选择相同 label、相同 zone 且可用内存、可分配内存及宿主机可容纳实例个数充足的最优目标宿主机,从而保证实例可以成功地漂移到目标宿主机上。


2)完全平衡制


由于集群中宿主机内存使用率的差距非常大(如图 3 所示),为了使每个宿主机上内存使用率尽可能平均,即方差尽可能小,可以通过将内存紧张的宿主机上的实例漂移到内存充足的宿主机上,从而缩小宿主机内存使用率的差距。



图 3 完全平衡制下宿主机的二次调度情况


如图 3 所示,通过手动选择需要平衡的宿主机实例,完全平衡制算法将计算宿主机群内存使用率的最小方差(图 3 中宿主机群内存使用率达到最小方差约为 61%),并在宿主机群间做实例的调度。


在实例漂移前 Redis 集群中还存在如图 4 所示的情况。由于某些宿主机上实例的 UsedMemory 很小,导致宿主机的内存可用率很高却由于实例个数已满无法再将实例漂移到宿主机上,使得宿主机的内存利用率不高。相反,也存在实例的 UsedMemory 很大导致的宿主机内存可用率低但还可将实例漂移到宿主机上的情况。


对于这种情况,我们首先将内存可用率高的宿主机上 UsedMemory 最小的几个实例漂移到内存使用率低的宿主机上,从而为宿主机腾出实例个数配额,接着将内存可用率低的宿主机上 UsedMemory 较大的几个实例漂移过来,从而平均宿主机的内存使用率。



图 4 内存可用率高却无可分配 pod 的宿主机与内存可用率低有可分配 pod 的宿主机


用户可配置二次调度的参数,如指定可漂移实例的 Max/Min UsedMemory,Rebalance 次数,最后生成一个 config 文件。


预留制算法与完全平衡制算法在选择源宿主机上需要被调度的实例时都使用的是 First Fit Decreasing(FFD)算法,即首先计算达到目标内存可用率需从源宿主机上释放内存(ReleaseMemory)的大小,接着遍历由大到小排序后源宿主机上实例的 RequestMemory 以及 UsedMemory,将符合条件(RequestMemory<ReleaseMemory 且 UsedMemory<ReleaseMemory)的实例列入候选调度名单。通过对历史迁移记录使用机器学习等方法,根据以往的迁移开销可以生成实例调度的集群画像(黑/白名单)。


在先对宿主机进行预处理后(如上图 4),根据二次调度 config 文件,综合考虑黑白名单、实例优先级,并且排除不能被调度的实例类型(如 XPipe 以及多 slave 实例)后,即可确定最终需要被二次调度的实例名单。最后即可生成如图 5 所示的二次调度方案。


Redis 主要瓶颈在内存,因此我们暂时也只考虑内存。但这种二次调度的模式同样可以应用于其他有状态应用的场景,如 Mysql/Mongodb/Es 等,只是考虑的维度更全面(Cpu/内存/磁盘)。



图 5 实例二次调度方案

3.2 自动化漂移

有了上面的二次调度,我们可以手工或者自动生成二次调度的计划或任务,在指定时间触发,此外我们上线了容器自动化漂移系统,漂移操作支持下面几种类型:


1)指定实例漂移到指定宿主机。


2)宿主机完全 down 掉,无法恢复,一键漂移。


3)宿主机有故障需要维修,一键漂移。


4)二次调度计划自动或手动漂移。


根据之前的描述,我们所有的运维操作需要在 CRedis 中注册,我们也针对 Redis 实例在 CRedis 中的不同角色,在逻辑和物理层面进行了无缝衔接,在漂移过程中自动修改 CRedis 的访问策略,数据同步,Xpipe DR 系统自动化注册(Xpipe 是携程 Redis 跨 IDC 容灾的方案),自动添加删除哨兵等。



图 6 容器漂移拉出流程

3.3 Cilium

由于我们漂移过程中,整个 IP 是不变的,IP 不变的逻辑由 OVS 来保证,这样好处是对客户端和中间件透明。但随着携程单个 IDC 内容器部署密度的越来越大,大二层网络的交换机表项无法承受这么多 IP 在整个 IDC 内可漂移。


Cilium 是下一代云原生的网络解决方案,之前有其他同事的文章有所描述,这里不再展开。我们将 Redis 容器跑在了 Cilium 上,漂移过程中 Redis 换宿主机后 IP 会变,这样会涉及多个系统的数据变更,如哨兵记录了老 IP,当前实例却变成新 IP,这时候正好分配一个老的 IP 给了新的实例,导致复制关系错乱,稍有不慎便会导致生产事故。也对漂移流程的可靠性提出了更高的要求,我们细化每一步漂移流程,设计合适的状态机,保证每一步的可重试和幂等性。

3.4 傲腾落地

大规模的 Redis 用量以及增长速度迫切需要我们调研性价比更高的解决方案,这时候 Intel 傲腾技术进入了我们的视线。目前为止,傲腾宿主机大约为整个 Redis 宿主机的 10%左右。

傲腾 SSD

率先被我们引入的是傲腾 SSD,通过 2 块 SSD 组合,可以提供操作系统约 700 多 G 的内存。



图 7 傲腾 SSD 和纯内存宿主机对比


从实际效果上看(图 7)傲腾 SSD 的平均延迟相比内存还是相对明显,从 0.3ms 上升到了 0.9ms,与测试的结果吻合,但某些业务能接受这种延迟的上升,并且能节约 60%成本,因此我们首先在携程内部小范围的部署了傲腾 SSD。

傲腾 AEP

尽管傲腾 SSD 可以符合我们的部分要求,但缺点还是比较多。


1)驱动支持不完善,基本所有的厂商需要对应的 RAID 卡驱动,并且每家还不太一样,现实状况是需要编译多个内核版本来适配不同厂商的驱动。


2)装机繁琐,需要注册码,还要开关机多次,并且还有失败的概率,是否能最终进入系统有点凭运气。


3)700G+作为 Redis 宿主机来说相对太大了,因为我们需要考虑 Redis 宿主机万一挂了恢复的时间。



图 8 傲腾 AEP 和纯内存宿主机对比


从线上结果来看,傲腾 AEP 和纯内存的耗时比较接近,业务的监控状态如上图。傲腾与普通物理内存实际运行区别已经非常小,可以满足绝大部分业务场景。并且相对于傲腾 SSD,傲腾 AEP 还有以下的优点:


1)装机方便,不需要注册码,也无需额外的驱动程序


2)可以选择的规格比较多,可以方便组合 CPU/内存/傲腾 AEP 的配比


我们经过数量和大小的权衡,选择的规格是 32C CPU+4 个 128G 的傲腾 AEP,傲腾 AEP 与内存配比是 1:4。单 GB 成本约为纯内存的 50%。

四、混合云时期

2019 年开始,随着集团业务的全球化,业务海外访问量的增加,Redis 出海的需求也不断上升,由于 Redis 的快速响应要求,我们也需要在公有云上部署 Redis 群集,以提供给当地的应用访问,减少延迟。


然而公有云上无法提供裸金属服务器,实际提供的宿主机都是虚拟机,出于容灾方面的考虑,我们将 Redis 的宿主机严格按 zone 打散,让 master/slave 部署在不同的 zone,这样即使一个 zone 全部 down 掉也完全不影响 Redis 的业务。此外对申请部署透明,对于用户来说,只需要选择想要部署的 Region 即可将 Redis 部署到海外,与私有云完全一致的体验,至此携程的 Redis 走到了混合云时期。

Redis On SSD

公有云上的 Redis 价格非常昂贵,约为私有云的 10 倍左右,并且私有云还有类似傲腾这种方案来进一步降低成本,但 Redis 需要出海的规模巨大,而携程大部分 Redis 需要通过内部的 Xpipe 系统同步到海外,因此迫切需要我们寻找一种廉价的方案来代替 Redis 跑在公有云上。


我们调研一段时间,最终选择开源的kvrocks作为二次开发的方案,自己开发实现支持 Redis 的 SYNC 和 PSYNC 协议,无缝对接公司的 Xpipe,来作为出海 Redis 的替代方案,实现方案和详细的数据后续会有专门文章介绍。


这里简单说下结论:下图为线上生产环境同一 Group 的 2 个 Redis/2 个 kvrocks 的访问平均延迟,表现较好的那两条线是 kvrocks 实例,从线上结果来看,与 Redis 表现没有什么差距。而这种替代方案可以节约 60%-80%的成本。



图 9 kvrocks/Redis 平均响应时间对比

五、总结

Redis 作为有状态应用,容器化和治理都需要很大的精力投入,而携程 Redis 治理既不盲从社区,为了支持内存超分,也难以照搬公有云厂商的相应的 Redis PaaS 服务,从实际业务需求出发,走出了一条既可行又现实的路。


作者介绍


向晨,携程资深数据库工程师;布莱德,携程技术专家;皓月,携程技术培训生。


本文转载自公众号携程技术(ID:ctriptech)。


原文链接


https://mp.weixin.qq.com/s/L7EQzthCoWuJw8TzY-KAMw


2020-05-14 10:044181

评论

发布
暂无评论
发现更多内容

谈谈项目中主动full gc的一些问题

AI乔治

Java 编程 架构 JVM GC

运筹帷幄之后,决胜千里之外!GitHub上标星75k+的《Java面试突击手册》助你拿到满意的offer。

Java架构之路

Java 程序员 架构 面试 编程语言

第七周课后总结

饭桶

鬼知道我经历了什么!全靠这份999页Java面试宝典,我刚拿到美团offer!

Java架构追梦

Java 程序员 架构 面试 美团

中国程序员超5000万?一线城市IT岗位已开始饱和过剩?

Java架构师迁哥

日常工作参数分析

hasWhere

饱受毕设摧残计算机系师兄,怒而分享纯净版SSM框架(附源码)

小Q

Java 学习 面试 开发 SSM框架

偷师Kubernetes源码,学会怎么用Go实现调度队列

网管

Kubernetes 并发编程 并发控制 Go 语言

Github标星35K+超火的Spring Boot实战项目,附超全教程文档

Java架构之路

Java 程序员 架构 面试 编程语言

如何快速构建Spring Boot基础项目?

田维常

spring Boot Starter

架构师训练营 1 期 - 第六周 - 技术选型2

三板斧

极客大学架构师训练营

华为云专家私房课:视频传输技术选型的三大法宝

华为云开发者联盟

音视频 视频 传输

第七周课后练习

饭桶

第六周学习技术选型2总结

三板斧

快速掌握并发编程---关于乐观锁、悲观锁、可重入锁

田维常

并发编程

快速掌握并发编程---ArrayBlockingQueue 底层原理和实战 java

田维常

并发编程 LinkedBlockingQueue

【原创】SpringBoot 这几种配置文件方式,你都用过吗?

田维常

springboot

JUC 之ThreadPoolExecutor实现原理分析

AI乔治

Java 架构 jdk 线程

登陆!Let's Start Coding

蚂蚁集团移动开发平台 mPaaS

移动开发 mPaaS

JUC之 FutureTask 源码与工作原理分析

AI乔治

Java 编程 架构 jdk 线程

4年Java经验,去面试居然10分钟就结束了,现在面试为什么这么难?

Java架构之路

Java 程序员 架构 面试 编程语言

熟悉又陌生的 k8s 字段:SecurityContext

郭旭东

Kubernetes Kubernetes源码

量化交易系统开发、自动对冲策略搭建

薇電13242772558

区块链

全国区块链信息服务备案超千个

CECBC

区块链 金融

美国大选观战感受:用区块链投票吧,少操点心

CECBC

区块链 投票机制

架构训练营-week7-学习总结-性能测试,操作系统,锁

于成龙

架构训练营

【API进阶之路】API带来的微创新,打动投资人鼓励我创业

华为云开发者联盟

学习 视频 API

电子劳动合同来了 足不出户也能签约

CECBC

社会保险 电子合同

如何降低young gc时间

AI乔治

Java 架构 GC GC算法

华为云FusionInsight MRS:助力企业构建“一企一湖,一城一湖”

华为云开发者联盟

数据库 云原生 数据

轻松使用TensorFlow进行数据增强

计算机与AI

tensorflow 学习 数据增强

数万实例数百TB数据量,携程Redis治理演进之路_开源_向晨_InfoQ精选文章