【前言】最近在实习公司用到了solarflare的万兆网卡,用到了网卡的openonload技术还有TCPDirect模式代码的编写,其理论基础都是内核旁路。网上关于内核旁路技术的介绍基本就两篇,我结合solarflare的技术文档,总结一下。

  原文地址(需要翻墙):https://blog.cloudflare.com/why-we-use-the-linux-kernels-tcp-stack/

  转:最近的一篇文章提出了“我们为什么使用Linux内核的TCP协议栈”的问题,并在Hacker News引发了非常有意思的讨论。我的经验绝大部分来自于在这里和生产环境中成千的机器打交道,我可以试着从这个角度回答这个问题。

  让我们从一个更宽泛的问题开始 – 到底什么才是运行一个操作系统的意义?如果你打算运行一个单独的应用,那使用一个包含几千万行代码的内核听起来就像一个负担。但实际上,我们绝大多数的人都决定要使用某种类型的操作系统,并且我们这么做主要有两个原因。首先,操作系统层带来了硬件的独立性和容易使用的API。有了这些我们可以专注于编写适用于任何机器的代码 – 而不只是我们目前所拥有的特定的硬件。其次,操作系统添加了一个时间分享的层。这让我们能同时运行多个应用。不管是一个额外的HTTP 服务器还是一次Bash会话,这个能在多个进程之间共享资源十分重要。所有被内核暴露出来的资源都可以在多个进程之间进行共享。

  一个重要的问题,tcp/ip协议无法带来多CPU的线性加速。

一、用户空间网络

  对于网络栈来说并没有什么不同。通过使用通用的操作系统网络协议栈我们拥有了运行多个网络应用的能力。然而如果我们为了运行一个用户空间的网络栈,将网络硬件专用于一个应用程序的话,这个能力就丢失了。通过要求将网卡仅为一个进程使用,你就失去了和你的服务器同时运行的能力另外一个应用,如一个SSH会话,的能力。

  可能这听起来有点不可思议,但是这正是绝大多数的用户空间网络栈技术的目的。用来完整描述这个名词叫做“完全内核旁路(full kernel bypass)”。这想法是绕过内核,然后直接从用户空间的进程使用网络硬件。

  在Linux的生态环境中,有一些已经存在的技术。不是所有的都是开源的:

  • PF_RING

  • Snabbswitch

  • DPDK

  • Netmap

  我已经在之前的一篇文章讲过它们。所有的的这些技术都需要将网卡整个移交给一个单独的进程。换句话说:完全有可能编写你自己的网络协议栈,让他变得聪明,专注于高级的特性,并且针对性能进行优化。但是这会招来一个很大的开销 – 每一张网卡最多只能将它用于一个进程。

  关于虚拟网卡(VF)这里有一个小小改变,但是我们不要在这里讨论它——它无法工作。我已经在“虚拟化方案”的那一段中讲到了它。

  但即使有种种障碍,我也不能简单地否定内核旁路的好处。确实有很多人在运行自定义的网络协议栈,并且他们可能出于下面两个原因之一:

  • 延迟

  • 性能(更低的CPU消耗,更高的吞吐量)

  延迟对于高率交易(high frequency tradin)来说至关重要。交易者能支付得起自定义的硬件,和各种复杂的私有网络栈。运行一个闭源的TCP协议栈会让我很不自在。

  在CloudFlare的内核旁路

  https://blog.cloudflare.com/kernel-bypass/

  https://blog.csdn.net/wwh578867817/article/details/50139819

  尽管这么说,在CloudFlare我们也的确使用内核绕行。我们是上面提到的第二种人,我们很在乎性能。更加明确的说,我们遭受着IRQ风暴的问题。Linux的网络栈一秒钟能处理的数据包是有限的。当达到上限的时候,所有的CPU都忙于接收数据包。在这种情形下,数据包要么被丢弃,要么会导致应用CPU匮乏( starve of CPU)。尽管在正常的情况下我们不用处理IRQ风暴,但是当我们是一次三层(OSI中的第三层)DDoS攻击的对象的时候就会成为问题。这是一种攻击目标被各种随意的不属于任何合法连接数据淹没的攻击 – 通常来说都是欺骗数据包(spoofed packets)。
  在一些攻击中我们一台服务器会遭受一秒高达3Mpps的数据包。一个广泛适用的法则就是Linux的iptables能在一个不错的服务器上处理约1Mpps的数据包的同时,仍为应用留下足够多的CPU。这个数字还可以通过调优来提高。

  对于这种规模的攻击来说Linux内核对于我们来说是不够的。我们必须找到解决方法。我们没有使用之前提到的“完全内核旁路”,相反的我们使用的是我们自称为的“部分内核旁路”。通过它内核仍然保留网卡的的拥有权,并且能让我们只在一个单独的“接收队列(Rx Queue)”上执行旁路。我们在SolarFlare的网卡上使用Solarflare的EFVI API。为了支持Intel的网卡,我们给Netmap添加了一个部分内核旁路的特性:这个在这篇文章里有讲到。通过这个技术我们可以将我们的抗DDoS iptable分担到一个十分快的用户进程。这让Linux不用再处理攻击的数据包,因此避免了IRQ风暴的问题。

二、一个完全的用户空间TCP协议栈如何呢?

  我们的同事经常会问我:我们什么我们不用Solarflare的OpenOnload框架来运行我们的Nginx呢,使用十分快速的用户空间TCP?

  是的,这会更快,但是没有证据这能产生什么实际上的不同。我们服务器绝大多数使用的CPU被用在了用户空间的Nginx进程而不是操作系统。CPU主要用在经常的Nginx的簿记和我们的Lua应用逻辑,而不是处理网络。我估计通过旁路我们能节省大约5%-10%的CPU,这(至少在目前看来)并不值当。但是对于量化交易的延时很重要
  其次,为了Nginx使用内核旁路会干扰我们平常使用的调试工具。我们的systemtap脚本会变得没有用。Linux的netstat统计会停止记录重要的事件,并且tcpdump不会再工作。然后我们的DDoS缓解栈来说也有一个问题。我们是iptables的重度用户,正如我们在这个BlackHat的演讲中讲到的。自定义的TCP协议栈是没有入”hashlimits”和”ipsets”这类东西的。  

  但是不只防火墙的特性。Linux的TCP协议栈有一些特别有用的非常重要的支持,如RFC4821,可以通过用sysctl的sys.net.ipv4.tcp_mtu_probing来设置。这种支持当一个用户在一个ICMP的黑洞后面来说是非常重要的。可以通过阅读这个文章来了解PMTU。

  最后,每一个TCP协议栈都会有一些自己的问题和怪异模式。我们已经描述了三种Linux TCP栈中不是很显而易见的Linux怪异问题:

  • 读缓冲中垃圾回收器闯入的问题

  • 关于太多监听套接字的问题

  • 一个套接字可写意味着什么

  想像一下要在一个闭源或者年轻的TCP协议栈中要调试这种问题意味着什么。

三、结论

  有两个问题:

  第一,目前还没有稳定的开源的部分内核旁路技术。我们希望Netmap能抢占这个商机,并且我们在积极地通过我们自己的补丁来支持它。

  第二,Linux TCP协议栈有很多重要的特性和优秀的调试能力。需要花费几年的的时间来能挑战这个丰富的生态系统。

  鉴于这些原因,基于用户空间的网络是不大可能成为主流的。在实践中,我只能想象少数合理的应用需要用到内核旁路技术:

  1、软件的交换机或者路由器。这里你想将网卡交由应用来处理,让它们来处理原始的数据包并且完全绕开内核。

  2、专用的负载均衡器。类似的,如果该机器只用来做数据包的随机处理( packet shuffling ),那绕过内核就是合理的。

  3、对于选定的高吞吐/低延迟的应用进行部分旁路。这就是在我们的DDoS缓解系统中用到的。不幸的是,我尚不知道有什么稳定且开源的TCP协议栈是适合这一类的。

  4、对于普通用户来说,Linux的网络栈才是正确的选择。尽管这比起自己重写TCP协议栈来说不那么振奋人心,但是我们专注于理解Linux栈的性能并且修复其中问题。已经有一些正在进行的严肃的提议来改善这个年老优秀的Linux TCP协议栈。

  5、量化交易高频、中低频交易可以使用。

Linux内核的TCP协议栈和内核旁路的选择?的更多相关文章

  1. CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

    CVE-2019-11477:Linux 内核中TCP协议栈整数溢出漏洞详细分析 代码卫士 今天

  2. linux下TCP/IP及内核参数优化调优(转)

    Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等. 如下配置是写在sysctl.con ...

  3. Linux内核中TCP SACK机制远程DoS预警通告

    漏洞描述 2019年6月18日,RedHat官网发布报告:安全研究人员在Linux内核处理TCP SACK数据包模块中发现了三个漏洞,CVE编号为CVE-2019-11477.CVE-2019-114 ...

  4. Linux 升级内核开启 TCP BBR 有多大好处

    前言 如果你有订阅一些科技新闻,应该会有看过内核在4.9当中加入了一个新的算法,来解决在有一定的丢包率的情况下的带宽稳定的问题,这个是谷歌为我们带来的干货,新的 TCP 拥塞控制算法 BBR (Bot ...

  5. TCP/IP及内核参数优化调优

    Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等.如下配置是写在sysctl.conf ...

  6. TCP/IP及内核参数优化调优(转)

    Linux下TCP/IP及内核参数优化有多种方式,参数配置得当可以大大提高系统的性能,也可以根据特定场景进行专门的优化,如TIME_WAIT过高,DDOS攻击等等.如下配置是写在sysctl.conf ...

  7. Linux内核Makefile文件(翻译自内核手册)

    --译自Linux3.9.5 Kernel Makefiles(内核目录documention/kbuild/makefiles.txt) kbuild(kernel build) 内核编译器 Thi ...

  8. Linux中mod相关的命令 内核模块化 mod相关命令都是用来动态加载内核模块/驱动程序模块

    Linux中mod相关的命令 内核模块化   mod相关命令都是用来动态加载内核模块/驱动程序模块 http://baike.baidu.com/link?url=lxiKxFvYm-UfJIxMjz ...

  9. Linux设备驱动工程师之路——内核链表的使用【转】

    本文转载自:http://blog.csdn.net/forever_key/article/details/6798685 Linux设备驱动工程师之路——内核链表的使用 K-Style 转载请注明 ...

随机推荐

  1. shell脚本的使用该熟练起来了,你说呢?(篇三)

    继续前一篇的文章: shell脚本的使用该熟练起来了,你说呢?(篇一) shell脚本的使用该熟练起来了,你说呢?(篇二) 文章里面测试的命令脚本文件,大家关注我公众号后,可以私信我领取文件. 作者: ...

  2. 2019 Multi-University Training Contest 1 A.Blank(dp)

    题意:现在要你构造一个只有{0,1,2,3} 长度为n且有m个限制条件的序列 问你方案数 思路:dp[i][j][k][now]分别表示四个数最后出现的位置 最后可以滚动数组 优化一下空间 ps:我的 ...

  3. Atcoder(134)E - Sequence Decomposing

    E - Sequence Decomposing Time Limit: 2 sec / Memory Limit: 1024 MB Score : 500500 points Problem Sta ...

  4. 要想用活Redis,Lua脚本是绕不过去的坎

    前言 Redis 当中提供了许多重要的高级特性,比如发布与订阅,Lua 脚本等.Redis 当中也提供了自增的原子命令,但是假如我们需要同时执行好几个命令的同时又想让这些命令保持原子性,该怎么办呢?这 ...

  5. ElasticSearch 搜索引擎概念简介

    公号:码农充电站pro 主页:https://codeshellme.github.io 1,倒排索引 倒排索引是一种数据结构,经常用在搜索引擎的实现中,用于快速找到某个单词所在的文档. 倒排索引会记 ...

  6. MySQL中为避免索引失效所需注意的问题

    一.索引介绍 二.索引的优势与劣势 1.优势 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本. 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗. 2.劣势 实际上索引也 ...

  7. Linux系统SCSI磁盘扫描机制解析及命令实例

    介绍Linux系统扫描SCSI磁盘有几种方式?Linux新增LUN之后,能否不重启主机就认出设备?如果安装了PowerPath,动态添加/删除LUN的命令是什么?本文总结了Linux主机对磁盘设备进行 ...

  8. Docker之Dockerfile文件

    Dockerfile是一堆指令,每一条指令构建一层,因此每一条指令的内容就是描述该层应当如何构建,在docker build的时候,按照该指令进行操作,最终生成我们期望的镜像文件 Dockerfile ...

  9. OpenCV+Ubuntu+缺少Python.h

    在cmake时粗心了, 要确保有 -D PYTHON_INCLUDE_DIR=/usr/include/python3.5 且该目录下存在Python.h文件. 如果在错误提示中是python2, 那 ...

  10. Apple iOS 触控按钮 自动关闭 bug

    Apple iOS 触控按钮 自动关闭 bug bug 轻点 iPhone 背面可执行操作 您可以轻点两下或轻点三下 iPhone 背面以执行某些操作,如向上或向下滚动.截屏.打开"控制中心 ...