赛题解析-初赛赛道三服务网格控制面分治体系构建

29次阅读

共计 2730 个字符,预计需要花费 7 分钟才能阅读完成。

简介: 首届云原生编程挑战赛正在报名中,初赛共有三个赛道,本文主要针对赛道三题目做出剖析,帮助选手更高效的解题。

首届云原生编程挑战赛正在报名中,初赛共有三个赛道,题目如下:

赛道一:实现一个分布式统计和过滤的链路追踪
赛道二:实现规模化容器静态布局和动态迁移
赛道三:服务网格控制面分治体系构建

立即报名 (报名时间即日起至 06/29):https://tianchi.aliyun.com/specials/promotion/cloudnative#problem-definition

本文主要针对赛道三题目做出剖析,帮助选手更高效的解题。

背景知识

“服务网格”是近年来非常火热的技术,其全托管的思维非常适合云原生场景。“服务网格”核心分为控制面与数据面:数据面主要是一个名为 Sidecar 的代理组件,它通过接收控制面发送的路由与控制信息来定向转发或处理数据。这样一些坐落在服务网格里的应用就将整个分布式逻辑交给了底层,自己不用关心了。一旦与底层解耦,灵活性大大增加,更符合云原生的标准。

题目解析

本题的核心考查点还是如何让服务网格的控制面支撑大规模的 Sidecar 实例。为什么会产生这个问题呢?因为在目前服务网格影响最广的实现 Istio 架构中,控制平面 Pilot 负责整个系统的路由转译工作,也就是说所有服务的实例信息都需要通过 Pilot 下发给每一个 Sidecar,当然用户可以通过 SidecarScope 来设置个别 Sidecar 对于系统服务的可见性,但这只会影响到 Sidecar 接受到的数据而已,Pilot 仍然是全量从注册中心同步(例如 Consul,K8s 的 CoreDNS 等),如此一来随着接入应用的增加,Pilot 不能横向扩容,很快便会成为性能瓶颈(内存不够用啊)。

题目提出了分治的解法,而选手们的任务就是优化分治逻辑,使整体负载均衡。为了理解题目,我们首先需要弄清楚什么是分治。所谓的分治就是将负载分成一个个独立的子系统,然后分别处理他们,这样就将问题化小了,比如我们常见的合并排序,就是分治的典型应用。按题目的解释,控制面的分治是按应用维度进行划分的,也就说坐落在服务网格中的应用将被划分到不同的子系统中。

上图中,就被划分成了左右两个子系统。应用之间存在相互依赖即服务依赖,在本题中一个应用只提供一个服务,因此应用所连接的 Pilot 需要加载的数据就是其依服务。由于分治的存在,每个 Pilot 不需要加载所有的服务了,这样当更多的应用接入时,我们就可以进行横向扩容解决容量问题。

上图中为什么每个分治组加载的数据不是完全隔离的呢?这里的原因是应用的依赖是错综复杂的,如果我们把每个应用一个点表示,依赖用一条线表示,那么实际生产中,几乎是不可能形成孤岛的,原因是:每个应用依赖的服务是有重叠的,而且很多。

这样我们便不能随意地划分应用,因为如果我们将依赖相似度很高的应用划分到不同的 Pilot 上,会导致同样的依赖在多个 Pilot 上加载,造成内存消耗增加。反过来,如果将所有应用都挂到同一个 Pilot 上,那么加载的内存总量是最少的,不过连接就极度不均匀了。

所以本题要求选手优化分治逻辑,让分治系统均匀承压。我们先来看看一评分的公式:

公式也不复杂,分为三个评分项:

  1. Pilot 实际加载内存与理想内存的占比,上文提到,不同应用之间依赖的服务可能会有重叠,因此最理想的状态就是所有服务依赖在整个 Pilot 系统中只加载一次,简单来说就是将有相似依赖的应用都划分到同一个 Pilot 中;
  2. Pilot 的内存标准差,这个就比较直白了,就是让 Pilot 加载的服务尽量均衡,不要出现一个 Pilot 加载很多数据,另一个空闲的状态;
  3. Pilot 连接的标准差,这个与上面的类似,就是要求 Pilot 连接的 Sidecar 尽量均衡。

由于实际加载的内存肯定是大于等于理想状态内存,因此最左边的分子式始终于大于 1 的,也就是说,这是一个倍率;而标准差是大于等于 0 的,显然想要两个标准差同时为 0 不现实。因此选手的任务就是分配应用,让

  1. 每个 Pilot 加载的服务数相近;
  2. 每个 Pilot 连接的 Sidecar 相近;
  3. 尽量不要重复加载服务。

什么意思呢,既然我们已经知道了分治就是让应用连接不同的 Pilot,那么每个应用连接上 Pilot 后便会给其一定的压力。

连接的应用越多,压力越大,但由于服务存在重叠的现象,因此并不完全是线性关系。例如上图中另一个应用 E 连 接上来后,如果其依赖的服务是 [服务 A,服务 B,服务 E],那么 Pilot 加载的服务仅会增长 1。这就很好的节省了内存开销。

因此,如何分配应用至每个 Pilot 上,使其满足公式所示条件,就是本题的操作空间与需要解决的问题。

需要特别注意的是,本题评分分为了 两个阶段,一个是静态的,选手可以一次性拿到一阶段所有数据,这样我们就可以整体分析。二阶段数据都是实时分批给的,因此如何让动态的数据也具备良好的表现亦是解题的一个关键点。另外还需要注意的一点,Pilot 加载的数据是只境不减的,因为在实际生产环境中,不可能将一个应用瞬间迁移到另一个 Pilot 上,因此已有的数据需要保留。

解题思路

既然我们知道了得分的要点,那我们就可以围绕这三个点来优化。以下给大家一些分析,以供解题。当然解法很多,下面只是一个列举。

仅量不要重复加载服务数据

当然是让依赖相同的应用出现在同一个 Pilot 上,因此我们可以分析应用依赖的相似度,把相似度高的应用归组一起分配。因为依赖是一个列表,我们可以将其视为一个基因片段或者字符串中的一个字符,问题便成了如何在海量字符串中找到相似的。

Pilot 连接的 Sidecar 相近

当然是每个 Pilot 都一样为好,理想状态是均分。平均说到是简单,但是我们可不能像切蛋糕那样做呀。每个应用的实例有大有小,那么这里的问题就化为了有一串物品,N 个包他们的价值为 a1, a2, a3……,我们如何放置才能使每个包里物品的价值接近平均值,虽然我们有两个要求相近的值(内存与连接),不过如果我们再把物品的重量考虑进来,参数维度就增加了。

第二阶段动态部分

由于第二阶段的数据是不能一次性得到的,因此如何利用已有的数据便成了关键,这里一个方向是类似基于已排序数列进行插入再排序的思想,如何构造这样的一个状态便是关键。

如何拿好成绩

由于得分公式是一个整体,单单提升一个是得不到好成绩的,因此要想拿好结果,建模是需要的,这样我们才能知道哪个才是最大的影响因子,或者甚至能够消除一个变量,那就更好了。

以上内容来自赛道三的明星导师玄胤。

作者信息:
玄胤,阿里云高级技术专家,8 年专注软负载领域,从 0 到 1 写过服务百万实例的软负载产品,Nacos 奠基人,《Service Mesh 实战》作者,Istio 社区成员,3 项国家发明专利。

正文完
 0