郭云龙,腾讯云高级工程师,目前就职于 CSIG 云产品三部-AI 应用产品中心,现负责中心后台业务框架开发。
导语
为了满足 AI 能力在公有云 SaaS 场景下,服务和模型需要快速迭代交付的需求,保障服务在不稳定高并发时的高成功率,以及进一步提升资源利用率,AI 应用产品中心进行了一系列的调研与实践,本篇将重点介绍团队在容器化方面的实践经验。
背景和问题
公有云 AI SaaS 产品(如人脸融合[1])的一般服务流程为:C 端或 B 端客户通过采集设备采集图像、音视频等,经由云 API 等接入方式传入,服务端利用强大的计算能力、充足的资源和相对成熟的算法对客户输入的多媒体内容进行处理。
如上图所示,对于一般流程来说,我们面临着三个挑战。
- 采集质量不稳定:由于采集设备之间存在差异,采集到的质量也会存在差异,拿图像处理来说,大图和小图会给我们的服务带来不同的压力,有时服务会因为集中的大图并发产生失败。
- 短期、高并发需求多:我们的客户会用我们的能力实现不同的玩法,使用人脸融合来进行游戏活动宣传就是一个很常见的运营手段,但是这种活动会给我们的服务带来短期内的高并发压力。
- 模型、服务迭代快:AI SaaS 服务的竞争非常激烈,经常会有客户提出新的需求,加上算法难免会有 badcase,所以我们的服务也要进行很频繁的升级迭代。
我们再来看下我们容器化前的精简架构(如上图所示),物理机的开发部署大背景下,我们的逻辑服务不论是结构上还是基础上都属于大泥球模式,另外算法服务也常有混布的现象存在。
这种架构也导致了忙时服务间抢占资源的情况频繁发生,影响服务成功率及耗时,导致我们没有办法很好的满足客户的需求;而闲时资源利用率非常低,容易造成资源浪费。
以两个实际的例子来说明:
- 升级发布时,我们需要先从 LB 中剔除一个节点,并在节点上观察没有流量进入后进行服务升级。升级完成后,人工对服务进行成功性检测,检测结果 OK 后再加回 LB 中。
- 客户搞活动时提出高并发需求,如果当前物理机/vm 资源池不满足,需要向资源同学紧急提物理机需求,资源同学协调到机器后,我们需要人工对机器环境/网络重新初始化,然后执行上述 1 操作。待活动结束后机器闲置,易造成成本浪费。
为了更好的满足客户不断迭代的需求,减轻研发的运维负担,补齐弹性能力和接入高效的服务管控平台对我们来说是迫切需要的。趁着公司推动上云的时机,我们对架构组件进行了几轮调研和优化。本文主要对容器化过程进行阐述。
容器化过程记录
我们的容器化上云到现在为止可以分为三步:容器化,稳定性提升和利用率提升。
容器化
这里的容器化映射到业务上来说,除了将服务载体由物理机迁移到容器上,更主要是将原来的复杂逻辑解耦,微服务化。
如下图所示,我们先对服务本身做了瘦身微服务化,另外借助于容器的能力,将原来混布的服务彻底分开。如何进行微服务化会因业务的不同存在差异,本篇对此不做赘述。
稳定性提升
在第一步容器化之后,我们很快享受到了飞一般的服务升级和扩容速度。同时对容器化比较浅显的理解也给我们带来了一些新的问题。
- 调用量波动较大的服务由于频繁扩缩容导致业务失败
- 一些客户传的大图在低核容器上处理效率较低
- 集群资源紧缺导致的容器无法按需扩容等。
对于上述三个问题,我们也分别找出了应对方案。
灵活使用探针
起初我们的服务都是没有设置存活和就绪检测(探针[2] )的,Prestop 给缩容时加上了一层保护,但是并不彻底,而且在扩容时难免会有服务失败。
探针给我们提供了另一种强大的解决方式。一开始时,我们参照链接中的示例,进行简单的端口检查来判断服务是否正常运行。后来我们发现了更多灵活的运用技巧和使用场景。以下列出几个例子供大家参考以及发散出更多有趣实践。
例子1:在一开始时大家经常遇到 LB Agent 启动时获取路由必然失败的情况,我们可以使用就绪探针来进行 LB 的预加载(如下图),即可达到 LB 获取成功后标记服务启动成功的效果。
例子2:由于一些低版本OS的实例存在弱口令的问题,大家需要把所有依赖旧版 OS 的镜像全部升级,这个工作对我们来说是及其繁重的,于是我们同样利用了探针,在容器标记服务启动前把弱口令全部干掉。
例子3:某个服务比较特殊,内存占用经常波动,当内存小于某个值时,服务会偶现失败,但是端口正常存活。这时我们可以使用 ConfigMap python 脚本来进行一些复杂的检测:
针对大图进行筛选适配
容器化后,我们发现某个算法在接收到高分辨率图片时,服务成功率会出现波动,原因是算法在对提特征时会出现更多的消耗,这一现象在物理机上部署时被物理机核数多的优势掩盖住了,一旦到了核数较低的容器上就显露了出来。为了解决这个问题,我们在上层逻辑中新增了大图筛选功能(如下图所示),如果检测到是大图,则走回物理机集群(由于初始时 TKEx 提供最高规格容器核数为 8 核,后来才扩充支持了 24 核及以上),如果是一般图片,则走容器集群。
多集群部署
在使用 TKEx 时,我们经常会碰到部署的 workload 会因为整体集群资源不足的原因,无法扩容到指定的 max 值,一度非常苦恼。
TKEx 的同学也是推荐我们在其他的集群复制一份资源,当一个集群扩不出来时,另一个集群充当备份角色。在这么调整过后,我们的扩容成功率逐步上升。
后来又出现了整个地域的资源都比较紧缺的情况,于是我们把一些对时延不那么敏感的服务进行了多地域部署(如下图),最终将集群资源不足的风险进一步降低。
当一地资源不足的情况下使用多地域部署以及 LB 时,一般 LB 都会根据后端响应时间动态调整各节点权重,所以我们应注意以下两点:
- 关闭就近访问
- 根据上下游调整 LB 权重(比如上游服务部署在广州,下游同时部署了南京和广州,这是南京和广州的 LB 权重分别为130,100)
利用率提升
在进行过一轮稳定性提升之后,我们可以更加自信的利用弹性能力,利用率也有了显著提升。不过依旧有两个问题阻碍着我们的利用率更进一步。一个是有些服务模型大,启动慢,流量突增时服务无法很及时的扩容出来,这时我们必须要提前占用一些资源导致利用率提不上去。
针对第一个问题,我们挑选了部分流量有规律的服务。利用 TKE 提供的定时 HPA 能力,在已知流量高峰前定时进行一轮扩容。
成果
优化前 | 优化后 | |
---|---|---|
资源占用 | 1500 CPU 物理机 ( 8w 核)800 GPU 物理机 (P4 1600 卡) | CPU 6w 核 T4 1000 卡 |
资源利用率 | 10% | 30% |
成本 | - | -40% |
服务成功率 | 99.9% | 99.95% |
服务扩容效率 | 小规模 (<2000核):3 小时 大规模:2天 | 小规模 (<2000核):10分钟 大规模:6小时 |
服务升级效率 | 小规模 (<50实例):6 小时 大规模:2天 | 小规模 (<50实例):30分钟 大规模:6小时 |
当前我们的 AI 服务已经基本完成容器化的升级。成功率高,扩容快,欢迎大家扫码进行体验。
参考资料
[1]
人脸融合: 【https://cloud.tencent.com/product/facefusion】
[2]
探针: 【https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/】
互动赢好礼
精读文章,回答问题赢好礼
Q1:K8s 是怎么做到对 GPU 的支持的呢?
Q2:对于镜像较大的服务,大家觉得应该如何加速扩容时的服务启动的速度呢?
9月24日上午11点,由作者选出回答最佳的5位读者,送腾讯超可爱粉鹅一只。
往期精选推荐
- qGPU on TKE - 腾讯云发布下一代 GPU 容器共享技术
- 如何高效掌控K8s资源变化?K8s Informer实现机制浅析
- 腾讯云 TKE Everywhere 特性发布,用户可在自有基础设施中托管 K8s 服务
- Getting Started and Beyond|云原生应用负载均衡选型指南
- 云原生 AI 前沿:Kubeflow Training Operator 统一云上 AI 训练
点个“在看”每天学习最新技术