基于服务画像的垂直伸缩系统建设思考

背景

近期公司开始做成本治理, 降本增效. 通过观察以往各业务线的资源规格配置, 不难发现有大量服务资源超配情况. 即服务实际资源开销远小于其声明的资源开销. 而这部分的超配直接导致集群的资源使用率较低. 通常形如下图

资源使用率.png

在过去的集群资源使用实践过程中,我们也遇到了如下问题:

  • 服务本身资源使用率较低, 但申请资源规格时使用了较高的规格

  • 服务仅在特定时段(流量波峰)有较高资源使用, 其余时段资源使用率较低,没有申请合理的资源规格

  • 开发者不知道如何评估及配置自身服务规格

在这篇文章的过程中,我们核心介绍的是:

  • 如何建设合理的服务资源画像, 对外提供画像数据查询能力

  • 依据资源画像数据在调度系统提供一定资源超售能力, 从而提高集群资源使用率

目标

如背景中提到的资源分配值与资源使用值之间的差值是带来整体资源利用率较低的直接原因, 故有效缩短这部分差值能带来直接的资源利用率提升.

故我们抽象了以下公式:

gap = abs(resource request - resource usage)

基于上述背景,我们细化出以下目标:

  1. 降低服务实际使用资源和服务声明使用资源的差异, 即尽可能减少上述公式中提到的 gap

  2. 根据在 PaaS 平台配置的服务类型提供梯度的资源超卖机制

  3. 对于指标中周期性抓取的资源特征数据进行持久化, 目前只考虑 cpu, memory

  4. 对于开发者在 PaaS 平台配置规格时给出推荐值

本次方案将降低用户配置服务资源规格成本,在集群维度避免过度超卖导致的节点内存掉底导致的宕机现象或频繁换页带来的性能影响.

本次讨论不关注 k8s 节点资源超卖, 仅关注服务粒度资源超卖

系统架构

系统架构

名词解释:

  • console: 服务平台, 存储服务元信息

  • plume: 调度系统, 包装 k8s api, 提供 k8s workload 操作能力

  • portrait data service: 服务画像服务, 提供服务维度画像数据

VPA 结构上主要分为三个组件:

  1. Recommender:

    • 定期(Interval 默认为1天)从 Console 获取全量部署到 kubernetes 上的服务列表

    • 向 Prometheus 查询服务过去 N 天的资源使用情况 (默认 N=1 以覆盖每日业务峰值)

      • 对于 CPU, 获取 TP50/90/95/99 的 cpu 利用率作为业务容器平均 cpu 利用率 (即从小到大排序有第 50/90/95/99 位的容器 cpu 使用率)

      • 对于 Memory, 获取特定时间窗口的峰值

    • 根据推荐算法⑴计算服务资源的推荐值, 并根据 Recommender 策略进行服务元信息配置更新

      • 策略1 – Auto: 将自动将推荐值刷入 console 服务元数据数据库中 (默认 Auto, 使用项目维度黑名单机制开启 Off)

      • 策略2 – Off: 将推荐值记录到 db 中用于 console 界面展示规格推荐值

  2. Recommender-Updater:

  • Recommender 的子模块, 用于周期性更新 k8s 资源, 存储特征数据

  • 根据配置策略更新 k8s deployment/pod

    • 策略1 – Auto: 将自动更新 k8s pod spec 中的资源 requests/limit 值, 且服务将发生重调度 (业务有感知)

    • 策略2 – Off: 不进行自动更新, 靠服务重新在 console 部署触发资源更新 (默认 Off, 使用项目维度白名单机制开启 Auto)

  • 往 db 中存储资源特征数据

  1. Portrait Data 画像服务:
  • 接收 Recommender 请求,对采集到的服务画像数据进行持久化.

  • 提高服务维度画像数据查询能力, 对外提供 http 查询接口.

  1. Admission Controller: (非必须组件)
  • 拦截 pod 提交请求, 自动获取 Recommender 中的资源推荐值, 并替换 pod spec 中的资源 requests/limit 值

  • 该组件用于提供以下能力

    • 解决确保弹性伸缩时扩容出的 Pod 为新资源配比值
    • 提供 Updater kill pod 时可以自动生成带有新资源配比值的 Pod 能力
    • 综合 b. 中两点考虑,目前我们暂无复杂用法, 先降低系统复杂度. 不做该组件, 转为和 k8s api 打交道

数据库表结构设计

用户画像架构参考

数据库选用 Hbase, 像画像中的资源数据类似指标打点, 会有 TP50/90/95/99 需要较灵活的分位分割, 对表的扩展性需要高.是 MySQL 不易于处理的场景,而列存储天然适合.

同时画像数据通常有较强的实时性要求, 即可能一段时间周期(比如6个月)前的画像数据的参考性不高. 同时为防止表数据膨胀, 也需要定期对画像表进行清理. 基于此可以利用 Hbase TTL 特性进行定期清理.

hbase ttl

资源画像表

资源画像表记录服务粒度的资源的静态信息,通过 resource_type 区分资源类型,目前有 cpu, memory, disk io。

类似时序数据库用法,在表中存储类型,特征值, 采集时间字段

表名:resources_portrait

列名 类型 备注信息
data varchar(255) 采集时间
id bigint 主键
resource_suffix varchar(255) 特征后缀, 如 cpu_busy_TP90, cpu_busy_TP99
resource_type int(11) 资源类型:cpu、memory等
value varchar(255) 资源值

设计细节

以下设计均建立在不考虑 Admission Controller 的场景下.

一、一次资源画像更新流程是怎样的?

Recommender 每周一早上 10 点调用服务平台 api 获取全量服务列表, 发起资源画像更新流程

向 Prometheus 查询 avg(rate(container_cpu_usage_seconds_total{container="${container}", pod=~"$service.+"}

Recommender-Updater 将采集到的特征数据更新到 db 中

Recommender-Updater 根据自身策略更新 k8s deployment spec

二、调度流程有啥修改?

调用流程与原来一致

Plume 调度系统接收到调度请求, 根据服务元信息中的资源规格配置生成 k8s pod spec 中相应资源字段

调用 k8s api 进行 apply workload

三、推荐算法是什么?

根据 PaaS 平台的服务类型 给予以下梯度 CPU 超售比

在线无状态服务: 1.5 (核心服务不超售)

离线服务 : 3.0

对于 CPU 按区间(单位为核数)拆分为 (0, 0.5], (0.5, 1], (1, 2], (2,4], (4,6], (6, 8], (8, 10], (10, 12], (12, 14], (14, 16], (16, *]. 按以下公式计算 CPU request 值

for interval in (0, 0.5], (0.5, 1], (1, 2], (2,4], (4,6], (6, 8], (8, 10], (10, 12], (12, 14], (14, 16]:

    if 应用_cpu_usage in interval:

        应用_cpu_request = ceil(interval) * 1/超售比 # 当前区间向上取整.

        break



if 应用_cpu_usage > 16:

    应用_cpu_request = 应用_cpu_usage * 1/超售比

对于 Memory 按区间(单位为 GB)拆分为 (0, 0.5], (0.5, 1], (1, 2], (2,4], (4,6], (6, 8], (8, 10], (10, 12], (12, 14], (14, 16], (16, *]. 按以下公式计算 Memory request 值

for interval in (0, 0.5], (0.5, 1], (1, 2], (2,4], (4,6], (6, 8], (8, 10], (10, 12], (12, 14], (14, 16]:

    if 应用_mem_usage in interval:

        应用_mem_request = ceil(interval) * 1/超售比 # 当前区间向上取整.

        break



if 应用_mem_usage > 16:

    应用_mem_request = 应用_mem_usage * 1/超售比 # 内存当前不超售, 未来可能超售

四、会自动修改资源的 limit 吗?

本次模型中 Recommender Auto 模式下只会修改 Request, Request 对于用户无感知.

对于 limit 在 console 上会与服务规格概念相关, 故只会给出推荐值, 不会帮用户修改.

五、Recommender-Updater 自动修改 k8s 模板后触发重调度业务可接受吗?

默认使用项目白名单机制,只有能接受这部分场景的应用开启,其余默认关闭 Updater.

对于二期链路上再尝试优化不进行重调度的 k8s 资源垂直扩缩.

六、Admission Controller 的作用是啥,可以去掉吗?

期望提供通用 patch pod spec 能力, 同时对于后续 Recommender-Updater 更新 pod spec 时可以提供通过逐步 kill pods 机制实现无感知上线

在目前的链路上可以去掉,也不计划在这一期支持

七、对于过度超卖的情况下如何矫正?

必然会存在部分项目出现计算出的 cpu requests/mem requests 不合理导致过度超卖的情况, 对于这类服务使用两种方式解决

在 Recommender 中白名单固定超卖比.

在 Recommender 中使用白名单关闭接入.

八、是否会对不同服务给予特定的超售比?

会计划, 但需要根据具体采集到的画像数据进行统一分析才能得到有依据的结论或超售比计算公式.

常见问题

Q: 对于 CPU, 获取 TP50/90/95/99 的 cpu 利用率作为业务容器平均 cpu 利用率 (即从小到大排序有第 50/90/95/99 位的容器 cpu 使用率)

是按哪个利用率作为阀值来决策呢?

A: cpu 默认以 P95 为决策,对于个别有明显波峰波谷的服务需要根据画像数据做具体调整. mem 默认以时间窗口内的峰值为决策.

Q: 内存超卖会影响业务稳定性,建议不进行。如果内存真的不合理,应推动业务主动更改配置更新服务

在资源调度层面不建议做内存和CPU超卖,会导致调度系统过于复杂,k8s pod层面request和limit可以不一样适当超卖

A: 内存不会进行超卖. 本次会对 cpu/mem 给出规格推荐值(界面展示). 会以邮件或其他通知方式推动配置更新. 用户主动在 PaaS 平台界面上按推荐值修改的资源规格实际影响的是 k8s limit. 对于方案中 VPA 调整实际是 k8s request, 对于用户无感. 同时对于 k8s resources limit 不会在调度链路中动态修改

Q: Recommender 虽然做了项目白名单可以选择性开启该功能,但自动调整风险较高。如果是一次性的调整,完全可以由平台给出参考建议,督促业务检查确认是否合理,之后由业务做出调整

如果是针对波峰波谷流量下资源的调整,可以给出利用率等曲线,业务需要综合服务延时等 确定按时段扩缩容规则,平台按业务规则进行操作。需要留一定的利用率buffer,要保证能够快速拉起服务

平台需要全局考虑所有业务在某个时间点扩容后需要的资源是否大于集群物理资源

因为在线任务原则上都是不能kill的,是高优,在线任务需要扩容时需要能保证资源,都是在线就无法完全保证了,可以结合离线任务来填补波峰波谷的资源; 在离线混部需要考虑离线任务对在线任务的干扰,需要一定的资源隔离机制保证。初期可以混部少量离线任务逐步打磨

Q: 在线资源利用率优化需要在考虑业务稳定性和服务延时的情况下去做,建议分步骤逐步实施,主要分为纵向扩缩容和横向扩缩容

1、纵向扩缩容,在满足业务延时情况下,尽力提升qps的情况下,资源仍然有富裕的,这部分应该通过缩减实例配置来优化

2、横向扩容容,在实例配置合理的情况下,因为业务流量下降(固定的)或者波峰波谷,可以调整实例数量来调整单实例的资源利用率

初期可以考虑在业务峰值压力下 如何优化单实例配置 和 实例数量,波峰波谷下的实例调整可以在一期积累更多经验后再进行。

A:合理的. 非常同意,目前计划是在 recommender 组件的机制上先留出这样一个策略的口子. 但不计划对生产业务线接入. 后续有能力建设对业务无感的资源调整机制后再通过这个口子开放业务接入.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容