Intel QAT 助力Nginx压缩处理

什么是Intel® QAT?

Intel® QuickAssist Technology是Intel®公司提供的一种高性能数据安全和压缩的加速方案。该方案利用QAT芯片分担对称/非对称加密计算,DEFLATE无损压缩等大计算量的任务,来降低CPU使用率并提高整体平台性能。该方案可以主板芯片,独立的PCI-E加速卡或者SOC三种方式部署。

QAT支持硬件加速Deflate无损压缩算法,在处理海量数据时,QAT在不增加CPU开销的前提下,通过压缩来减少需要传输和存盘的数据量,从而减少了网络带宽和磁盘读写的开销,最终提高了整体的系统性能。 例如,在Web Serer上使用QAT硬件加速压缩处理,可将CPU从繁重的压缩计算中解放出来,以处理更多的连接请求。

什么是Nginx Web Server

Nginx(发音同engine x)是一款使用异步框架的高性能Web服务器,相较于Apache、lighttpd等其他Web Server,Nginx具有占有内存少,稳定性高等优势。根据Netcraft 2018年一月的Web Server市场调查报告, Nginx的装机率达25.39%,位列Web Server市场第三,并在持续增长中[1]。

Nginx中的GZIP模块实现了对HTTP压缩的支持,该模块通过调用Zlib库实现对网页内容进行Deflate压缩。由于使用软件实现无损压缩,需要消耗大量CPU运算时间进行压缩运算。

然而,在大并发流量的网站接入层的Nginx需要处理相当多的业务,包括https连接建立,安防攻击,流量镜像,链路追踪等等。使得CPU进行HTTP压缩处理成为Web Server最主要的CPU开销,进而限制了网站支持最大并发连接数。根据客户提供的接入层流量模型分析来看, GZIP 单个模块 CPU 消耗占比达到 15%-20% 左右,且占比呈上升趋势。所以,若能使用加速Nginx的网页压缩处理,可以极大的提高网站性能。

Zlib-SHIM API

Zlib作为广泛部署的软件压缩库,提供Deflate压缩的软件实现,被包括Nginx在内的广大应用程序所采用。Intel® QuickAssist Technology提供了与Zlib类似接口的Zlib-SHIM 软件库来适配上层应用,减少了应用迁移的开发量。该库提供了与Zlib一致的Deflate API,只需对源代码做少量修改,并将原有应用与Zlib-SHIM编译链接,就能使用QuickAssit提供的硬件加速功能。

Zlib-SHIM库实现了DeflateInit,DeflateInit2,Deflate,DeflateEnd等常用API并支持Stateful和Stateless压缩,可以替代Zlib的绝大部分功能。

Zlib-SHIM提供了Deflate API同步模式接口(调用程序阻塞在Deflate API上,直到压缩任务完成),而其内部实现调用了异步模式API,即在CPU上运行的QAT驱动程序向QAT协处理器提交了一个数据压缩请求后即返回,期间使用Polling 接口定期检查压缩请求是否完成,等到QAT硬件完成压缩处理后通过回调函数通知CPU端的应用程序进行下一步操作。这样的设计, 在不影响上层应用程序原有设计的前提下,实现了高并发场景中CPU和QAT的协同工作:CPU专注于网络链接处理而QAT处理复杂的压缩计算, 各司其职,最终提高了系统整体性能。

Zlib-SHIM 层次图

Zlib-SHIM工作原理

采用这种异步模式API实现对外的同步接口,在实现上有三种方法:Direct Polling,Indirect Polling Spinning和Indirect Polling Semaphore模式。

使用Direct Polling模式时,Deflate调用者会在当前线程直接调用Polling接口,若压缩结果还没有返回则休眠一段时间后再检查,直到压缩成功后Deflate 调用才返回。Direct Polling模式下CPU开销小,但是单个Request从发出到返回结果延迟较长,只有在多进程多线程高并发模式下才能充分发挥QAT的压缩性能。

Direct polling 模式流程图

Indirect Polling模式,是通过创建一个轮询线程定期调用Polling接口来检查压缩请求在QAT 协处理器中的执行状态,轮询线程一旦发现有请求执行完毕就通过回调函数(Callback Function)通知CPU端程序进行后续处理。

Indirect pooling模式时序图

根据回调通知方式的不同,Indirect Polling模式又可细分为Spinning模式和Semaphore模式:

Spinning模式中,Deflate函数调用线程定期轮询与回调函数共享的任务完成标志,若尚未完成则主动休眠,若已完成则进行后续处理。

Semaphore模式中,Deflate调用线程通过互斥锁来隔离与轮询线程共享的任务完成标志的访问操作,若任务尚未完成则Deflate调用线程休眠,一旦任务完成,轮询线程中的回调函数会通过信号量唤醒调用线程进行后续处理。

采用Indirect Polling模式无论Deflate调用数目多少都需要启动轮询线程,在压缩请求数不大的情况下增加了CPU的Polling开销,但是当压缩任务作为CPU的主要任务时可以减少不必要的Polling调用,提高CPU的使用率。

Nginx为了实现高性能的高并发处理能采用了单进程单线程异步工作模式,如果使用Indirect Polling模式,就需要在每个Nginx Worker进程中创建一个轮询线程 (Polling Thread), 从而增加了线程间切换的开销和共享数据的互斥的操作, 所以在Nginx和Zlib-SHIM集成中,我们使用了Direct Polling Mode。

USDM优化

USDM是QAT为了优化内存使用效率而提供的用户态内存管理工具。由于QAT和CPU之前需要频繁高速的交换数据,使用传统的Memory Copy方式不仅效率低而且消耗CPU资源,所以QAT支持DMA方式进行数据传输,CPU只需分配好拥有物理连续内存的输入地址和输出地址,QAT会自动完成的从该地址的输入读取或输出写回的操作。QAT Driver中的USDM模块,利用了Linux 内核提供的Huge-Page特性来获得物理地址连续内存并使用SLAB算法进行内存管理。

对于每一个新分配的Huge-Page,USDM会对应地在Devfs中新建一个临时文件,并通过mmap将临时文件描述符与新申请到的Huge-Page关联上,当USDM发现该Huge-Page上所有内存块均已释放,并不需将其留作缓存时,就关闭该临时文件以释放Huge-Page。当Zlib-SHIM运行过程中需要使用连续的内存时,就使用USDM Alloc接口从内存池中申请连续物理地址的内存, 并在发送压缩请求时将申请到的连续内存地址作为参数传递给QAT。

USDM DMA传输

测试结果

基于以上设计的Zlib-SHIM可以很方便的替换原有Zlib库,使得调用者可以方便的利用QAT进行压缩加速。 在实际应用中, 客户就是将Zlib-SHIM与基于Nginx定制的Web Server进行集成,在接入层的性能优化上取得了理想的效果。

客户的Web Server运行在Intel® Xeon® CPU上(CPU型号:Intel® Xeon® CPU E5-2650 v2 @ 2.60GHz 32核 内核:2.6.32 Zlib版本:zlib-1.2.8 QAT驱动版本:intel-qatOOT40052 ),在相同网络流量条件下,未开启QAT加速的CPU平均使用率为48%左右,而开启QAT加速后CPU平均使用率为41%左右。

CPU使用率对比[2]

相同条件下,开启QAT加速后系统load平均值为12.09,关闭QAT加速时系统load平均值为14.22,如下图所示:
系统load对比[2]

综合以上数据,Web Server在QPS 10K的压力下,使用QAT加速后可以节省CPU 15%左右,且Gzip基本上完全卸载、随着其占比变高,优化效果将越好。

总结

拥有和Zlib相同API接口的Zlib-SHIM可以很方便的与上层应用集成,利用QAT的硬件加速性能。此外,为了最大限度的发挥QAT的新能,Intel还提供了使用专有API的QATzip软件库,相应的Nginx module也在开发中,相信不久的将来集成QATzip的Web Server能够提供更好的性能。

*性能测试中使用的软件和工作负荷可能仅在英特尔微处理器上进行了性能优化。诸如SYSmark和MobileMark等测试均系基于特定计算机系统、硬件、软件、操作系统及功能。上述任何要素的变动都有可能导致测试结果的变化。请参考其他信息及性能测试(包括结合其他产品使用时的运行性能)以对目标产品进行全面评估。

参考文献

[1] January 2018 Web Server Survey, netcraft
[2] 后摩尔时代,如何给你的CPU减负

原文地址:英特尔中国

发表评论

电子邮件地址不会被公开。 必填项已用*标注