SPRIGHT:将服务器无感知计算抽离出服务器!基于 eBPF 的高性能事件驱动和共享内存处理机制 转载
SPRIGHT:将服务器无感知计算抽离出服务器!基于 eBPF 的高性能事件驱动和共享内存处理机制
提要本文是对SIGCOMM 2022入选论文《SPRIGHT: Extracting the Server from Serverless Computing! High-performance eBPF-based Event-driven, Shared-memory Processing》的解读。服务器无感知计算承诺在云环境中提供一种高效、低成本的计算能力。然而现有的解决方案,例如典型的开源平台Knative,包含了重量级的组件,这阻碍了服务器无感知计算愿景的实现。此外,现有的服务器无感知计算平台缺乏对数据平面的优化使得函数链能够高效高性能的运行,而函数链又是流行的微服务开发模式。最后,冷启动也会损害服务延时。因此,本文提出了SPRIGHT,一种轻量级、高性能、快速反应的服务器无感知计算框架。通过广泛利用eBPF,SPRIGHT(1)实现了事件驱动的代理,替换了独立且长时间运行的重量级sidecar和网关组件;(2)实现了共享内存机制,显著避免了数据移动开销;(3)实现了直接函数路由功能,简化了函数间调用流程。实验结果表明,SPRIGHT能够在延时和吞吐上相比Knative有一个数量级的性能提升,同时显著降低了CPU的利用率,避免了冷启动的需求;相比于长时间运行、基于轮询机制的DPDK实现,SPRIGHT能够在真实负载情况下降低10倍CPU利用率。
背景和动机
服务器无感知计算允许用户将应用逻辑实现为函数,例如实现为一组松耦合的链状函数,即函数链,而云服务提供商负责函数运行和管理底层的操作系统和硬件资源。然而现有的服务器无感知环境引入了较多额外的开销,这阻碍了实现一个高性能、资源集约、快速响应的服务器无感知云。首先,现有的每个函数都有一个专门的sidecar代理,函数间调用也都会经过额外的组件broker,这方便了服务器无感知计算的网络和调度,但是这些组件会带来额外的开销。例如函数服务每个请求时,会引入额外的数据拷贝、上下文切换和中断处理开销。其次,sidecar代理和网关等组件是长时运行的独立组件,相比于事件驱动的架构会额外的占用更多资源。最后,目前函数间通信都会为了灵活性使用平台无关的技术,例如HTTP/REST API,这也引入了额外的协议栈处理开销和序列化及反序列化开销。以上种种开销都会造成服务器无感知计算较差的数据平面性能,并有可能影响服务的SLO。
图1:典型的服务器无感知计算函数链涉及的网络处理流程
表1:一个“1前端+2函数”的数据流水线每请求Knative的开销
SPRIGHT系统设计
SPRIGHT总体架构如图二所示。基于Knative和Kubernetes,SPRIGHT控制器控制函数链的放置位置,当用户发送函数链创建请求时,SPRIGHT控制器会指定相应节点的kubelet来创建相应的共享内存管理器和SPRIGHT网关,并按照用户配置创建函数链。当外部请求到达时,Ingress网关会将请求分配到相应的SPRIGHT网关处。对于之后的请求处理部分,SPRIGHT结合事件驱动处理机制和共享内存机制,做了如下三个优化:
1. 基于eBPF的事件驱动代理(EPROCXY和SPROXY):不同于现有的网关和sidecar代理,EPROXY(用于加速网关)和SPROXY(用于加速sidecar)都基于eBPF实现,完全是事件驱动的。因此当没有请求时,它们不产生任何CPU开销。此外,他们完全实现在内核中,避免了额外的内核态-用户态切换。
2. 高效的共享内存处理机制:SPRIGHT SPROXY在函数间通信时触发相应eBPF程序,直接使用共享内存通信,绕过了网络协议栈处理、序列化等冗余过程。对于外来请求,SPRIGHT EPROXY让数据直接从物理网卡转到容器虚拟网络栈,加速iptables处理。
3. 直接函数路由机制:现有的函数之间的调用都需要经过broker这一额外组件进行路由。SPRIGHT实现的直接路由机制则可以直接在内核中让函数链上的函数调用后续函数,并且能够通过eBPF的socket map在用户态进行直接配置。这一机制降低了数据路径的额外跳数。
图2:SPRIGHT总体架构
实验评估
本文在Cloudlab的40核机器上进行了实验。比较对象为不使用服务器无感知框架的gRPC实现、基于Knative的实现、基于DPDK的SPRIGHT(D-SPRIGHT)实现和基于eBPF的SPRIGHT(S-SPRIGHT)实现,实验负载采用了三个有代表性的函数链:在线购物、动作检测和停车计费。
如图三所示,相比于Knative,SPRIGHT吞吐量提升6倍,并且更加稳定。相比于没有sidecar和网关的gRPC实现,SPRIGHT也能实现5倍吞吐提升。
图3:服务在线购物函数链情况下不同实现的RPS比较如图四所示,在高负载情况下,Knative实现会有较高的尾部延迟,SPRIGHT因为使用共享内存进行函数间通信,能够比Knative和gRPC显著降低延时。
图4:服务在线购物函数链情况下不同实现的延时比较此外,本文还比较了不同实现的CPU占用情况,结果显示基于eBPF的SPRIGHT能够显著降低资源占用情况,甚至使得函数处于“温状态”的资源消耗比Knative冷启动开销小。
论文中还包括了SPRIGHT与Knative等实现在服务不同函数链,利用不同策略时的效果,结果都显示SPRIGHT有明显优势。
总结
SPRIGHT提出了基于eBPF的事件驱动组件和共享内存机制,相比于现有的典型开源服务器无感知计算框架能够显著提升吞吐、降低延迟和降低CPU利用率,展现了事件驱动能力在服务器无感知环境下的高效性和共享内存机制的高性能。
背景和动机
服务器无感知计算允许用户将应用逻辑实现为函数,例如实现为一组松耦合的链状函数,即函数链,而云服务提供商负责函数运行和管理底层的操作系统和硬件资源。然而现有的服务器无感知环境引入了较多额外的开销,这阻碍了实现一个高性能、资源集约、快速响应的服务器无感知云。首先,现有的每个函数都有一个专门的sidecar代理,函数间调用也都会经过额外的组件broker,这方便了服务器无感知计算的网络和调度,但是这些组件会带来额外的开销。例如函数服务每个请求时,会引入额外的数据拷贝、上下文切换和中断处理开销。其次,sidecar代理和网关等组件是长时运行的独立组件,相比于事件驱动的架构会额外的占用更多资源。最后,目前函数间通信都会为了灵活性使用平台无关的技术,例如HTTP/REST API,这也引入了额外的协议栈处理开销和序列化及反序列化开销。以上种种开销都会造成服务器无感知计算较差的数据平面性能,并有可能影响服务的SLO。
SPRIGHT系统设计
SPRIGHT总体架构如图二所示。基于Knative和Kubernetes,SPRIGHT控制器控制函数链的放置位置,当用户发送函数链创建请求时,SPRIGHT控制器会指定相应节点的kubelet来创建相应的共享内存管理器和SPRIGHT网关,并按照用户配置创建函数链。当外部请求到达时,Ingress网关会将请求分配到相应的SPRIGHT网关处。对于之后的请求处理部分,SPRIGHT结合事件驱动处理机制和共享内存机制,做了如下三个优化:
1. 基于eBPF的事件驱动代理(EPROCXY和SPROXY):不同于现有的网关和sidecar代理,EPROXY(用于加速网关)和SPROXY(用于加速sidecar)都基于eBPF实现,完全是事件驱动的。因此当没有请求时,它们不产生任何CPU开销。此外,他们完全实现在内核中,避免了额外的内核态-用户态切换。
2. 高效的共享内存处理机制:SPRIGHT SPROXY在函数间通信时触发相应eBPF程序,直接使用共享内存通信,绕过了网络协议栈处理、序列化等冗余过程。对于外来请求,SPRIGHT EPROXY让数据直接从物理网卡转到容器虚拟网络栈,加速iptables处理。
3. 直接函数路由机制:现有的函数之间的调用都需要经过broker这一额外组件进行路由。SPRIGHT实现的直接路由机制则可以直接在内核中让函数链上的函数调用后续函数,并且能够通过eBPF的socket map在用户态进行直接配置。这一机制降低了数据路径的额外跳数。
实验评估
本文在Cloudlab的40核机器上进行了实验。比较对象为不使用服务器无感知框架的gRPC实现、基于Knative的实现、基于DPDK的SPRIGHT(D-SPRIGHT)实现和基于eBPF的SPRIGHT(S-SPRIGHT)实现,实验负载采用了三个有代表性的函数链:在线购物、动作检测和停车计费。
如图三所示,相比于Knative,SPRIGHT吞吐量提升6倍,并且更加稳定。相比于没有sidecar和网关的gRPC实现,SPRIGHT也能实现5倍吞吐提升。
论文中还包括了SPRIGHT与Knative等实现在服务不同函数链,利用不同策略时的效果,结果都显示SPRIGHT有明显优势。
总结
SPRIGHT提出了基于eBPF的事件驱动组件和共享内存机制,相比于现有的典型开源服务器无感知计算框架能够显著提升吞吐、降低延迟和降低CPU利用率,展现了事件驱动能力在服务器无感知环境下的高效性和共享内存机制的高性能。