NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

京东数科统一接入网关 JDDLB 性能优化之 QAT 加速卡

  • 2021-01-11
  • 本文字数:4543 字

    阅读完需:约 15 分钟

京东数科统一接入网关JDDLB性能优化之QAT加速卡

京东数科 JDDLB 作为京东数科最重要的公网流量入口,承接了很多重要业务的公网流量。目前,已成功接替商业设备 F5 所承载的流量,并在数次 618、11.11 大促中体现出优越的功能、性能优势。


一、京东数科 JDDLB 整体架构



图 1 京东数科 JDDLB 整体架构


JDDLB 整体架构的核心包括:基于 DPDK 自主研发的四层负载 SLB,定制开发扩展功能的 NGINX,以及统一管控运维平台。其主要特点为:


  • 高性能:具备千万级并发和百万级新建能力。

  • 高可用:通过 ECMP、会话同步、健康检查等,提供由负载本身至业务服务器多层次的高可用。

  • 可拓展:支持四层/七层负载集群、业务服务器的横向弹性伸缩、灰度发布。

  • 四层负载能力:通过 ospf 向交换机宣告 vip;支持 ECMP、session 同步;支持均衡算法如轮询、加权轮询、加权最小连接数、优先级、一致性哈希;FullNAT 转发模式方便部署等。

  • 七层负载能力:支持基于域名和 URL 的转发规则配置;支持均衡算法如轮询、基于源 IP 哈希、基于 cookie 等。

  • SSL/TLS 能力:证书、私钥、握手策略的管理配置;支持 SNI 配置;支持基于多种加速卡的 SSL 卸载硬件加速等。

  • 流量防控:提供一定的 Syn-Flood 防护能力;与应用防火墙结合后提供 WAF 防护能力;提供网络流量控制手段如 Qos 流控、ACL 访问控制等。

  • 管控平台:支持多种维度的网络和业务指标监控和告警。


此外,借助于 JDDLB 现有能力特性,方便扩展其他新功能。例如,借助于 NGINX 的 SSL/TLS 硬件优化性能以及连接高并发处理能力,可以实现基于 MQTT 协议的、支持 SSL/TLS 协议、安全的推送长连接网关等。


本文针对 JDDLB 中七层负载的 SSL/TLS 性能优化方法之一——将耗 CPU 计算资源的加解密算法计算卸载到 QAT 加速卡——进行概述性介绍。


二、优化方案性能提升对比

1、测试方法


执行机部署适配 QAT 引擎后的 nginx,发包测试机进行压测灌包,在 CPU 负载达到 100%后比较得出 nginx 在进行 QAT 优化后的新建 connection 速率对比。


2、测试场景


3、本地测试数据对比


▷ 使用单张加速卡性能对比



▷ 使用双加速卡性能对比



此优化方案,通过 NGINX 进行 HTTPS 新建速率实测,与软件加解密场景做对比:


  • 使用单加速卡,rsa 平均新建速率提升 3 倍,ecdh 新建速率提升 2.5 倍

  • 使用双加速卡:rsa 平均新建速率提升 6 倍,ecdh 新建速率提升 5.5 倍


此优化方案所带来的性能提升主要依赖于:


  • 对比 fsl 加速卡、qat 采用用户态驱动的方式,实现了内核态到用户态到内存零拷贝。

  • NGINX 采用异步模式调用 OpenSSL API,代替传统的同步模式调用。

  • 驱动支持多加速卡同时进行卸载加速。


三、硬件加解密异步处理

1、异步框架概述


JDD-LB 基于 nginx 原生的异步处理框架上拓展出针对异步硬件引擎的异步事件处理机制,整体框架如下图所示:



硬件加解密的异步框架整体依赖 nginx 的 epoll 异步框架处理机制和 openssl 协程机制。原生的 nginx epoll 框架负责网络 I/O 的异步事件处理,在此基础上 jdd-lb 重新增加了 async fd 异步监听任务,在原有的连接结构体中增加新的异步来源用来接收异步引擎的通知,当执行 OpenSSL 相关操作时,把返回的事件 fd 加载到 jdd-lb 的异步事件框架中,openssl 当检测到硬件执行完相关操作后就会唤醒相关事件进行后续操作的执行。


关于协程的详细介绍可以参考《UAG性能优化之freescale加速卡》,里面有关于协程实现的基本语义、切换机制等详细介绍,这里不在赘述,总而言之,openssl 协程机制实现在线程内的多个任务切换管理。


这里涉及到两个问题:


  • 异步任务的上下文切换以及通知机制;

  • Nginx 如何获取 async fd,并加入 epoll 监听队列中,并与 openssl 以及 qat engine 协同完成一次 ssl 握手的;


2、交互流程


以 ssl 握手为例,nginx、openssl、qat 引擎各个模块之间的交互流程如下图所示:



  • ASYNC_start_job:nginx 调用 ssl lib 库接口 SSL_do_handshake, 开启一个异步任务。

  • Rsa/ecdh 加解密操作。

  • Qat 引擎将加密消息发送给驱动,创建异步事件监听 fd,将 fd 绑定到异步任务的上下文中。

  • qat_pause_job: 调用该接口保存异步任务执行的堆栈信息,任务暂时被挂起,等待硬件加解密操作完成。同时进程堆栈切换到 nginx io 调用主流程,ssl 返回 WANT_ASYNC,nginx 开始处理其他等待时间。

  • nginx io 处理框架获取保存在异步任务上下文中的 asyncfd,并添加到 epoll 队列中启动监听。

  • 加速卡处理任务完成,qat 引擎调用 qat_wake_job 接口唤醒任务(也就是将 async fd 标记为可读),这里有一个问题,这个 qat_wake_job 是什么触发执行的?qat 为 nginx 提供了多种轮训方式去轮训加速卡响应队列,目前 jdd-lb 采用的是启发式轮训的方式,具体参数可以在配置文件中定义。

  • Nginx 处理异步事件重新调用异步任务框架的 ASYNC_start_job 接口,这时候程序切换上下文,堆栈执行后跳回之前 pase job 的地方。


四、用户态驱动实现内存零拷贝


区别于上期我们介绍的freescale加速卡方案、qat 采用用户态驱动的实现方式,利用 linux uio+mmap 技术实现了内存零拷贝。接下来介绍 qat 实现内存零拷贝的基本原理。


在弄清楚这个问题前,我们先介绍一下 uio 技术的基本原理,简而言之:UIO(Userspace I/O)是运行在用户空间的 I/O 技术,Linux 系统中的驱动设备一般都是运行在内核空间,UIO 则是将驱动的很少一部分运行在内核空间,而在用户空间实现驱动的绝大多数功能。



工作原理图


我们先明确一个用户态程序如何操作一个 pci 设备?首先需要找到它的寄存器并对其进行配置,而找到寄存器的前提是拿到外设的基地址,即:通过“基地址+寄存器偏移” 就能找到寄存器所在的地址,然后就可以配置了。


综上,qat 的内核模块可以分为两块基本内容:


(1)PCI 设备驱动,获取 pci 设备的配置空间信息,申请内核资源;也就是拿到加速卡的基址寄存器地址,映射设备的地址空间。


(2)注册 UIO 设备,实现用户态驱动的主要功能:映射寄存器地址到用户空间,在内核态屏蔽设备中断;


利用 UIO 框架实现将设备的寄存器地址映射至用户空间后,QAT 还需要完成用户态进程与硬件之间消息传递。QAT 中消息队列的创建是在进程运行时创建,同样利用 mmap 原理将一段物理地址映射至用户态进程,为了避免内核在运行过程中出现内存碎片导致性能下降,QAT 新增了 usdm 内核模块用于管理和维护页表。


如下图所示,显示了 QAT 如何将设备地址及消息队列映射到用户空间:



综上所示,QAT 通过 UIO+ mmap 的方式实现了内核态到用户态到内存零拷贝,相比于 freescale 和 cavium 等其他加速卡厂商,QAT 在这一方面存在着一定优势。


关于内存映射的问题,jdd-lb nginx 多进程之间必须要保证物理地址的对齐偏移量一致,jdd-lb 在实际部署和上线过程中遇到过类似问题:


  • 现象描述


装载 qat 加速卡机器出现宕机,我们抓取宕机的 crash 日志,如下图:



系统挂之前操作消息队列(send_null_msg),内核被踩了,另外,在挂之前截图内核日志,发现大量内存申请失败的信息:


  • 原因分析


基于以上现象分析,机器挂之前的主要行为:1、nginx 正在频繁 reload;2、预分配的大页内存池不够了,新起的 worker 进程采用 ioctl 的方式从内核申请 2m 页,也就是我们在修复问题二之前采取的内存分配方式,这点可以从内核日志中分配内存失败的打印推断出来,因为只有通过 ioctl 方式申请才会出现 userMemAlloc failed 的打印。3、worker 退出前访问了消息队列,这个是导致宕机的直接原因。


总结一下三条行为的因果关系,频繁 reload > 老的 worker 还没彻底 shutdown,新的 worker 已经起来了, 同一时间出现大量 nginx > 预分配的大页内存池被占满 > 新的 worker 采用 ioctl 的方式去申请> 有个 worker 释放时访问消息队列 > 机器挂了。


根据以上分析,在机器挂之前 nginx 的 worker 进程是同时存在两种内存分配方式,但是 qat 是同时支持两种内存分配方式的,如果 ioctl 方式申请内存失败最多出现 nginx qat 加速卡卡降级,在问题二中已经说明了,并不会出现宕机的行为,难道是两种方式不能共存?


  • 问题验证


带着上述疑问,采取人为手段在测试环境复现该场景,先是继续在 nginx 拉起前人为的消耗完 2m 页,在 nginxworker 代码中加入调试控制,shutting down 之前 sleep100 秒(测试环境下 nginx shutdown 的速度非常快,并不能完全模拟线上环境的场景),然后运行一个 nginx 不断 reload 的脚本,最后,线上环境的问题在测试环境复现,crash 的日志与线上环境一致。


问题到这一步,只能说明两种内存分配方式共存的场景下,nginx 释放消息队列时会引起宕机,同样的测试场景,如果只采用一种内存分配的方式申请,都不会出现宕机。总之,知其然不知其所以然。然后经过阅读源代码加点日志分析判断,最终找到点眉目,下面放结论。


usdm 内核模块会维护物理地址和虚拟地址的映射关系,进程在释放队列后会去操作加速卡的 CSRs,而这个物理地址是通过创建的消息队列的物理地址偏移后计算出来的,虽然两种内存申请方式按 2m 的大小申请的,但是通过大页内存的方式申请的物理页是按 2m 的大小保存的,而通过 ioctl 方式申请的物理页是按照 4k 大小保存的,因此,如果通过同时存在两种内存分配方式的话,计算得到的 CSR 的物理地址就不一致了。画个图说明一下:


五、进程级别的加速引擎调度


QAT 的引擎启动主要完成 3 个步骤:


(1)完成应用程序注册:打开字符串设备/dev/qat_dev_processs,将 app 配置信息写入驱动,App 的信息必须与驱动配置中定义的配置块一致,也就是/etc/dh895xcc_dev0.conf 这个配置文件中的配置信息。


(2)完成服务的注册(qat 支持 cy 和 dc 两种服务),并完成加速卡硬件相关资源的初始化操作。


(3)获取服务实例,这里的 instances 可以理解为应用程序与加速卡相互通信的通道,实际上就是与底层的加速卡和消息队列建立绑定关系。所以 8950 加速卡最多支持 128 个 instance(考虑硬件队列最多就 256 个)。


需要说明的是:qat 的 instance 资源是进程级别,那么每个 worker 在启动之前都会调用 qat_engine_init 函数,qat 用了一个钩子使得 master 进程在 fork 之后子进程调用 qat_engine_init 函数,同时在 fork 之前释放引擎(master 本身不需要引擎资源),流程如下图所示:



六、QAT 组件框架概览



  • Application


应用层主要包含两块内容:(1)qat 异步框架的 patch,该 patch 提供对异步模式的支持;(2)qat 引擎,engine 是 openssl 本身支持的一种机制,用以抽象各种加密算法的实现方式,intel 提供了 qat 引擎的开源代码用以专门支持 qat 加速。


  • SAL(service access layer)


服务接入层,给上层 Application 提供加速卡接入服务,目前 qat 主要提供 crypto 和 compression 两种服务,每一种服务都相互独立,接入层封装了一系列实用的接口,包括创建实例,初始化消息队列、发送\接受请求等。


  • ADF(acceleration driver framework)


加速卡驱动框架,提供 SAL 需要的驱动支持,如上图,包括 intel_qat.ko、8950pci 驱动、usdm 内存管理驱动等。


七、总结与思考


截止目前,JDD-LB 在硬件加速领域,已经同时支持飞思卡尔与 intel QAT 硬件方案,为有效替代 f5 提供了性能保证,成功实现核心网络组件自主可控,为构建金融级的网关架构赋能行业打下坚实的基础。


未来 JDD-LB 将持续构建接入层网关能力体系。


  • 安全与合规


作为京东数科统一流量接入入口,JDD-LB 将持续构建金融级的通信安全基础设施,打造全方位的安全防护体系。


  • 多协议支持


JDD-LB 在高效接入能力建设方面将持续投入,通过引入 QUIC 协议,将提升用户在弱网场景下的用户支付体验。


通过 MQTT 协议可以通过非常小的接入成本实现新设备和协议接入,积极拥抱万物互联。


文章转载自: 京东数科技术说(ID:JDDTechTalk)

原文链接:京东数科统一接入网关JDDLB性能优化之QAT加速卡

2021-01-11 08:002026

评论

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

SQLSmith: Databend 如何利用随机化测试检测 Bug

Databend

Mac可用的流程图和图形设计软件OmniGraffle Pro 7

展初云

Mac 流程图绘制工具

云教室如何部署?云教室使用教程

青椒云云电脑

云教室 云教室厂商

StarRocks 荣获 InfoWorld 2023 年最佳开源软件

StarRocks

app游戏定制开发【 小游戏定制开发】

V\TG【ch3nguang】

教育培训行业APP软件定制开发

V\TG【ch3nguang】

Mac系统清理和优化软件 CleanMyMac X

展初云

CleanMyMac X Mac软件 系统优化工具

EMQ 获第八届 “创客中国” 物联网中小企业创新创业大赛一等奖

新消费日报

如何平衡表单设计过程中用户体验与企业管控需求(上)

用友BIP

财务共享

国内有哪些做的比较好的云教室厂商?

青椒云云电脑

云教室 云教室厂商 云教室解决方案

Kubernetes跨StorageClass迁移,切换Rainbond默认SC

北京好雨科技有限公司

云原生 #Kubernetes# 企业号10月PK榜

产研团队必看!3款在线白板工具助你轻松改善工作!

彭宏豪95

产品经理 科技 产品研发 在线白板 效率软件

Dapp开发,让你掌握区块链技术-dapp开发团队

V\TG【ch3nguang】

软件开发全文档整理(获取原件)

金陵老街

项目管理 软件文档

Mac可用的GTD任务管理软件Omnifocus Pro 3

展初云

Mac软件 任务管理软件 GTD

关于亚马逊 CodeWhisperer 的测试反馈

亚马逊云科技 (Amazon Web Services)

#人工智能 云上探索实验室 Amazon CodeWhisperer

区块链DAPP开发技术方案,开启你的区块链时代

V\TG【ch3nguang】

🎊OpenTiny Vue 3.11.0 发布:增加富文本、ColorPicker等4个新组件,迎来了贡献者大爆发!

Kagol

Mac电脑专业批量文件重命名 MetaRename中文激活版

胖墩儿不胖y

Mac软件 重命名工具 重命名软件

Kafka 在分布式系统中的 7 大应用场景

越长大越悲伤

Java kafka

Python 继承和子类示例:从 Person 到 Student 的演示

小万哥

Python 程序员 软件 后端 开发

为何 DevOps 会给开发人员带来压力和倦怠?

SEAL安全

DevOps 策略 企业号10月PK榜 缺点

Linux ls命令:查看目录下文件

智趣匠

Redis 7.0 源码调试环境搭建与阅读技巧

码哥字节

redis redis 底层原理

你知道ping命令是如何工作的吗?

百度搜索:蓝易云

Linux 运维 ping ICMP Internet

数科公司新动向,借助外部力量寻求增长突破

用友BIP

数科公司

3DCAT+东风日产:共建线上个性化订车实时云渲染方案

3DCAT实时渲染

汽车虚拟仿真 汽车3D可视化

自定义过滤器配置 Shiro 认证失败返回 json 数据

emanjusaka

Java shiro

如何选择向量数据库|Weaviate Cloud v.s. Zilliz Cloud

Zilliz

非结构化数据 Zilliz 向量数据库 zillizcloud

跨语言高性能 RPC 框架 Focus 架构解析

dinstone

RPC 高性能 跨语言 focus

提升网站性能:Nginx五种高效负载均衡策略

百度搜索:蓝易云

nginx 云计算 Linux 运维 Web

京东数科统一接入网关JDDLB性能优化之QAT加速卡_语言 & 开发_京东数科_InfoQ精选文章