Koordinator 最佳实践系列:精细化 CPU 编排
作者:乔普、申信
介绍
在云原生环境中,集群提供者常常将不同类型的工作负载部署在同一个集群中,利用不同业务的不同峰值效果,实现资源分时复用,避免资源浪费。然而,不同类型负载之间混合部署常常会导致资源竞争和相互干扰。最为典型的场景便是在线和离线负载的混合部署。当离线较多的占用计算资源时,在线负载的响应时间就会受到影响;当在线长时间较多的占用计算资源时,离线负载的任务完成时间不能得到保证。这种现象属于 Noisy Neighbor 问题。
根据混合部署的程度、资源类型的不同,解决该问题有许多不同的思路。Quota 管理可从整个集群维度限制负载的资源使用量,Koordinator 在这方面提供了多层次弹性 Quota 管理功能 [ 1] 。单机维度上看,CPU、内存、磁盘 IO,网络资源都有可能被不同负载共享。Koordinator 在 CPU、内存上已经提供了一些资源隔离和保障的能力,磁盘 IO 和网络资源方面的相关能力正在建设中。
本文主要介绍当不同类型工作负载混合部署在同一个节点上时,Koordinator 如何帮助负载之间(在线和在线、在线和离线)协同地共享 CPU 资源。
问题描述
CPU 资源 Noisy Neighbor 的本质是不同的负载之间无协同地共享 CPU 资源。
- Kubernetes 默认的资源模型利用 cgroup(cfs quota) 从 CPU 时间使用量上来限制不同负载对于 CPU 资源的访问。这种情况下,一些负载就可能会被操作系统调度器切换所在的 CPU 核。由于不同 CPU 核对不同物理位置的内存访问时间不同,切换大概率会导致更长的内存访问时间,从而影响负载性能。
- 在 NUMA 架构中,SMT 线程(逻辑核)共享物理核的执行单元和 L2 缓存。当同一个物理核中有多种工作负载时,不同工作负载间就会产生资源争抢,导致负载性能下降。
Kubernetes 在单机侧提供了拓扑管理器和 CPU 管理器来尝试解决上述问题。然而,该功能只有在 Pod 已经调度到机器上之后才会尝试生效。这样就有可能导致 Pod 会被调度到 CPU 资源满足但是 CPU 拓扑不满足负载要求的情况。
解决方案
面向应用的 CPU 编排 QoS 语义
针对上述问题和不足,Koordinator 设计了面向应用的 QoS 语义和 CPU 编排协议,如下图所示。
LS(Latency Sensitive)应用于典型的微服务负载,Koordinator 将其与其它的延迟敏感型负载隔离保障其性能。LSR(Latency Sensitive Reserved)类似于 Kubernetes 的 Guaranteed,在 LS 的基础上增加了应用要求预留绑核的语义。LSE(Latency Sensitive Exclusive)则常见于中间件等对 CPU 特别敏感的应用,Koordinator 除了满足其类似于 LSR 要求绑核的语义外,还确保其所被分配的 CPU 不与任何其它负载共享。
另外,为提高资源利用率,BE 负载可与 LSR 和 LS 共享CPU。为了确保与 BE 共享的延迟敏感型应用不受其干扰,Koordinator 提供了如干扰检测、BE 压制等策略。本文重点不在此,读者可关注后续文章。
丰富的 CPU 编排策略
对于 LSE 类型的应用,当机器是超线程架构时,只能保证负载独占逻辑核。这样当同一个物理核中有其它负载时,应用性能仍会受干扰。为此,Koordinator 支持用户在 Pod Annotation 上配置丰富的 CPU 编排策略来提高性能。
CPU 编排策略分为 CPU 绑定策略和 CPU 独占策略。CPU 绑定策略决定应用所被分配逻辑核在物理核间的分布,可采用物理核间打散或者堆叠。堆叠(FullPCPU)的方式指为应用分配完整的物理内核,可以有效地缓解 Noisy Neighbor 问题。打散(SpreadByPCPU)则主要应用于一些具有多种不同峰谷特性的延迟敏感型应用,可以让应用程序在特定时间充分使用 CPU。CPU 独占策略决定应用所被分配逻辑核的独占级别,可尽量避开已经同独占策略申请的物理核或 NUMANode。
增强的 CPU 调度能力
Koordinator 支持配置 NUMA 的分配策略,决定在调度时如何选择满意的 NUMA 节点。MostAllocated 表示从可用资源最少的 NUMA 节点分配,可以尽可能减少碎片,为后续的负载留下更大的分配空间。但是,这种方式可能会导致依赖 Barrier 的并行代码性能收到影响。DistributeEvenly 表示在 NUMA 节点上平均分配 CPU,可以提高上述并行代码的性能。LeastAllocated 表示从可用资源最多的 NUMA 节点分配。
另外,Koordinator 对 CPU 的分配逻辑是在中心调度器完成的。这样就会有一个全局的视角,避免了 Kubernetes 单机方案可能导致的 CPU 资源量满足但是拓扑不满足的窘境。
最佳实践
由上文可知,Koordinator 精细化 CPU 编排能力能够显著提高多应用混合部署场景下 CPU 敏感型工作负载的性能。为了让读者能够更清楚地使用和直观感受 Koordinator 的精细化 CPU 编排能力,本文将在线应用采用不同方式部署到集群中,观察压测中服务的延迟,来判断 CPU 编排能力的效果。
本文会在同一个机器上部署多个在线应用,压测 10 分钟,以充分模拟生产实践中可能出现的 CPU 核切换场景。对于在线应用和离线应用混合部署的情况,Koordinator 提供了如干扰检测、BE 压制等策略。本文重点不在此,读者可关注后续文章中的实践。
本次实验采用以下指标,评估应用不同部署方式下 Nginx 应用的性能表现:
- 响应时间 RT(Response Time)分位值RT 是在线应用通常关注的性能指标,RT 越低代表在线服务性能越好。RT 指标通过收集 wrk 压测结束后打印的信息获得,在实验中反映了 Nginx 应用响应 wrk 请求所花费的时间。例如 RT-p50 表示 Nginx 响应前 50% wrk 请求最大所花费的时间(中位数),RT-p90 表示 Nginx 响应前 90% wrk 请求最大所花费的时间。
- 每秒请求数 RPS(Request Per Second)RPS 是在线应用每秒服务的请求数量,服务承受的 RPS 越多代表在线服务的性能越好。
实验结果如下:
- 对比 B 和 A,可以发现采用 LSE QoS 绑核之后,服务响应时间 P99 明显减小,很好地减轻了长尾现象
- 对比 C 和 B,可以发现采用 LSR QoS 绑核且允许逻辑核占用更多物理核资源之后,在服务响应时间更好的情况下可以承受更多的请求
综上,在线服务部署在同一机器的场景下,采用 koordinator 精细化 CPU 编排能够有效抑制 Noisy Neighbor 问题,减少 CPU 核切换带来的性能下降。
环境
首先,要先准备一个 Kubernetes 集群并安装 Koordinator [ 2] 。本文选择一个 Kubernetes 集群的两个节点来做实验,其中一个节点作为测试机,将运行 Nginx 在线服务器;另一节点作为压测机,将运行客户端的 wrk,向 Nginx 请求 Web 服务,制造压测请求。
在线应用
- 使用 ColocationProfile [ 3] 为应用注入精细化 CPU 编排协议
B 组精细化 CPU 编排协议:
apiVersion: config.koordinator.sh/v1alpha1 kind: ClusterColocationProfile metadata: name: colocation-profile-example spec: selector: matchLabels: app: nginx # 采用 LSE QoS qosClass: LSE annotations: # 采用物理核间堆叠 scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy":"FullPCPUs"}' priorityClassName: koord-prod
C 组 CPU 精细化编排协议:
apiVersion: config.koordinator.sh/v1alpha1 kind: ClusterColocationProfile metadata: name: colocation-profile-example spec: selector: matchLabels: app: nginx # 采用 LSR QoS qosClass: LSR annotations: # 采用物理核间打散且独占物理核 scheduling.koordinator.sh/resource-spec: '{"preferredCPUBindPolicy":"SpreadByPCPUs", "preferredCPUExclusivePolicy":"PCPULevel"}' priorityClassName: koord-prod
- 在线服务本文选用 Nginx 在线服务器,Pod YAML 如下:
--- # nginx应用配置 apiVersion: v1 data: config: |- user nginx; worker_processes 4; # Nginx的Worker个数,影响Nginx Server的并发。 events { worker_connections 1024; # 默认值为1024。 } http { server { listen 8000; gzip off; gzip_min_length 32; gzip_http_version 1.0; gzip_comp_level 3; gzip_types *; } } #daemon off; kind: ConfigMap metadata: name: nginx-conf-0 --- # Nginx实例,作为在线类型服务应用。 apiVersion: v1 kind: Pod metadata: labels: app: nginx name: nginx-0 namespace: default spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - "${node_name}" schedulerName: koord-scheduler priorityClassName: koord-prod containers: - image: 'koordinatorsh/nginx:v1.18-koord-exmaple' imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 8000 hostPort: 8000 # 压测请求访问的端口。 protocol: TCP resources: limits: cpu: '4' memory: 8Gi requests: cpu: '4' memory: 8Gi volumeMounts: - mountPath: /apps/nginx/conf name: config hostNetwork: true restartPolicy: Never volumes: - configMap: items: - key: config path: nginx.conf name: nginx-conf-0 name: config
- 执行以下命令,部署 Nginx 应用
kubectl apply -f nginx-0.yaml
- 执行以下命令,查看 Nginx 应用的 Pod 状态
kubectl get pod -l app=nginx -o wide
可以看到输出如下,表示 Nginx 应用已经在测试机上正常运行
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-0 1/1 Running 0 2m46s 10.0.0.246 cn-beijing.10.0.0.246 <none> <none>
- 在压测机上,执行以下命令,部署压测工具 wrk
wget -O wrk-4.2.0.tar.gz https://github.com/wg/wrk/archive/refs/tags/4.2.0.tar.gz && tar -xvf wrk-4.2.0.tar.gz cd wrk-4.2.0 && make && chmod +x ./wrk
压测
- 使用压测工具 wrk,向 Nginx 应用发起压测请求。
# node_ip填写测试机的IP地址,用于wrk向测试机发起压测;8000是Nginx暴露到测试机的端口。 taskset -c 32-45 ./wrk -t120 -c400 -d600s --latency http://${node_ip}:8000/
- 等待 wrk 运行结束后,获取 wrk 的压测结果,wrk 输出格式如下所示。重复多次测试,以获得相对稳定的结果。
Running 10m test @ http://192.168.0.186:8000/ 120 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev Latency 3.29ms 2.49ms 352.52ms 91.07% Req/Sec 0.96k 321.04 3.28k 62.00% Latency Distribution 50% 2.60ms 75% 3.94ms 90% 5.55ms 99% 12.40ms 68800242 requests in 10.00m, 54.46GB read Requests/sec: 114648.19 Transfer/sec: 92.93MB
总结
在 Kubernetes 集群中,不同业务负载之间可能存在 CPU、内存等资源的争抢,影响业务的性能和稳定性。面对 Noisy Neighbor 现象,用户可以使用 Koordinator 为应用配置更精细的 CPU 编排策略,使得不同应用可以协同的共享 CPU 资源。我们通过实验说明,Koordinator 的精细化 CPU 编排能力能有效抑制 CPU 资源的争抢,改善应用性能。
非常欢迎你通过 Github/Slack/钉钉/微信 等方式加入我们来参与 Koordinator 开源社区。你是否已经有一些希望与我们社区交流的内容呢?可以通过以下渠道参与讨论:
- 加入社区 Slack channel (English)
- 加入社区钉钉群:搜索群号 33383887 (Chinese)
相关链接:
[1] 多层次弹性 Quota 管理功能
https://koordinator.sh/docs/user-manuals/multi-hierarchy-elastic-quota-management/
[2] 安装 Koordinator
https://koordinator.sh/docs/installation/
[3] ColocationProfile
https://koordinator.sh/docs/user-manuals/colocation-profile/
点击此处,立即了解 Koordinator 项目!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
精选博客系列|vSphere 8 Update 1 介绍
去年,我们推出了 vSphere 8,这是传统和下一代应用程序的企业工作负载平台,该产品于2022年11月正式推出。今天,我们很高兴地宣布vSphere 8 Update 1版本。通过这个版本,客户可以获得增强的管理员操作效率,更高端的人工智能/机器学习工作负载的超级性能以及跨环境的升级安全性。预计 vSphere 8 Update 1 将在本财季结束前的四月份实现初始可用性,并根据我们的新发布模式进行发布。 vSphere 8 Update 1 在三个关键领域为客户提供了增强的价值。 增强运营效率 IT 管理员需要执行很多重复性任务来维护他们的环境。主机和集群配置、更新和升级对基础设施的持续健康至关重要,但它们会耗费宝贵的时间和资源,使其无法运行关键任务。随着 Update 1 的发布,vSphere 8 增加了降低运营负担和提高效率的额外功能。 下面讨论了一些关键功能: VMware vSphere® 配置文件TM 这个功能在 vSphere 8 中作为技术预览引入,将在 Update 1 中变得普遍可用和得到完全支持。通过使用 JSON 文件的声明性模型,简化主机生命周期管理,大...
- 下一篇
基于阿里云 Serverless 容器服务轻松部署企业级 AI 应用
作者:元毅、坤仑 数禾科技 AI 模型服务基于云原生架构,为不同业务环节提供智能决策支持。随着业务的快速发展,摆在数禾面前的难题是支撑模型计算的底层应用资源无法根据请求量来调整机器资源支持运算能力。同时,随着模型在线推理服务数量的增加,数禾的模型服务也变得越来越庞大、臃肿,难以管理。这种状况不仅导致了资源浪费,还增加了维护和升级的成本。 为了解决这些“顽疾”,数禾科技采用阿里云 ASK 部署线上模型,无需 K8s 节点管理,根据实时流量动态使用 POD,资源成本节省 60%;通过 ASK Knative 服务,解决了数禾模型的灰度发布和多版本并存问题;得益于ASK 自动伸缩和缩容到 0 的优势,降低运行成本,大幅提升服务可用性。 目前,该系统已上线部署 500+AI 模型服务,每天能够提供上亿次查询决策服务,具备无限横向扩展的能力。同时,数禾科技 AI 模型服务支持自动调整容量,满足不同业务压力下的需求,从而保障业务的稳定运行。不仅如此,采用云原生架构方案,平均部署周期由之前的1天缩短至 0.5天,大幅提升了研发迭代效率,从而加速商业化应用的进程,为金融业务提供新的增长动力。 关于 S...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装