新闻中心
您所在位置: 球盟会 > 新闻中心 > 行业新闻
球盟会APP从滴滴的毛病我们能学到甚么?
时间:2023-12-13 13:57点击量:


  11 月 27 日晚滴滴发作了大范畴、长工夫的毛病。官方动静说是“底层体系软件发作毛病”,而据网上的小道动静,一个范围十分大的 K8s 集群停止在线热晋级,由于某些缘故原由,一切 Pod(容器)被 kill,而 K8s 的元数据曾经被新版本 K8s 修正,没法回滚,因而规复工夫拉的很长。

  从滴滴近期分享的手艺文章来看,这个说法并非空穴来风。滴滴团队近两个月正在把公司内部的 K8s 从 1.12 晋级到 1.20,1.12 是 2018 年 9 月公布的,而 1.20 是 2020 年 12 月,对高速开展的 K8s 项目来讲,两个版本存在相称大的差异。K8s 官方保举的办法是沿着一个个版本升上去。但滴滴团队以为屡次晋级风险更高,采纳了一把梭哈的战略,逾越 8 个版本一把升。并且为了不中止营业,在不重启容器的状况下原地晋级,滴滴团队还修正了 kubelet 的代码。

球盟会APP从滴滴的毛病我们能学到甚么?(图1)

  这个晋级流程假如统统一般实际上是 work 的。我揣测仍是赶上了未思索到的不测身分,好比运维误操纵,形成了此次大范围的毛病。从我的经历来讲,遵照以下设想准绳,能够极大的低落风险几率、减小毛病范畴:

球盟会APP从滴滴的毛病我们能学到甚么?(图2)

  先说我的⼀个阅历。晚年阿⾥云倡议过⼀个 5K 项⽬,⽤ 5000 台物理机构成⼀个 ODPS(即厥后的 MaxCompute)大集群来⽀持阿⾥内部的⼤数据营业,5K 项⽬在 13 年上半年进⼊攻坚阶段,我作为手艺⻣⼲被抽调到这个项⽬⾥。ODPS 有⼀个组件叫⼥娲,相似 Hadoop 的 Name Node,供给名字剖析、散布式锁等效劳。当 5K 集群进⾏机房级掉电测试时,⼏千台效劳器(此中有⼏万个效劳)在重启后会向 3 台⼥娲效劳器倡议长途调⽤去剖析相互的地点,就像 DDoS 进犯⼀样,瞬时流量会连续打满千兆⽹卡,形成全部 5K 集群⼀波⼜⼀波的雪崩。

  这段阅历报告我,当一个集群范围很大时,很简单在乎想不到的处所发作相似的成绩。因而,在设想体系时,我偏向于把集群的范围掌握在⼀个公道的范畴。比方把⼀个资本池的⼤⼩掌握在⼏百台机械的范围,当需求更多资本时,不是去扩大单个资本池的⼤⼩,⽽是去新建资本池,扩大资本池的数目。换句话说,为理解决营业增加成绩,不要 scale up 单个集群,⽽是 scale out 出更多的集群!

  另外一个要思索的成绩是爆炸半径。再举个例子,PolarDB 的底层存储组件叫 PolarStore,从内部来看,PolarStore 是⼀个可⽆限扩容的存储效劳,但内部完成上,我将其设想成由一个个隔分开的⼩集群构成,每一个集群⼏⼗到上百台效劳器。这个设想 2017 年投入商用,固然以后 PolarDB 的范围逐年激增,但 PolarStore 效劳历来没呈现过大范畴的毛病。K8s 集群也是⼀样。出格⼤范围的 K8s 集群,比方上万台的,实在都存在爆炸半径过⼤的的不变性⻛险。与其不竭优化与提⾼ K8s 的范围极限,不如梳理营业,把这些巨型 K8s 集群拆为多个⼤⼩适中的集群。

  实践体系设想和开辟中,我们能够会由于多种缘故原由偏向于挑选大集群。我听过的⼀个来由是为了不跨 K8s 集群⽹络不连通成绩,就⼲脆把一切 Pod 都塞到了⼀个 K8s 集群⾥。但⽹络连通性的成绩仍是该当由⽹络⽅案来解,好比这个成绩能够经由过程负载平衡器(LB)表露 Pod 地点,或给 Pod 分外分派⼀个 Underlay ⽹络地点(比方物理收集大概 VPC 收集的地点)来处理,而不应当将其和架构设想相耦合。KubeBlocks 的⽤户常常来征询我们,⼀套 KubeBlocks 能不克不及办理⼏千大概上万个数据库实例。我们给出的谜底是能,但我们保举的更优理论是采⽤多个 K8s 集群⽔平扩大的⽅法,每一个 K8s 集群都是⼀个资本池,各⾃布置⼀套⾃治的 KubeBlocks,然后再把这些资本池注册到我们的中⼼办理集群⾥来,经由过程这类架构扩大到⼏⼗万个数据库实例数都不存在成绩。这素质上是⼀种将多个 K8s 集群构成联邦的⽅案。

球盟会APP从滴滴的毛病我们能学到甚么?(图3)

  架构师们不断都很胆小如鼠的制止单点毛病。效劳要停止冗余布置,数据库要有主备。在机房内,收集要有双上联交流机,效劳器除市电供电,还要筹办柴油发机电应急。在付出宝机房被挖断光纤后,各人又开端正视机房级此外高可用容灾,营业要做跨机房以至是跨地区的布置。假如一个机房断网、断电,那流量要能快速的从毛病机房切走,营业处置和底层的存储都要切换到其他机房。好比,八年前我在设想 RDS 专有云双机房布置计划的时分,要思索单机房劫难发作时,数据库的主备复制干系、负载平衡另有 IP 网段怎样从主机房漂移到备机房,和毛病规复时流量怎样再切回主机房。

  但 K8s 常常被架构师们视作是一个业已具有多机房容灾、高可用才能的散布式体系。从而无视了把高可用营业布置在单 K8s 集群上的固有风险。K8s 是一个办理容器编排的体系软件,好像一切的软件体系,碰到非预期的变乱,比方本次滴滴毛病中跨多个版本的原地晋级,也是有概率完全挂掉的。这个时分,营业和存储体系在单 K8s 里纵使有再多的副本,也要歇菜。

  因而我们倡议架构师们在设想布置计划时,要把 K8s 视作存在单点风险的单位,一个 K8s 是一个布置单位,把已往多单位多活的手艺计划移植到多 K8s 多活的场景下来球盟会APP。不只是无形态的效劳,效劳所依靠的数据库的副本也要跨 K8s 布置。除数据面,在掌握面办理营业负载与数据库的 K8s operator 办理软件也需求做到多 K8s 多活。这相似于,在 RDS 体系里,除数据库要做高可用,RDS 的管控体系必须要完成双活,不然毛病发作时,主动化体系都生效了,一切操纵都得野生施行,天然会增长毛病的处置时长。这个才能我们会在 KubeBlocks 里撑持上。

  分外的益处是,假如你的营业布置在多个 K8s 集群中,那末 K8s 的晋级战略能够愈加灵敏,能够经由过程逐一晋级 K8s 集群,如许可以进一步低落晋级过程当中能够呈现的风险。

球盟会APP从滴滴的毛病我们能学到甚么?(图4)

  回到 K8s 的晋级,K8s 官方保举的方法是如许的,一一地将每一个节点上的 Pod 摈除到其他节点上去,从集群中移除节点,晋级,然后再将它从头参加到集群,这是一种转动晋级机制(Rolling)。而 AWS EKS 还撑持一种蓝绿布置机制(Blue-Green),创立一个新的节点组,利用新的 K8s 版本,然后,将 Pod 从旧的节点组迁徙到新的节点组,完成蓝绿布置,一旦一切的 Pod 都曾经胜利迁徙到新的节点组,再能够删除旧的节点组。两种办法都需求迁徙和重启 Pod。此次毛病里,滴滴接纳了十分规的 K8s 晋级手腕,此中一个主要的念头是制止 Pod 重启影响营业。这实在代表了一类 old-school 的效劳器办理理念。

  在 DevOps 中,Pets vs Cattle 是一个经常使用的比方,用来形貌两种差别的效劳器办理战略。Pets(宠物,比方猫)代表的是那些我们经心顾问和保护的效劳器。当它们呈现成绩时,我们会尽统统能够去修复,而不是间接交换它们。每个 Pet 都是独一的,有本人的名字,我们晓得它们的机能,以至它们的性情(比方,某个效劳器能够会常常呈现某种特定的成绩)。已往工程师和运维们十分的讨厌效劳重视启,以致于云厂商 ECS 团队的一个斗争目的就是把假造机做到如小型机般的牢靠,为此不竭的改良假造机热迁徙等手艺。

  Cattle(牲畜,比方牛)代表的是那些我们能够随便新增或删除的效劳器。我们不会对它们停止个体办理,而是将它们视为一个团体来办理。假如此中的任何一个呈现成绩大概变革,我们凡是会挑选间接交换,而不是修复。Cattle 的例子包罗在云情况中运转的虚机,大概是在 Kubernetes 集群中运转的 Pod。以至能够把 K8s 集群自己也视作 Cattle,假如 K8s 呈现成绩,大概是 K8s 集群要做版本晋级,间接把这个 K8s 换掉,把老的 K8s 里的 Pod 间接迁徙到新的 K8s 里。

  把 Pod 看作 Pets,就会想尽统统法子来制止 Pod 重启。而把 Pod 看作 Cattle,就会换一个思想,把 Pod 的重启和迁徙作为一个需求来设想体系。我倡议工程师们接纳后一种思想。不关键怕 Pod 重启和迁徙,而是把处置 Pod 重启、迁徙和碰到成绩回滚的代码视为体系的一般运转例程的一部门。在庞大体系设想中,等待并计划毛病的发作,而不是试图阻遏它们发作,经由过程按期晋级体系,考证处置重启、迁徙、回滚的代码,确保体系在面临重启和迁徙这类常态时可以一般运作。把重启和迁徙视为常态,而不长短常,这类思想方法可以协助我们设想出更牢靠、更强健的体系。

  因而,在 KubeBlocks 施行数据库大版本晋级时,我们其实不保举原地晋级,由于原地晋级总有一天会踩到坑的。我们会新建一个高版本的数据库实例,经由过程全量和增量数据迁徙将数据导入到新实例中,经由过程数据库代办署理层连结来自使用真个收集毗连,低落在实例间切换对营业的影响。在晋级完成后,我们还会连结老版本和新版本的数据库同时运转一段工夫而且保持双向同步,在营业确认晋级不形成非预期影响后再清算老版本的实例。

球盟会APP从滴滴的毛病我们能学到甚么?(图5)

  最初想说的一个经历是数据面的可用性要和掌握面解耦。我先举两个例子,这两个都是存储体系,可是基于差别理念设想的:

  第一个别系是 PolarDB 的存储体系 PolarStore。PolarStore 采纳了掌握面与数据面别离的理念(详情参考我在 VLDB 2018 年揭晓的PolarFS论文)。数据面的读写操纵都仅依靠查询缓存在当地的全量元数据。掌握面仅仅在施行办理操纵,比方创立卷球盟会APP、卷的扩缩容、节点宕机倡议数据迁徙、集群扩缩容的时分需求修正元数据才会被强依靠。掌握面临元数据的修正会经由过程元数据告诉机制异步更新到数据面的缓存里。这个设想的长处是高度的牢靠性,即便全部掌握面不成用,在数据面读写文件都能够一般完成,这对数据库营业而言很主要。

  而在另外一个别系中,掌握面与数据面是耦合的。这个别系有三个很主要的 Master 节点,Master 节点除负担掌握面的使命外,还负担了一部门数据面的职责。举个例子,在这个别系中,数据是以 Append only 的情势不竭追加到一个日记流中,而日记流会按 64MB 朋分为 chunk,每写满一批 chunk,数据面的节点就要找 Master 节点分派下一批新 chunk 的调理战略。这个设想有一个缺限,就是 Master 节点一旦宕机,全部存储集群很快就没法写入新数据。为了克制这个缺点,Master 从三副本改成了五副本,同时 Master 还接纳了 Sharding 的计划来进步吞吐才能。

  我还想到第三个例子,前阵子阿里云的史诗级毛病,工具存储的枢纽途径里依靠了 RAM 的鉴权逻辑,因而 RAM 呈现毛病时,也形成了工具存储的不成用。这几个存储例子报告我们,数据面的可用性假如和掌握面解耦,那末掌握面挂掉对数据面的影响很细微。不然,要末要不竭去进步掌握面的可用性,要末就要承受毛病的级联发作。

  KubeBlocks 也采纳了掌握面与数据面别离的设想,掌握面包罗 KubeBlocks operator、K8s API Server、Scheduler、Controller Manager 和 etcd 存储球盟会APP,它卖力全部集群的办理,包罗调理、资本分派、工具性命周期办理等功用。而数据面则是在 Pods 中运转的容器,包罗各类数据库的 SQL 处置与数据存储组件。KubeBlocks 能够包管即便掌握面的节点局部宕机,数据面仍旧可用。而分离数据库内核、代办署理与负载平衡的协同,还能够进一步做到掌握面失利,数据面仍旧能够施行高可用切换。

  掌握范围、制止单点、拥抱重启、数据面的可用性和掌握面解耦。这些点是我已往十多年在设想 RDS 和 PolarDB 如许的大范围云效劳时所正视的一些设想准绳,这些准绳能够协助防备体系呈现大范围毛病。在开辟 KubeBlocks 的过程当中,我发明这些准绳在 K8s 的场景下仍旧是有用的,期望能够协助架构师和工程师们设想更不变的体系。