用户态TCP协议栈

摘要:自从互联网诞生以来,网络协议栈和内核的关系向来很密切,内核作为操作系统的控制者,它会负责很多关键的操作,比如内存资源的分配、网卡资源的分配、数据解析等等,并且随着时间的发展,内核协议栈(关于内核协议栈,可以查看https://blog.csdn.net/LPAINI520/article/details/105970517)的功能、性能和稳定性都一直在提高,而随着互联网技术的发展,网络的瓶颈已经不再是以往的网络传输,人们利用集群、分布式等方式进行优化,将网络的业务能力不断的提高,但是同样的,Linux内核作为一个管理者,却不适宜对外提供业务服务,也不适合占用资源,不管怎样开发都存在面对单点性能瓶颈的问题。由此则引发了人们对于用户态协议栈的思考,让Linux内核可以很好的专注于系统调度,而其他的复杂处理全都移到用户态进行处理,使用更多的系统资源,开发也更加的自由。

1 传统内核协议栈的性能瓶颈

在传统的内核协议栈中,网络包的处理有着很多的性能瓶颈,从而严重的影响数据包的收发,它的瓶颈主要有以下几个方面:

(1)局部性失效:即一个数据包它的处理很可能会跨多个不同的CPU核心、缓存失效、NUMA不友好等,从而让一个数据包的接收可能在一个CPU核心,处理在另一个核心,使用又在另一个核心,就会造成局部失效,而CPU缓存失效和跨NUMA节点访问内存同样会增加我们的处理代价,从而严重影响性能;

(2)中断处理:内核协议栈中,数据包的处理涉及到了很多的中断处理,比如进入网卡时候的硬件中断,进入内核协议栈的软中断,以及很多的上下文切换等等,所以当涉及数据量较大的情况下,就会让产生频繁的硬件中断来接收数据包,这就会打断那些优先级较低的软中断或者系统调用过程,从而产生较高的性能开销,同样的软中断和上下文切换也增加了额外的开销;

(3)内核拷贝:数据包从网卡处接收到最终的使用,这中间可能会涉及到很多的数据拷贝,比如一开始数据从网卡进入,会通过DMA的方式传入内核缓冲区,内核处理完之后,又会拷贝到用户态进行使用,这些操作在内核协议栈中,占用了处理数据包整个流程的一半以上时间,从而达到的影响了性能;

(4)系统调用:内核协议栈主要是通过一些软中断来实现进程的切换什么的,而进程切换则会导致上下文切换,从而也会产生锁的频繁竞争,这些不管是硬件中断还是软件中断都可能会随时抢占系统的调用,也就产生了大量的上下文切换开销,而加锁和解锁的操作,以及大量的并发操作都会造成很大的性能浪费,特别是大量短连接的创建。

2 用户态协议栈

基于以上介绍到的关于内核协议栈的一些性能瓶颈,由此引发了人们对于用户态协议栈的思考,用户态协议栈,多半是通过移植FreeBSD的协议栈到用户态去进行相关操作,内核的网络协议栈主要是强调通用性,一般的优化主要是为了吞吐量和大量的并发;连接,用户态协议栈则可以根据开发所需要的特点来定制协议栈的功能,优化更直接,不再是调黑盒参数组合,而是直接上 profiling,根据结果修改应用程序和协议栈的代码。从而让LInux内核不再关注各种复杂的操作,只负责简单的资源控制和调度,也能让开发更加的自由。

用户态网络协议栈,是通过将网络协议栈上移到用户态实现的方式,主要是通过内核旁路技术实现,从而绕过内核,直接将网络硬件设备的数据给用户态的应用程序使用,目前常见比较好的技术方案有PF_RING、netmap、DPDK、MTCP和IwIP等,成熟的产品则有应用层开发项目FD.io,有思科的VPP和较完善的协议支持;腾讯开源的项目F-Stack,开发更简单,直接提供了POSIX接口;Seastar,很灵活,可以在内核态和DPDK模式随意切换。而用户态网络协议栈的最大好处就是——“定制化”,可以针对具体的业务区开发自己的协议栈,从而让性能有很大的提升,当然问题也很明显,那就是因为协议栈的定制化,在开发上需要花更多的成本。

3 用户态协议栈的应用场景

(1)在软件定义的交换机或者路由器上,因为这种情况下,希望将网卡的数据直接交给软件来管理,从而处理原始数据包并绕过内核,常见的有Open VSwitch和VRouter;

(2)在比如双十一等大型购物活动类似的场景,因为这种情景下需要很低的延迟,而用户态的协议栈则可以很好的解决这个问题,因为它在放弃了很多的中断以及采用了零拷贝等技术,在降低延迟方面有很好的的效果;

(3)针对特定的场景进行使用,比如专用的数据包存储、负载均衡等,它们需要的是直接对数据包进行处理,这个时候绕过内核在用户态实现数据包的存储和负载均衡就能很好的提高性能。

而在用户态协议栈里面最火的一门技术则是DPDK,所以接下来我会对DPDK进行一下介绍。

4 DPDK简述

说到DPDK,我们首先要说的就是DPDK的网络层和我们传统的Linux网络层的区别了,在传统的Linux网络层中,数据包的流程如下:


硬件中断--->取包分发至内核线程--->软件中断--->内核线程在协议栈中处理包--->处理完毕通知用户层

用户层收包-->网络层--->逻辑层--->业务层


以下则是DPDK的网络层中,数据包经过的流程:


硬件中断--->放弃中断流程

用户层通过设备映射取包--->进入用户层协议栈--->逻辑层--->业务层  


从以上两个流程中,我们可以看出,在传统的Linux网络层中,数据包要到我们的应用层中间经过了很多的拷贝和硬件以及软件中断。而对于DPDK,直接放弃了采用硬件中断的方式,用户层通过映射直接从网卡取包,然后就进入了数据包的处理和使用了,中间减少了很多的中断和拷贝,因为DPDK采用了内核旁路技术以及零拷贝技术。

所以DPDK有着以下几点优势:(1)它减少了中断次数;(2)减少了内存拷贝次数;(3)它绕过了Linux的内核协议栈,直接进入用户态协议栈,用户获得了协议栈的控制权后,能够定制化协议栈降低复杂度。

有利必有弊,DPDK也有它不好的地方,比如内核协议栈转移到了用户态,增加了开发成本,因为内核协议栈是一个通用的协议栈,已经比较成熟,有很多的特性和优秀的调试能力;其次是对于低负荷服务器不实用,会造成内核的空转。

 关于DPDK的其他相关信息,请参考https://blog.csdn.net/LPAINI520/article/details/106053817

5 用户态协议栈产品介绍

(1)FD.io(Fast data - Input/Output):这是一个基于许多项目和库的一个集合,是基于DPDK演化的,支持在通用硬件平台上部署灵活且可变的业务,FD.io为软件定义基础设施的开发者提供了一个平台,可以创建多个项目,开发基于软件的报文处理创新方案,以便于设计高吞吐量、低延时和有效利用资源的应用程序,并能够应用在多个平台上,比如X86、ARM、PowerPC等,还可以部署在裸机、虚拟机和容器等不同的环境中。在FD.io中最重要的一个项目就是VPP-矢量包处理,这是一个高度模块化的项目,很容易集成其他的功能进去而不会影响VPP的底层架构,除此之外,还有NSH_SFC、Honeycomb和ONE来加速网络功能虚拟化的数据面,还与其他开源项目进行了集成,比如K8s、OpenStack、ONAP和OpenDaylight,它的生态如下图1:

                   

                                                                                     图1 FD.io生态图

而到目前为止,该项目的开源社区成员包括了AT&T、Comcast、中兴、华为、博科、思科、爱立信、Metaswitch、英特尔、Cavium、红帽、Inocybe等。

(2)腾讯F-Stack:它粘合了DPDK和FreeBSD 的TCP/IP协议栈,是用C语言编写,API基本兼容Socket、Epoll、Kqueue,从而对于原有系统的兼容性比较好;但是它是基于DPDK来实现的一个用户态协议栈,其中DPDK主要是操作系统的内核数据平面,重载网卡驱动,减少中断和内存拷贝等,F-Stack是一款兼顾高性能、易用性和通用性的网络开发框架,在上层应用上还支持Nginx、Redis等,使绝大部分的网络应用可以通过直接修改配置或替换系统的网络接口即可接入 F-Stack,从而获得更高的网络性能。它的架构等如图2:

                     

                                                                                图 2 F-Stack架构图

从图中可以看出F-Stack使用了多进程的无共享架构,每个进程CPU、网卡队列绑定,具有无竞争、零拷贝、线性扩展、NUMA友好等特点。

(3)Seastar:是一个高级,开源的 C++ 框架,基于c++ 11/14 feature,支持现代化硬件的高性能服务器应用。Seastar 支持 Linux 和 OSv,支持高并发和低延迟的异步编程高性能库。从总体架构而言,Seastar是一个完全分片(share-nothing)的设计:每个逻辑核 一个线程,每个核有自己的资源:CPU, 网络, 磁盘 I/O, 内存。多个核之间没有资源的竞争,随着核数量的增加,扩展性和性能也随之提升,对于多个核之间的通信,采用point-to-point queue发送和接受异步消息。所有核之间没有数据共享,没有锁,没有cache lines频繁的丢失。与此同时,Seastar也是一个异步编程框架。而且Seastar还是第一个集成了大量的架构创新的框架,比如:Share-nothing设计;高性能网络;未来和承诺;消息传递等,至于它的应用则有Scylla,一个NoSQL数据库;Seastar HTTPD,一个Web服务器;以及Seastar Memcached等等。

(4)mTCP:它是一个的用户级别的 TCP 堆栈,用于多核处理器的系统。mTCP 从 I/O 包到 TCP 连接管理上进行全方位的优化。mTCP是用于多核系统的高性能用户级TCP堆栈。由于内核效率低下,扩展短TCP连接的性能是一个根本性的挑战。mTCP从头到尾解决了这些效率低下的问题——从包I/O和TCP连接管理一直到应用程序接口。除了采用众所周知的技术外,mTCP堆栈首先将昂贵的系统调用转换为同一CPU内核内的两个线程之间的共享内存访问;其次允许高效的流级事件聚合;再者,执行RX/TX包的批处理以获得高I/O效率。并且mTCP是作为一种用户态的协议栈库来实现的,以函数库的形式链接到应用进程去使用,底层则使用其他的用户态Packet IO库,它的架构图如图3所示:

                       

                                                                              图3 mTCP架构图

总之,mTCP有着以下特性,(1)良好的多核扩展性,(2)批量报文处理机制,(3)类epoll事件驱动系统,(4)BSD风格的socket API,(5)支持多种用户态Packet IO库,(6)传输层协议仅支持TCP。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值