• 在SPDK中使能E810网卡ADQ特性


    在SPDK中使能E810网卡ADQ 特性

    --改善TCP/IP 存储应用的性能

    最近Intel发布了最新的100Gbps的以太网网卡控制器E810, 这款新的网卡不仅支持两种不同协议的RDMA 协议(iWARP 和RoCE v2),并且针对基于TCP/IP协议的应用(包括各种使用网络的应用)给出了基于ADQ(Application Device Queues)特性的性能改善方案,可用于改善网络应用的性能(诸如平均或者长尾延迟,以及throughput等)。

    ADQ简介

    Intel 网卡中的ADQ特性是一种智能的系统级方法,旨在提高网络I/O性能。ADQ特性的目标是确保高优先级应用程序具有可预期的高性能,并显著降低抖动。ADQ的核心技术是将隔离的硬件网卡队列供某些应用程序进行专有使用。并且希望这些硬件网卡队列可以最佳地连接到所需应用程序中的不同线程。显而易见, 这种方法可以防止专有程序的网络流量与其他应用程序竞争,并且该应用程序的性能(例如,延迟)可以变得可预测。此外开启ADQ特性以后,我们仍然可以对专有应用程序在队列上提供QoS控制。

    图1 Without ADQ那部分的图,给出了不使用ADQ的例子(也就是正常网卡的包处理)。如果把图中不同颜色的汽车看成不同的应用,不同的车道看成不同的网卡队列,我们可以看到同一个网卡队列上可以同时处理不同应用的网络包。这样的处理方法是通用的,但是不利于某些专有应用的QoS 控制。图1中使用了ADQ以后,我们可以看到某些网络队列可以直接分配给某些专有应用,于是这些应用的网络包可以在特定分配的队列上被处理,和其他应用程序隔离,继而可以进行后续的QoS控制。

    图1 ADQ特性的开启以及关闭

    总结一下ADQ隔离队列的思想,和DPDK/SPDK PMD的思想有些相似。基于DPDK的application可以去操纵分配给这个应用的物理队列,这一点来讲和ADQ的思想是完全相同的。唯一的区别是目前DPDK只工作在层3以下,所以工作在TCP/IP层的应用想要通过DPDK PMD驱动来享受到隔离队列的特性,必须使用基于DPDK的用户态TCP/IP栈。所以从这一点看来,ADQ的特性通用性更好一些,不需要应用强制使用用户态的解决方案。

    另外我们可以看到ADQ的特性,对于多核应用的支持还存在需要加强的地方。因为使用ADQ以后,我们可以分配一些特定的队列给应用。比如给一个应用程序A分配4个队列,这个可以保证应用程序对这4个队列的独享 。但是如果这个应用是使用多CPU的,那么这个应用的多个线程(可能运行在不同的CPU core上)形成对这4个队列的内部竞争。我们在SPDK库中的集成工作,就是为了避免内部竞争的出现。

    SPDK应用使用ADQ的使用示例

    为了更好地解释SPDK库中ADQ的集成, 图2给出了SPDK NVMe-oF TCP应用使用ADQ的例子。首先在SPDK NVMe-oF TCP应用启动之前,需要做一些配置工作,诸如分配一些网卡队列,对应到不同的TC (traffic class)。于是监听在以下三元组的的套接字(如图2 Socket init module中的绿色描述,要调用setsockopt函数使用SO_PRIORITY 作为OPT_NAME进行设置)。那么这个套接字所接收到的连接都会被分配在预先设置好的队列中。比如我们预先分配了4个队列,那么得到的NAPI_ID在APP的生命周期中,只会存在4个不同的值,比如789,790, 791和792。很显然我们可以通过getsockopt,传入SO_INCOMING_NAPI_ID作为OPT_NAME进行NAPI_ID的获取。那么在NVMe-oF层的accepter logic模块,对于新接收的连接位于哪个物理队列上了如指掌。那么就可以利用NAPI_ID的信息,把具有相同NAPI_ID的连接交于同一个NVMe-oF的polling group进行处理,从而可以最优地利用ADQ特性。

    图2 SPDK NVMe-oF集成ADQ的特性

    SPDK socket library中的支持

    为了实现图2中的使用需求,在SPDK SOCK库中,我们做了以下的工作,使得使用SPDK库的应用诸如NVMe-over TCP target可以更好地使用分配的队列。

    在SPDK 的thread 设计中,每一个SPDK thread都可以使用一个polling group。这个polling group中可以处理所有归属于这个polling group处理的连接。比如在NVMe-oF target (app/nvmf/nvmf_tgt)以及相关的库(module/event/subsystems/nvmf/, lib/nvmf)实现中, 当NVMe-oF target启动以后,每个Reactor线程上启动一个NVMe-oF的SPDK thread,然后这个SPDK thread上会运行一个polling group。这个polling group可以处理不同transport上的polling group,诸如RDMA,TCP或者Fibre Channel上的各个polling group的连接。

    所以在没有使用ADQ之前, 每一个SPDK thread上的TCP polling group处理的TCP连接,可能位于不同的队列上。而使用ADQ之后,处理的TCP连接可能分布在有限的几个队列上。举个例子,如果SPDK的NVMe-oF TCP应用使用了两个CPU core,被分配了4个队列。那么每个CPU core上运行的sock polling group能处理到4个不同的队列。那么这两个CPU对于网卡队列还是存在竞争关系。原则上,我们需要让不同的CPU core去处理不同的队列,才是效率最高的。也就是说, 假设一个CPU core i上处理的网卡队列集合是 N(i), 那么任意的CPU之间处理的网卡队列的交集都是空集,也就是:For any CPU core i and j, N(i) ∩ N(j) = ∅ 。

    为了满足这一实现,我们在SPDK的sock library中,维护了placement_id(网卡队列的NAPI_ID在SPDK sock库中被抽象为placement_id)到sock polling group的映射, i.e., 。另外我们提供了spdk_sock_get_optimal_sock_group这个调用,可以针对一个spdk socket,去寻找最佳的polling group。这个其实就是利用这个mapping关系。因为每一个SPDK socket都可以得到一个placement_id。如果得到的placement_id不是有效的,则认为ADQ特性没有被开启,那么就不会得到一个被优化的polling group;如果得到的placement_id是有效的,我们就去寻找是否存在这个这个placement_id所对应的polling group。然后这个sock polling group的信息会被上层逻辑(诸如nvmf层)使用。

    如果在nvmf层的逻辑中,通过查询spdk_sock_get_optimal_sock_group得到无效的sock_polling_group,就会采用默认的算法, 比如使用Roundrobin的算法(如图2所示)进行调度,寻找一个SPDK thread;如果发现了有效的sock_polling_group,我们就会找寻这个sock_polling_group的创建者(意思是由哪个SPDK thread创建),然后交由这个SPDK thread处理。无论哪种方式,我们最终都会到一个SPDK thread去处理这个连接,最后我们将会更新这个placement_id和对应的sock_polling_group的映射信息。此外, 在一个socket被一个polling group移除的时候,我们也要对placement_id和sock_polling_group相应的映射进行维护。

    性能数据分享

    图3给出了同样硬件环境下,服务器端的SPDK NVMe-oF TCP target程序使用ADQ特性后的性能变化。我们可以看到在使用ADQ以后,可以更高效地利用CPU资源, 比如SPDK NVMe-oF TCP target使用5个CPU core,就基本可以达到E810网卡的line rate。如果不开启,那么可能需要使用6-7个CPU core。并且在1-5个CPU core的配置下,在ADQ模式和非ADQ模式下运行同样的工作负载,ADQ模式可以提升IOPS以及降低延迟。图4给出了同样测试下,长尾延迟(p99, p999以及p9999)的改善。我们可以看出使用了ADQ特性以后,NVMe-oF TCP target应用的可预测性有了很大的改善,也就是延迟的普遍降低趋势。

    图3 SPDK NVMe-oF TCP性能

    图4 长尾延迟的改善

    总结

    这篇文章中主要介绍在通过SPDK SOCK库中怎样透明的向上层模块暴露出Intel E810网卡的ADQ(Application Device Queue)的特性。一旦系统开启ADQ的支持,基于TCP/IP的服务器端存储应用可以得到很好的性能提升,比如IOPS的提升以及延迟的降低。

    学习地址:http://ke.qq.com/course/5066203?flowToken=1043717

    更多DPDK学习资料有需要的可以自行添加进入学习交流君 羊 793599096 免费获取,或自行报名学习,免费订阅,永久学习,关注我持续更新哦!!!

    原文链接:https://blog.csdn.net/weixin_37097605/article/details/109349046

  • 相关阅读:
    Matlab数据导入代码(importdata函数允许加载不同格式的各种数据文件)
    Linux操作系统——线程概念
    php使用sqlServer
    ABB机器人如何在自动运行中修改目标点位的坐标数据?
    京东API接口带你了解京东工业|电商及供应链服务
    基于SpringBoot的校园志愿者管理系统
    责任链模式
    SpringBoot使用kafka事务-消费者方
    鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统
    day6_C++
  • 原文地址:https://blog.csdn.net/lingshengxiyou/article/details/126730325