提升TLS性能的利器:QAT加速引擎

文章转载自DPDK与SPDK开源社区

什么是异步模式

异步是一个重要且应用广泛的思想。现代很多高级语言比如python, .NET和Node.js等都支持异步编程,许多应用程序库比如Glib都提供了异步接口来处理一些特定的场景。许多应用程序特别是web服务器软件如nginx和Lighttpd,为了提高并发连接数充分利用异步思想设计出了事件驱动框架。这一架构在消耗相对很少的系统资源下就能达到所需的性能,而且具有很好的扩展特性满足未来连接数的增长需求。

图1 异步思想
异步通过并行处理减少等待从而提高效率缩短系统整体响应时间且增加整体性能,但是哪些场景是可以应用异步处理思想呢?如果一个任务非常费时且能够在主流程之外单独处理, 那它就是一个可以被异步化的潜在对象,譬如要访问外设比如磁盘,处理外部事件比如来自网络的请求,或者一个需要很大的计算资源的任务比如RSA签名和DH密钥交换。

OpenSSL异步模式

在TLS协议栈中,加解密操作尤其是非对称加解密操作是一个非常耗时的操作,所以它是一个很好的异步化对象。如果能将其异步化处理,势必能够提升效率,这也即将TLS处理异步化的动机。OpenSSL是一个广泛使用的TLS协议栈,它从1.1.0版本开始支持这一操作模式。

OpenSSL对异步模式的实现是基于协程和纤程。协程属于语言构建,应用于Linux平台,由glibc提供;而纤程属于系统构建,应用于Windows平台。它们是比线程还轻量级的执行单元,能协作性地进行上下文切换从而主动地让出系统资源而不需要调度器的参与。这种实现方式通过对堆栈的保存和恢复避免了对同一函数接口的两次调用中相同函数调用堆栈的重复产生和重复释放。

OpenSSL用异步任务结构描述和管理这种协程/纤程切换,该结构体与一次TLS异步请求处理有着相同的生命周期。一个TLS处理被设置成异步模式时,一个异步任务结构就会被分配给该连接;当一个协程/纤程放弃系统资源切换出去的时候,该异步任务被暂停,旧函数堆栈信息会被完整地保存在这个结构体里;当协程/纤程切换回来再次执行的时候,该异步任务恢复,函数堆栈会从这个结构体里复原出来;如果这个TLS异步处理请求完整结束,该异步任务结构就会被释放归还。OpenSSL使用事件机制通知异步接口调用者,接口调用者需要监视对应异步任务的文件句柄。

对于应用程序来说,TLS异步模式跟TLS同步模式的编程接口完全一样,只需将一个TLS连接设置为异步模式。但是异步模式定义了一些新的错误码,所以需要对这些新错误码做相应的处理。例如,TLS异步模式引入了一个重要的错误码SSL_ERROR_WANT_ASYNC。它的语义定义跟先前的SSL_ERROR_WANT_READ/WRITE非常类似, 用于通知调用者一个加解密操作已经提交为一个异步请求需要等待异步处理的结果。在调用SSL_do_handshake()和SSL_read()等这类接口时,如果返回SSL_ERROR_WANT_ASYNC,该接口需要在合适的时间再次调用以获得最终的结果。对比同步模式,异步模式需要两次调用该接口:第一次产生异步请求并返回SSL_ERROR_WANT_ASYNC,第二次得到最终结果。

QAT异步引擎

为了实现异步带来的优势,往往需要一个独立执行单元去并行处理异步任务。例如,充分利用多核架构运行一个辅助进程于另一个CPU核。这个进程一般被隐藏起来,在后台独自处理异步任务。除此之外,利用各种协处理等硬件来实现并行处理也是常见的选择,也即卸载操作。

OpenSSL要真正发挥TLS异步模式的优势,一个支持异步模式的OpenSSL引擎是不可或缺的。OpenSSL QAT 引擎是一个全面支持OpenSSL异步模式的的杰出代表,支持异步框架且提供事件机制用于通知异步处理结果。除此以外,该引擎是动态引擎类型支持动态加载。该项目已经开源,源代码可以在这里访问 (https://github.com/intel/QAT_Engine) 。OpenSSL QAT 引擎是基于Intel的QuickAssist技术,该技术提供基于硬件的加解密加速方案,对主流的加解密算法有很好的支持且性能优异。

利用OpenSSL QAT引擎和OpenSSL自带的测试程序,可以从算法级别对比一下异步处理为openssl speed带来的性能提升。数据来自文档Intel(R) QuickAssist Technology and OpenSSL-1.1.0: Performance (参考文档3) 的4.2节。需要指出的是异步性能跟参数异步任务数有很大的关联性,此处异步任务数选择的是36。通过这些数据可以发现异步处理确实极大地提升了加解密操作速度。

TLS异步模式实践之Nginx

OpenSSL提供了TLS异步模式,Intel提供了OpenSSL QAT 引擎,它们一起为在应用程序实现TLS处理异步化提供了必要的基础。此处以nginx为例,探索TLS异步模式对其的性能提升。nginx是异步设计的典范,已经实现了多种异步框架和基础模块,所以它具有天然的优势可以将异步处理延伸到其TLS处理模块。

图2给出了对nginx HTTPS模块进行TLS异步模式适配的设计,它突出了异步事件的产生和处理。类似描述网络端事件的读事件和写事件,专门用于描述加解密硬件事件的异步事件被扩展出来。监听加解密硬件异步处理的文件句柄跟监听网络端连接的句柄一样, 用于某个I/O复用机制(epoll或者poll等)进行异步事件捕捉。nginx的SSL I/O处理模块对SSL_do_handshake()等接口的二次调用也显式标记出来了。

图2 TLS异步模式对nginx HTTPS模块适配的设计图
基于这个设计,Intel已经完成了一个参考实现,源代码可以在此访问 (https://github.com/intel/asynch_mode_nginx) 。利用这个版本我们可以对比TLS异步模式的nginx相对于TLS同步模式的性能提升。数据来自文档Intel(R) QuickAssist Technology and OpenSSL-1.1.0: Performance (参考文档3)的4.5节。通过这些数据可以清楚地看到TLS异步模式对nginx HTTPS模块性能的巨大提升。

图3 RSA-2K 每秒的连接数(NGINX-1.10 + OpenSSL-1.1.0)

图4 ECDHE-RSA-2K 每秒的连接数(NGINX-1.10 + OpenSSL-1.1.0)

结论

TLS异步模式虽然能带来众多好处,但是也会带来一些挑战。首先,产生TLS异步请求并不是免费的。如果涉及到加解密硬件,这个卸载的代价不容小觑,需要评估这个代价对最终性能提升的影响。其次,程序的复杂度会有所提高。如前面所述的支持异步TLS的nginx,当引入了加解密硬件加速后,同时存在加速硬件和网络两个事件源而构成竞争条件。这种情况需要细致地处理以避免异步任务被网络事件意外唤醒。

尽管有种种挑战,从实践来看,TLS异步模式配合QAT加速引擎能够提升TLS的处理性能,是一个优异的TLS优化解决方案。

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

参考文献

1.https://www.slideshare.net/cjgiridhar/asyncprogramming-and-python
2.http://www.openstd.org/jtc1/sc22/wg21/docs/papers/2014/n4024.pdf
3.Linux System Programming, Second Edition, Robert Love, O’Reilly Media, Inc.
4.https://01.org/sites/default/files/downloads/intelr-quickassist-technology/337003-001-intelquickassisttechnologyandopenssl-110.pdf


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。 本站中所有编译类文章仅用于学习和交流目的,编译工作遵照 CC 协议,如果有侵犯到您权益的地方,请及时联系我们。
  • 本文链接https://www.sdnlab.com/21094.html
分享到:
相关文章
条评论

登录后才可以评论

SDNLAB君 发表于18-07-04
2