基于DPDK的高效包处理系统
一、概念
Intel® DPDK全称Intel Data Plane Development Kit,是intel提供的数据平面开发工具集,为Intel architecture(IA)处理器架构下用户空间高效的数据包处理提供库函数和驱动的支持,它不同于Linux系统以通用性设计为目的,而是专注于网络应用中数据包的高性能处理。目前已经验证可以运行在大多数Linux操作系统上。DPDK使用了BSDLicense,极大的方便了企业在其基础上来实现自己的协议栈或者应用。目前出现了很多基于 dpdk 的高性能网络框架,OVS 和 VPP 是常用的数据面框架,mTCP 和 f-stack 是常用的用户态协议栈。
需要强调的是,DPDK应用程序是运行在用户空间上利用自身提供的数据平面库来收发数据包,绕过了Linux内核协议栈对数据包处理过程。Linux内核将DPDK应用程序看作是一个普通的用户态进程,包括它的编译、连接和加载方式和普通程序没有什么两样。如下图2所示DPDK包处理流程绕过了内核直接到用户层进行处理,区别于传统的数据包先到内核最后再到用户层。

图1 传统网络包处理路径 图2 DPDK数据包处理路径
Kni(Kernel NIC Interface)内核网卡接口,是DPDK允许用户态和内核态交换报文的解决方案,例如DPDK的协议栈是专门处理DNS报文,其余的报文通过KNI接口返回给内核来处理。KNI模拟了一个虚拟的网口,提供dpdk的应用程序和linux内核之间通讯。用于DPDK和内核的交互,kni接口允许报文从用户态接收后转发到内核协议栈去。DPDK的包全部在用户空间使用内存池管理,内核空间与用户空间的内存交互不用进行拷贝,只做控制权转移。DPDK的主要对外函数接口都以rte_作为前缀,抽象化函数接口是典型软件设计思路,rte是指runtime environment,eal是指environmentabstraction layer. 下图3是kni的mbuf使用流程图,可以看出报文的流向,因为报文在代码中其实就是一个个内存指针。其中rx_q右边是用户态,左边是内核态。最后通过调用netif_rx()将报文送入linux协议栈,这其中需要将dpdk的mbuf转换成skb_buf。当linux向kni端口发送报文时,调用回调函数kni_net_tx(),然后报文经过转换之后发送到端口上。rte_pktmbut_free()把内存重新释放到mbuf内存池中。

图3 数据包通过KNI的流程
二、DPDK的Helloworld代码示例
HelloWorld是最基础的入门程序,代码简短,功能也不复杂。它建立了一个多核(线程)运行的基础环境,每个线程会打印“hello from core #”,core # 是由操作系统管理的。
int main(int argc, char **argv)
{
int ret;
unsigned lcore_id;
ret = rte_eal_init(argc, argv);
)
rte_panic("Cannot init EAL\n");
/* call lcore_hello() on every slave lcore */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(lcore_hello, NULL, lcore_id);
}
/* call it on master lcore too */
lcore_hello(NULL);
rte_eal_mp_wait_lcore();
;
}
对于HelloWorld这个实例,最需要的参数是“-c <core mask>”,线程掩码(coremask)指定了需要参与运行的线程(核)集合。rte_eal_init本身所完成的工作是复杂的,它读取入口参数,解析并保存作为DPDK运行的系统信息,依赖这些信息,构建一个针对包处理设计的运行环境。主要动作分解为:配置初始化-->内存初始化-->内存池初始化-->队列初始化-->告警初始化-->中断初始化-->PCI初始化-->定时器初始化-->检测内存本地化(NUMA)-->插件初始化-->主线程初始化-->轮询设备初始化-->建立主从线程通道-->将从线程设置在等待模式-->PCI设备的探测与初始化...对于DPDK库的使用者,这些操作已经被EAL封装起来,接口清晰。如果需要对DPDK进行深度定制,二次开发,需要仔细研究内部操作,详见官方网站https://doc.dpdk.org/guides/prog_guide/。
DPDK面向多核设计,程序会试图独占运行在逻辑核(lcore)上。Main函数里重要部分是启动多核运行环境,RTE_LCORE_FOREACH_SLAVE(lcore_id)如名所示,遍历所有EAL指定可以使用的lcore,然后通过rte_eal_remote_launch在每个lcore上,启动被指定的线程。
int rte_eal_remote_launch(int (*f)(void *),
void *arg, unsignedslave_id);
第一个参数是从线程,是被征召的线程,第二个参数是传给从线程的参数,第三个参数是指定的逻辑核,从线程会执行在这个core上。具体来说,int rte_eal_remote_launch(lcore_hello,NULL, lcore_id);参数lcore_id指定了从线程ID,运行入口函数lcore_hello.
运行函数lcore_hello,它读取自己的逻辑核编号(lcore_id), 打印出“hellofrom core #”
static int
lcore_hello(__attribute__((unused)) void *arg)
{
unsigned lcore_id;
lcore_id = rte_lcore_id();
printf("hello from core %u\n", lcore_id);
;
}
以上仅是个简单示例,在真实的DPDK处理场景中,该处理函数会是一个循环运行的处理过程。
DPDK也有自身的劣势,对于低负荷的场景不建议使用DPDK:
- 内核栈转移至用户层增加了开发成本.
- 低负荷服务器不实用,会造成内核空转.
基于DPDK的高效包处理系统的更多相关文章
- 基于DPDK的高效数据包捕获技术分析与应用
被NFV的论文折磨了两天,今天上午看了两篇DPDK的综述. 传统的包捕获机制 1. BPF 两个组成部分:转发部分和过滤部分. 转发部分负责从链路层提取数据包并转发给过滤部分. 过滤部分根据过滤规则, ...
- TRex,一个基于DPDK的数据包发生器,测试仪
1. introduction TRex是cisco基于Intel dpdk开发的软件程序.推荐在CentOS/RHEL 7.6, 64bits中运行,否则connectx-4网卡不可使用. 笔者在U ...
- 26种基于PHP的开源博客系统
26种基于PHP的开源博客系统 来源:本站原创 PHP学习笔记 以下列举的PHP开源Blog系统中,除了我们熟知的WordPress之外,大多都没有使用过,其中一些已经被淘汰,或者有人还在使用.除了做 ...
- 代码片段:基于 JDK 8 time包的时间工具类 TimeUtil
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “知识的工作者必须成为自己时间的首席执行官.” 前言 这次泥瓦匠带来的是一个好玩的基于 JDK ...
- 基于Flume的美团日志收集系统(二)改进和优化
在<基于Flume的美团日志收集系统(一)架构和设计>中,我们详述了基于Flume的美团日志收集系统的架构设计,以及为什么做这样的设计.在本节中,我们将会讲述在实际部署和使用过程中遇到的问 ...
- Factom(公证通)--基于区块链的存证系统
Factom这个Solution在2014年的时候就已经推出了,现在已经2018年了,我才来写这一篇分析文章可能有些迟了,但是它是十分具有参考价值的.因为现阶段来开区块链虽然炒得火热--养猫.养狗.草 ...
- 数据分析:基于Python的自定义文件格式转换系统
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 深度学习与计算机视觉(11)_基于deep learning的快速图像检索系统
深度学习与计算机视觉(11)_基于deep learning的快速图像检索系统 作者:寒小阳 时间:2016年3月. 出处:http://blog.csdn.net/han_xiaoyang/arti ...
- 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统
面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...
随机推荐
- logback.xml例子
我项目中一直使用这样的模板,留档,并纪念. <?xml version="1.0" encoding="UTF-8"?> <configura ...
- JNDI是什么
参考文章:---为什么 追本溯源 http://www.cnblogs.com/xx0405/p/5332198.html jndi在Spring和tomcat下的使用: https://www.cn ...
- 廖雪峰Java9正则表达式-2正则表达式进阶-3分组匹配
1.使用括号可以提取字符串 不加括号匹配电话号码 匹配成功后,如何提取想要的字符串? 使用(...)可以分组:"^(\d{3,4})\-(\d{6,8})$" 2.String.m ...
- linux dd命令 创造一个文件
创造一个1G的文件 dd if=/dev/zero of=/nod/tmp/test bs=1M count=1024 创造一个1T的文件 [root@oracledg tmp]# dd if=/de ...
- Google SketchUp Cookbook: (Chapter 5) Roofs: Constraints and Inferences
软件环境 SketchUp Pro 2018 参考书籍 Google SketchUp Cookbook Creating an Overhanging Roof 屋顶上有一个缝隙需要填充,有两种方法 ...
- 3、谈谈 Java NIO
在 JDK1.4 之后,为了提高 Java IO 的效率,Java 提供了一套 New IO (NIO),之所以称之为 New,原因在于它相对于之前的 IO 类库是新增的.此外,旧的 IO 类库提供的 ...
- sqlserver2008 查看数据库自带的索引建议
SELECT [Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0) , a ...
- 关于如何使用ehcarts2加载svg矢量地图并自定义县级内部乡镇轮廓
项目需求:显示县级内部的乡镇一级地图的轮廓! 效果预览: 阻碍因素:echarts不提供县级以下乡镇级轮廓. 解决思路: 1.根据资料查找相关县的行政区域图(百度搜索),如本人所制作的浙江省宁波市宁海 ...
- 走进HashMap
1.手写实现HashMap 2.解析代码并阐述HashMap1.7到1.8的变化 3.HashMap的遍历方式 4.HashMap与HashSet,Hashtable,ConcurrentHashMa ...
- HTML5+CSS3(3)
一.CSS3新增属性用法整理 1.box-shadow(阴影效果) 2.border-color(为边框设置多种颜色) 3.border-image(图片边框) 4.text-shadow(文本阴影) ...