Linux转发性能评估与优化 转发瓶颈分析与解决方案

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

线速问题

很多人对这个线速概念存在误解。认为所谓线速能力就是路由器/交换机就像一根网线一样。而这,是不可能的。应该考虑到的一个概念就是延迟。数据包进入路由器或者交换机,存在一个核心延迟操作,这就是选路,对于路由器而言,就是路由查找,对于交换机而言,就是查询MAC/端口映射表,这个延迟是无法避开的,这个操作需要大量的计算机资源,所以不管是路由器还是交换机,数据包在内部是不可能像在线缆上那样近光速传输的。类比一下你经过十字街头的时候,是不是要左顾右盼呢?

       那么,设备的线速能力怎么衡量呢?如果一个数据包经过一个路由器,那么延迟必览无疑,可是设备都是有队列或者缓冲区的,那么试想一个数据包紧接一个数据包从输入端口进入设备,然后一个数据包紧接一个数据包从输出端口发出,这是可以做到的,我们对数据包不予编号,因此你也就无法判断出来的数据包是不是刚刚进去的那个了,这就是线速。

       我们可以用电容来理解转发设备。有人可能会觉得电容具有通高频阻低频的功效,我说的不是这个,所以咱不考虑低频,仅以高频为例,电容具有存储电荷的功能,这就类似存储转发,电容充电的过程类似于数据包进入输入队列缓冲区,电容放电的过程类似于数据包从输出缓冲区输出,我们可以看到,在电流经过电容的前后,其速度是不变的,然而针对具体的电荷而言,从电容放出的电荷绝不是刚刚在在另一侧充电的那个电荷,电容的充电放电拥有固有延迟。

       我们回到转发设备。对于交换机和路由器而言,衡量标准是不同的。

       对于交换机而言,线速能力是背板总带宽,因为它的查表操作导致的延迟并不大,大量的操作都在数据包通过交换矩阵的过程,因此背板带宽直接导致了转发效率。而对于路由器,衡量标准则是一个端口每秒输入输出最小数据包的数量,假设数据包以每秒100个进入,每秒100个流出,那么其线速就是100pps。

       本文针对路由器而不针对交换机。路由器的核心延迟在路由查找,而这个查找不会受到数据包长度的影响,因此决定路由器线速能力的核心就在数据包输出的效率,注意,不是数据包输入的效率,因为只要队列足够长,缓存足够大,输入总是线速的。但是输入操作就涉及到了如何调度的问题。这也就说明了为何很多路由器都支持输出流量控制而不是输入流量控制的原因,因为输入流控即使完美完成,它也会受到路由器输出端口自身输出效率的影响,流控结果将不再准确。

       在写这个方案的前晚,有一个故事。我最近联系到了初中时一起玩摇滚玩音响的超级铁的朋友,他现在搞舞台设计,灯光音响之类的。我问他在大型舞台上,音箱摆放的位置不同,距离后级,前置,音源也不同,怎么做到不同声道或者相同声道的声音同步的,要知道,好的耳朵可以听出来毫秒级的音差...他告诉我要统一到达时间,即统一音频流到达各个箱子的时间,而这要做的就是调延迟,要求不同位置的箱子路径上要有不同的延迟。这对我的设计方案的帮助是多么地大啊。

       然后,在第二天,我就开始整理这个令人悲伤最终心碎的Linux转发优化方案。

声明:本文只是一篇普通文章,记录这个方案的点点滴滴,并不是一个完整的方案,请勿在格式上较真,内容上也只是写了些我认为重要且有意思的。完整的方案是不便于以博文的形式发出来的。见谅。

问题综述

Linux内核协议栈作为一种软路由运行时,和其它通用操作系统自带的协议栈相比,其效率并非如下文所说的那样非常低。然而基于工业路由器的评判标准,确实是低了。
 
       市面上各种基于Linux内核协议栈的路由器产品,甚至网上也有大量的此类文章,比如什么将Linux变成路由器之类的,无非就是打开ip_forward,加几条iptables规则,搞个配置起来比较方便的WEB界面...我想说这些太低级了,甚至超级低级。我很想谈一下关于专业路由器的我的观点,但是今天是小小的生日,玩了一天,就不写了。只是把我的方案整理出来吧。

       Linux的转发效率到底低在哪儿?如何优化?这是本文要解释的问题。依然如故,本文可以随意转载并基于这个思路实现编码,但是一旦用于商业目的,不保证没有个人或组织追责,因此文中我尽量采用尽可能模糊的方式阐述细节。

瓶颈分析概述


1.DMA和内存操作

我们考虑一下一个数据包转发流程中需要的内存操作,暂时不考虑DMA。
*)数据包从网卡拷贝到内存
*)CPU访问内存读取数据包元数据
*)三层报头修改,如TTL
*)转发到二层后封装MAC头
*)数据包从内存拷贝到输出网卡
这几个典型的内存操作为什么慢?为什么我们总是对内存操作有这么大的意见?因为访问内存需要经过总线,首先总线竞争(特别在SMP和DMA下)就是一个打群架的过程,另外因为内存自身的速度和CPU相比差了几个数量级,这么玩下去,肯定会慢啊!所以一般都是尽可能地使用CPU的cache,而这需要一定的针对局部性的数据布局,对于数据包接收以及其它IO操作而言,由于数据来自外部,和进程执行时的局部性利用没法比。所以必须采用类似Intel I/OAT的技术才能改善。

1.1.Linux作为服务器时

采用标准零拷贝map技术完全胜任。这是因为,运行于Linux的服务器和线速转发相比就是个蜗牛,服务器在处理客户端请求时消耗的时间是一个硬性时间,无法优化,这是代偿原理。Linux服务唯一需要的就是能快速取到客户端的数据包,而这可以通过DMA快速做到。本文不再具体讨论作为服务器运行的零拷贝问题,自己百度吧。

1.2.Linux作为转发设备时

需要采用DMA映射交换的技术才能实现零拷贝。这是Linux转发性能低下的根本。由于输入端口的输入队列和输出端口的输出队列互不相识,导致了不能更好的利用系统资源以及多端口数据路由到单端口输出队列时的队列锁开销过大,总线争抢太严重。DMA影射交换需要超级棒的数据包队列管理设施,它用来调度数据包从输入端口队列到输出端口队列,而Linux几乎没有这样的设施。

虽然近年在路由器领域有人提出了输入队列管理,但是这项技术对于Linux而言就是另一个世界,而我,把它引入了Linux世界。

2.网卡对数据包队列Buff管理

在Linux内核中,几乎对于所有数据结构,都是需要时alloc,完毕后free,即使是kmem_cache,效果也一般,特别是对于高速线速设备而言(skb内存拷贝,若不采用DMA,则会频繁拷贝,即便采用DMA,在很多情况下也不是零拷贝)。

       即使是高端网卡在skb的buffer管理方面,也没有使用完全意义上的预分配内存池,因此会由于频繁的内存分配,释放造成内存颠簸,众所周知,内存操作是问题的根本,因为它涉及到CPU Cache,总线争抢,原子锁等,实际上,内存管理才是根本中的根本,这里面道道太多,它直接影响CPU cache,后者又会影响总线...从哪里分配内存,分配多少,何时释放,何时可以重用,这就牵扯到了内存区域着色等技术。通过分析Intel千兆网卡驱动,在我看来,Linux并没有做好这一点。

3.路由查找以及其它查找操作

Linux不区分对待路由表和转发表,每次都要最长前缀查找,虽然海量路由表时trie算法比hash算法好,但是在路由分布畸形的情况下依然会使trie结构退化,或者频繁回溯。路由cache效率不高(查询代价太大,不固定大小,仅有弱智的老化算法,导致海量地址访问时,路由cache冲突链过长),最终在内核协议栈中下课。

       如果没有一个好的转发表,那么Linux协议栈在海量路由存在时对于线速能力就是一个瓶颈,这是一个可扩展性问题。

       另外,很多的查询结果都是可以被在一个地方缓存的,但是Linux协议栈没有这种缓存。比如,路由查询结果就是下一跳,而下一跳和输出网卡关联,而输出网卡又和下一跳的MAC地址以及将要封装的源MAC地址关联,这些本应该被缓存在一个表项,即转发表项内,然而Linux协议栈没有这么做。

4.不合理的锁

为何要加锁,因为SMP。然而Linux内核几乎是对称的加锁,也就是说,比如每次查路由表时都要加锁,为何?因为怕在查询的期间路由表改变了...然而你仔细想想,在高速转发情景下,查找操作和修改操作在单位时间的比率是多少呢?不要以为你用读写锁就好了,读写锁不也有关抢占的操作吗(虽然我们已经建议关闭了抢占)?起码也浪费了几个指令周期。这些时间几率不对称操作的加锁是不必要的。

       你只需要保证内核本身不会崩掉即可,至于说IP转发的错误,不管也罢,按照IP协议,它本身就是一个尽力而为的协议。

5.中断与软中断调度

Linux的中断分为上半部和下半部,动态调度下半部,它可以在中断上下文中运行,也可以在独立的内核线程上下文中运行,因此对于实时需求的环境,在软中断中处理的协议栈处理的运行时机是不可预知的。Linux原生内核并没有实现Solaris,Windows那样的中断优先级化,在某些情况下,Linux靠着自己动态的且及其优秀的调度方案可以达到极高的性能,然而对于固定的任务,Linux的调度机制却明显不足。

       而我需要做的,就是让不固定
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值