抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

网易轻舟 Serverless 平台 Knative 性能调优实践

2020 年 6 月 29 日

网易轻舟 Serverless 平台 Knative 性能调优实践

Serverless 技术正在获得越来越多的认可。CNCF 2019 年报告显示,41% 的受访者表示已经在使用 Serverless,另外 20% 的受访者表示计划在未来 12-18 个月内采用 Serverless 技术。


Serverless 技术关注者对其价值点讨论⼤多是基于公有云场景的云函数等产品,其关注点在资源支付方式更加细粒度,和公有云 Baas 的粘合上,和私有云环境中业务团队关注的价值不太契合;在我们对业界落地场景调研以及同业务团队⼀起实践后,我们发现私有云环境中业务团队关心的 Serverless 价值可概括为三点:


  1. 提效: 加快业务团队迭代效率, Serverless 对开发流水线重新对分工,业务开发人员聚焦业务,无需操心运维和扩容等诸多事项;

  2. 降本:按需实时弹性可避免资源浪费,最大程度发挥资源优势;

  3. 解耦:支持事件触发,将各个组件通信的逻辑变成事件进⾏解耦合,非常适合业务的扩展和变化;


其中“提效”和“降本”为核心价值,解耦为重要考虑点。


我们认为 Serverless 出现不是为了替代现有的 Serverful(传统云)框架,两者是互补的关系,Serverless 有其业务场景优势(后续⽂章再展开),合适最重要。笔者目前工作是聚焦轻舟 Serverless(“轻舟”系网易研发的云原生基础设施平台代号)和业务团队⼀起实现业务开发的提效、降本和解耦。当前开源 Serverless 方案很多,而选型强大活跃开源社区方案让我们能够持续改进自己的 Serverless 平台。基于此诉求,我们很早便选型了 Knative,因为从一开始其社区非常活跃,有 Google,IBM,RedHat 等大公司参与,其次是标准先行。而事实也在慢慢印证了我们的选择。



如图所示, Knative 占据了 34% 的份额,遥遥领先于第⼆名 OpenFaaS,Knative 是搭建 Serverless 平台的首选。( 数 据 来 源 于 CNCF 2019 年 社 区 调 查 报 告


目前,网易轻舟云原生团队已经和网易云音乐前端团队合作共建云音乐 Serverless 部署平台 ALPACA,将 Serverless 用于前端场景。该平台架构如下图。



其中轻舟负责底层能力,Knative 是其中的核心能力,我们基于其业务场景,对 Knative 进行了压测分析,也做了性能调优 POC,本文主要从性能角度,基于 Serverless 前端使用场景对 Knative 进行分析,尝试揭开 Knative 核心数据路径性能真相并给出调优思考。


⼀、Knative 系统内的数据路径分析

本文暂不讨论流量如何导⼊到 ALPACA 平台,先聚焦到 ALPACA 平台 Knative 系统内部本身。


Knative 系统内部数据路径是, Knative 网关->Activator->Queue Proxy->业务 App;社区推荐使用的方式是不注入 Sidecar 以获取更佳的性能,因此我们讨论场景是“不注入 Sidecar,管控面使用 Pilot,Knative 网关使用轻舟的 API 网关产品”。



Knative 系统内部默认的数据路径如上图,用户业务流量经过一层 Knative 网关,经过 Activator 到达 Queue Proxy 代理组件,最后到达应用程序。


从上图可知,默认情况下流量经过三层代理(Knative 网关、Activator、Queue Proxy)后才到达应用 APP,每⼀层代理均可能是性能的拦路虎。


我们的分析思路如下:


  • Knative 网关这⼀层承载了流量管理、灰度发布等功能必须存在,当前使用轻舟 API 网关产品充当,性能均调优过,本身性能没什么问题,非本次核心关注点

  • App 为用户的业务代码性能无法控制,平台层面不可操作,也非关注点

  • 于是将性能分析要点集中到剩余的两层代理(Activator 和 Queue Proxy)上。


首先 Activator 作用是:


  • 冷启动充当看门人,业务 POD 0-1 流量会经过 Activator 组件

  • 突发流量的保护者,将 Activator 加⼊到核心路径,充当缓冲,流量将会在 Activator 缓存(0.8版本加入功能)


其次 Queue Proxy 作用是:


Queue Proxy 以 Sidecar⽅式和应⽤容器部署到同⼀个 Pod,Queue Proxy 是为了配合完成扩缩容事宜以及满足 App 可观测性要求,以 Sidecar 方式部署主要考虑到对 App 应用无侵入,功能描述如下:


  • 完成观测性数据收集向 Autoscaler 同步当前的并发监控,以便实现自动伸缩功能

  • 代理业务容器,完成指标的统计,并将对应的数据汇报给后端的⽇志/监控/分布式跟踪服务


Activator 必要性分析

谈到 Activator 必要性,需要先了解当前 Serverless 难题“冷启动”,所谓冷启动是 Serverless 缩容到 0 后,重新从 0 扩容到 1 的过程,该过程目前是非常慢的,也是业界难题,根据社区对 Knative 冷启动分析得知,冷启动时间大概 6s ,很显然 6s 的冷启动任何业务都⽆法容忍;当前可以尽量优化冷启动时间,但是想达到 ms 级别,做到业务⽆感知,挑战非常大,目前有两种解决思路:


方向 1: 温启动,通过冗余方式建立预热池来解决,当需要 0-1 时候,从预热池取,然后将用户程序注入,省去建立容器的过程


方向 2: 通过默认预留实例来规避


目前该问题我们先通过方向 2 来解决,至于方向 1 也在考虑,但是涉及到的开发工作量大,且需要对 K8s 框架改动,需要根据需求触发。所以目前在我们使用场景中不需要 Activator 帮助从 0-1 扩容。


对于突发流量保护功能,在使⽤场景中可降低扩容触发的并发要求,预留出一定的 Pod 计算能力来抵御突发流量;因此在目前业务场景中,Activator 存在必要性⼀般,可以考虑将其从核心数据路径中彻底去除。


QueueProxy 必要性分析

Queue Proxy 核心作用是收集 App 的指标(并发、RPS 等)来决定扩容,当前以 Sidecar⽅式部署是非常有必要的:


  • 将核心指标统计逻辑提炼到 Queue Proxy,对 App 无任何代码逻辑侵⼊,基础设施和应用 App 业务逻辑分离,独立运维

  • 收集扩容指标支持跨语言


所以 Queue Proxy Sidecar 是非常有必要的,但是相比裸业务容器而言,会增加⼀层代理(该场景就像服务网格 Server Sidecar⼀样),导致业务容器性能降低,这是选择这种架构所要付出的资源成本,我们要做的就是将该成本降到最小。



如上图,总结下分析结论,从性能⾓度出发,我们需要关注:


将 Activator 从数据路径中去除


重点关注 Queue Proxy 和 App 路径


关注 Knative 网关和 Queue Proxy 路径


⼆、开源 Knaitve 性能实际测试

从上文的分析结论可知,我们得到了具体的性能关注点,于是对这些关注点进行实际的性能测试。


在 Knative 框架下,性能可以通过 CPU 和实例个数横向扩展性能,所以后续测试均固定在单个业务容器,通过对比测试来发现性能瓶颈,业务容器选型社区简单的 go 语言实现的 helloworld 服务程序(镜像为 hub.c.163.com/qingzhou/knative/demo/helloworld-go:v0.1),采用测试工具 Hey(https://github.com/rakyll/hey )使⽤HTTP 长连接进行测试。


测试环境


  • Knative serving 0.14

  • 物理机容器

  • 轻舟网关

  • 三台独立的物理机器避免相互影响


测试方法

  1. 部署测试 server kservice


root@pubt1-k8s59:/home/liuqinlong# cat performance.yamlapiVersion: serving.knative.dev/v1alpha1kind: Servicemetadata:  name: helloworld-go  namespace: defaultspec:  template:    metadata:      labels:        app: helloworld-go      annotations:        autoscaling.knative.dev/maxScale: "1"        autoscaling.knative.dev/minScale: "1"    spec:      containers:        - image: hub.c.163.com/qingzhou/knative/demo/helloworld-go:v0.1          env:            - name: SIMPLE_MSG              value: "helloworld-go"
复制代码


  1. 测试命令


hey -z 60s -c 70 --host "helloworld-go.default.example.com" "<http://10.178.67.100/>"
复制代码


  1. Knaitve 原生性能数据测试


  • 默认数据路径进行压测


如下结果显示,虽然 Activator 采用 HPA 进行性能扩展,但是其扩容非常慢,如果性能测试时候没有来得及扩容 Activator,对整个延迟影响效果巨⼤只有 920Qps。即使 Activator 扩容成了 8 个发现 p90 延时也在 7ms 以上,Qps 约 7 千。



避坑说明:在测试过程中,需要确认 Activator HPA 扩容是否生效,笔者测试过程中默认环境中没有安装 metrics-server 导致 Activator 无法 HPA 扩容。整个核⼼路径中 Activator 默认限制单个 CPU,其使用率达到 100%,导致 QPS 非常低(才 920),P90 延迟要 111ms,p99 延迟要 195.2ms


  • 原生容器对比含有 Queue Proxy sidecar 的容器



经过前文的分析 Queue Proxy 以 Sidecar⽅式存在是 Knative 架构要求,当前测试 case 情况下,加⼊Queue Proxy Sidecar 后,相⽐原⽣容器,QPS 从 3.9w->3.1w,P90 延迟翻倍(2.5->4.2)。


相对来说,在相同并发压力情况下,因为新增⼀层代理延迟肯定提升,QPS 会跟着降低。但是我们发现 CPU 损失代价有些大,CPU 使⽤率达到了 1497% (Server CPU 才 482.4%),理论测试的 App 为 hello world 程序业务逻辑⾮常简单,业务处理延迟不长,Queue Proxy 和当前测试 App CPU 使用率比值最好是 1:1,所以 Queue Proxy 存在 CPU 异常消耗的问题,需要进行调优解决。


注意:v0.14 Queue Proxy 性能要比 v0.9 版本 Queue Proxy 性能要好,后⽂Queue Proxy 测试版本均采⽤的是 v0.14 版本,下面给出性能对比:



QPS 提升 (31891.7207-20505.6853)/20505.6853 = 55%(计算过程后文不再赘述)。


测试结论

  • Activator 加⼊到数据路径中,在没有扩容情况下,性能⾮常差 QPS 只有 920,经过 HPA 扩容成 8 个后,QPS 可达 7776.1257

  • 业务容器引入 Sidecar 后,数据路径变长,相同压⼒下 QPS 从 3.9w -> 3.1w,P90 延迟翻倍(2.5->4.2),但是 CPU 使⽤率达到了 1497%,和 Server CPU 消耗差距约三倍,需对 Queue Proxy⾼CPU 问题进行分析

  • Knative 社区对 Queue Proxy 也在不断优化中,社区 v0.14 Queue Proxy 相比 v0.9 版本的 Queue Proxy 性能提升明显,QPS 2w->3w,延迟 6ms->4.2 ms


三、Knaitve 数据路径性能优化

经过对 Knative 性能测试,进⼀步确认了下面性能调优点:


1.数据路径上去除 Activator


2.Queue Proxy 和 App 路径优化


3.优化 Knative Gateway 性能


数据路径上去除 Activator

分析对比去除 Activator 路径带来的性能收益,如下表,将 Activator 移出核心数据路径后,QPS 能力提升三倍(7776.1257 -> 25569.5698),且 P99 延迟大幅降低



Queue Proxy 和 App 路径优化

1.组件优化


经过对 Queue Proxy-> App 路径分析,有两种优化方法,阐述如下:


优化方向一: 优化 Queue Proxy


优化 Queue Proxy HTTP 代理解析过程,延迟大幅度降低(4.2->2.4 ms),且 CPU 使用率大幅度降低(代理 CPU 使用率接近 Server CPU 使用率),QPS 小幅度提升。



优化方向二:将 Queue Proxy 替换成 Envoy


优化后 QPS 相对社区 Queue Proxy 版本提升 23%,延迟也大幅度降低,代理 CPU 使用率接近 ServerCPU 使用率。



2.框架优化


框架上协议栈穿透,通过 sockmap 以及 sock redirect 特性加速 Queue Proxy 和业务容器 App 之间通信。原理如下图:



基于轻舟的基于 EBPF 的高性能网络加速组件–SOPS,开启该功能,测试结果如下:



  • 针对于 Queue Proxy 代理,组件优化+协议栈穿透, QPS 提升 26%

  • 针对于 Envoy Proxy 代理,协议栈穿透,QPS 提升 44%

  • 在当前测试 Case 场景下,协议栈穿透,可以提升业务容器 QPS 上限约 20%。


Knative 系统内全路径测试结果


注:单位百分百 CPU 支撑的 Qps= Qps/(Gateway(cpu%)+ QueueProxy(cpu%) + server(cpu%))


  • 轻舟调优的 Queue Proxy 可以将 QPS 提升 23%,连同 SOPS 一起可将 QPS 提升 43%

  • 使用 Envoy 替代 Queue Proxy 可将 QPS 提升 39%,连同 SOPS 一起可将 QPS 提升到 55%

  • 轻舟调优的 Queue Proxy 可以将 Queue Proxy CPU 占比高问题解决

  • 使用 Envoy 替换 Queue Proxy 可将 QPS 额外提升 12%,单位 CPU 百分比支撑的 QPS 基本一致


Knative 社区也在讨论 Envoy 代替 Queue Proxy,但是具体何时未知,考虑到工作量较大,我们打算 follow 社区进度;从性能角度和使用场景考虑,当前优化 Queue Proxy 也不差,所以先优化 Queue Proxy 来满足业务需求。


优化 Knative Gateway 性能

网关性能优化方面轻舟网关团队已经做了较多工作,性能也较为可观,在 Knative 当前使用场景,我们计划将 Gateway 底层网络更换成轻舟高性能网络,继续降低延迟,提升 Gateway 性能天花板,降低 CPU 使用率,使得单位百分比 CPU 支撑更多的业务 QPS。


总结

Knative 框架内,默认情况下引入了三层代理路径,固定压力(70 连接)下测试发现,默认情况下 Knative 性能表现非常不佳;经过调优(去除 Activator 这⼀层代理+ 使用 Queue Proxy v0.14 并优化+ 使用 Sops 加速 Queue Proxy 和 App 路径)Knative 框架性能表现还是非常优异的。


和裸业务容器相比:


1、单位百分比 CPU 支撑的 QPS 5:1


2、链路的变长,当前测试场景和测试方法下,链路延迟 p90 提升 2.5->4.7 约 2.2ms


从性能角度看 Knative 业务容器和裸业务容器,直接使用容器性能是最好的,使用 Knative 业务容器牺牲还是可以接受的。


下面进一步探讨,Knative 和 K8s 到底是什么关系?


从功能角度看,Knative 框架是 K8s 补充,工作在业务层次,解决业务的 “什么时候该扩容”,“怎么扩容”,“什么时候触发业务运行”等问题,是专业搞定业务自动扩缩容和事件触发的功能组件。


Knative 框架支持功能并不什么新鲜事情,其功能特性,完全可以通过,K8s 容器 + 智能网关+ 自定义扩容数据收集机制和并发控制+自己编码事件机制来代替+上层业务封装逻辑来替代,但是需较多的研发投入,而且对接 API 为私有 API 接口,对用户有绑定。


从自动扩容角度看,业务的扩缩容也可以通过 HPA 来完成,但是这种方案速度较慢,一般 3-5 分钟,无法适应业务快速扩容需求。



我们基于 K8s 角度对 Knative 框架下一个定义:Knaitve=K8s++,是⼀种对 K8s 补充,是一种通过牺牲 CPU 和局部的延迟,换取业务流量管理能力(红绿发布、回滚、流量管理)和业务扩展能⼒(自动扩容能力、事件机制等)的开源软件框架。


四、业务流量导⼊Knative

前文性能分析均是基于单个业务 Pod,Knative 本身性能可从单个业务 Pod 横向扩展出多个业务 Pod 来进行性能扩容而且其非常擅长这一点,这里不赘述。下面介绍业务流量如何从外部导入 Knative 系统,因为 Knative 系统内部扩展性没什么问题,我们需要使得接入 Knative 系统部分具备更强的横向扩展能⼒,以满足业务扩容的性能需求。


在选型之初,我们打算按照如下架构图,流量接入到 Knative 系统。流量经过 Nginx Https 代理 -> 轻舟网关-> 轻舟 Knative 网关 -> Queue Proxy -> 业务 App,其中:


Nginx:主要作用是 HTTPS 加密


轻舟网关:主要做 URL 路径和域名路径的转换、业务降级


轻舟 Knative 网关:主要实现红绿发布、流量管理等功能



上图中业务路径比较长,特别是经过了三次 7 层网关(Nginx、轻舟网关、轻舟 Knative 网关),且 Nginx 和轻舟网关存在能力集重复问题,所以我们打算做如下调整:


使用轻舟网关接管 Nginx 的 HTTPS 的能⼒,缩短七层代理的路径,采用轻舟网关自动降级功能,业务降低避免了人为操作,为了方案的可扩展(性能横向扩展、未来 IPv6 需要等)和部署的灵活性,引入低延时的轻舟的四层 LB。架构如下图,做到各个层可横向扩展。



因为方案降级需求,轻舟网关需要连云外的降级资源,但 Knative 网关无法管理该云外资源,所以目前无法将 Knative 网关和轻舟网关融合成一个网关。未来 Serverless 平台不再需要云外的降级资源,再将轻舟网关和轻舟 Knative 网关合并,达到如下流量框架,进一步缩短流量路径,达到最佳性能。



实现轻舟网关和轻舟 Knative 网关的融合需要修改 Knative,原因是:Knative 默认通过域名来区分应用,非常适合公有云,但是往往私有云业务场景,域名是固定且受限的,甚至有时候固定嵌入到客户端代码中,所以通过域名进行应用区分非常不适合,对于 HTTP 协议来说,我们需要使用请求路径来区分应用。


五、总结和展望

基于云原生化的泛前端部署平台依赖的底层 Knative 场景,通过分析,我们发现 Knative 社区默认情况下性能非常差,配置调优(不注入 Sidecar + 将 Activator 从数据路径中去除后+使用 Queue Proxy v0.14 版本)后,除 Queue Proxy CPU 偏高外,性能还可以,特别是经过调优 Queue Proxy、框架上协议栈穿透优化以及业务流量导入路径缩短后,性能可满足绝大部分业务需求,目前社区对于性能也在继续优化中(v0.14 相比 v0.9 QPS 性能约有 55%提升),我们相信社区 Knative 数据路径的性能会越来越好。


作者简介:


刘勤龙,网易杭州研究院资深云计算开发工程师,7 年服务端开发和优化经验,负责网易轻舟四层负载均衡数据面设计,参与轻舟服务网格性能优化,目前专注于轻舟云原生 Serverless 平台底层的开发和优化工作。主要关注 Kubernetes、Istio、Knative、Cilium 等技术领域。


2020 年 6 月 29 日 15:172433

评论

发布
暂无评论
发现更多内容

亚马逊云 AWS LightSail 搭建高性能 LNMP 环境并安全部署 Wordpress

小蚂蚁(Snow Hide)

Nginx PHP-FPM Wordpress 部署 SELinux 安全上下文配置 亚马逊云 AWS Lightsail 安全

越是困难,越是要做有分析判断能力的人

霍太稳@极客邦科技

创业 团队管理 个人成长

微服务架构深度解析与最佳实践 - 第三部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

微服务架构深度解析与最佳实践 - 第五部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

最近看了两本书:The Rules of Life 和 Make Big Happen

霍太稳@极客邦科技

创业 团队管理 自我管理

2019 年

贾献华

2020 2019 总结 日历 计划

微服务架构深度解析与最佳实践(全篇汇总)

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

两边夹的应用

孙苏勇

算法 积水问题 两边夹

数据分析师应该了解的数据湖

数据社

大数据 数据仓库 数据湖 数据分析

微服务架构深度解析与最佳实践 - 第六部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

微服务架构深度解析与最佳实践 - 第七部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

黄金思维圈,养成透过现象看本质的能力

非著名程序员

读书笔记 程序员 程序人生 提升认知

归去来兮:递归

曲镇

算法

微服务架构深度解析与最佳实践-第二部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

小程序的当下和未来可能 | GMTC.2019深圳站演讲文稿

崔红保

小程序 uni-app

平均响应1000ms到200ms,PHP和Go那家强?

拖地先生

php 架构 性能优化 后台开发 运维

你不是迷茫,只是缺乏目标

ikook

学习 身心健康 方法 自我管理

程序员职业生涯的八点感想

池建强

程序员 职业

申请鲲鹏920测试机试水+编译nginx

草宝虫

鲲鹏920 centos7 nginx编译 armv8

两边夹的应用二

孙苏勇

算法 两边夹 重排序 函数式接口 Lambda

微服务架构深度解析与最佳实践 - 第四部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

阿里笔记之数据模型

迹_Jason

大数据

聊聊:Python

谢烟客

Python 人工智能 编程

一个独立开发者,他是如何做到月入 20 万的?

非著名程序员

程序员 独立开发者 副业赚钱 开发者 程序人生

求稳不得

孙苏勇

职业 发展 职场

一个运营经理人的工作两周年总结

霍太稳@极客邦科技

高效工作 身心健康 项目管理 自我管理

浅谈数据中台

数据社

大数据 数据中台 数据仓库

一文讲清楚 MySQL 事务隔离级别和实现原理,开发人员必备知识点

古时的风筝

MySQL 数据库 事务隔离级别 mysql事务 数据库事务

微服务架构深度解析与最佳实践-第一部分

kimmking

微服务 微服务架构 最佳实践 深度解析 高可用

凡事必先骑上虎背

ikook

学习 态度 方法论

【译】Rust 开发者的2019

WasmEdge

程序员 rust

Study Go: From Zero to Hero

Study Go: From Zero to Hero

网易轻舟 Serverless 平台 Knative 性能调优实践-InfoQ