悲哀!作为服务器,Top 1却是fib_table_lookup

越是靠海的地方,海鲜越贵!
但那是骗外地的以种田为生的人的...
作为服务器,你敢想象系统的开销大部分都在“路由查找”上吗?

        如果你的系统中10w+条量级以上的路由表项的话,这个无可厚非,然而系统就是一个服务器,一共两块网卡,连接在一个可怜的万兆以太网中,该以太网一共两个出口,一个默认网关,一个内网网关,我勒个去,一共就2条路由...爆炸!
    
        然而该服务器的pps/tps均非常巨量,每一个数据包都要往路由表中走一趟,这其实就是例行公事!走这一趟的原始意义在于找出一个结果,告诉我我该从哪里走,为了让处理更快些,很多路由器采用了流缓存,在硬件或者软件的底层保留一个关于N元组的缓存,里面保存一个流的路由项,邻居等信息。在早期的一篇文章中,我描述了怎么在nf_conntrack中保存路由信息,一个数据包从一个接口进来,然后快速地查找缓存,找出从哪个接口出去,发出去,即可。这样就避开了查找路由表。
    
        对于服务器而言,大多数人有一种偏见,就是鄙视Netfilter,鄙视conntrack,这绝对是一种偏见,我也承认conntrack的效率低下,但这绝对不是Netfilter的错!很多人把iptables和Netfilter混为一谈,这是极其错误的,坏了Netfilter名声的仅仅是iptables的filter而已,我前任公司的老师在6年前就告诉过我,10000条iptables可以让系统的网络性能下降一半!后来我确实证实了这个,因为iptables是通过Netfilter实现的,所以就觉得Netfilter性能低下,我后来移植了nf-HiPAC,也是基于Netfilter,加了50000条规则,性能却几乎没有任何损失!
        因此,iptables的性能损失在于其线性结构,而与Netfilter完全无关!不管怎么说,在网络领域大行其道的Netfilter在服务器领域却被无情蔑视,事实上,Netfilter更多的是想用于服务器的。你可以试试看,只要你对开发人员说用Netfilter就可以搞定什么的时候,他们一定会站起来跟你嚷嚷,这样效率太低,这样不合理,这样太复杂之类的反驳如同暴风骤雨,大珠小珠落玉盘!
    
        好了,扯远了,我们现在忘掉Netfilter,我暂时也加入蔑视一族。我们的目标是绕开每一个数据包的路由查找,而又不想用Netfilter,那么怎么办?!事实上,对于服务器而言,有一个天然的缓存,那就是socket!既然你不想查路由,也不想引入Netfilter查缓存,如果你连socket都不想查,我觉得你可以成仙玩瞬间移动了。socket查找既然最终必不可少,那就把所有的东西都扔到socket里面,第一个包查找到路由的时候,就把路由项存在socket里面,后面的数据包直接取而用之!
    
        不过我还是建议使用基于Netfilter的流缓存,将socket也保存在里面,囊括一切。不要鄙视Netfilter,特别是在服务器,如果做转发设备,Netfilter可能真会成为瓶颈,但是对于服务器,应用的处理能力完全比不上Netfilter,充其量是一个量级,这要不要学iptables,不会带来任何性能问题。你自己想啊,应用程序会受制于各种计算,磁盘IO,日志,统计...任何一个延迟都会拖慢整体,而协议栈的处理是软中断驱动的,完全异步。对于转发设备,pps是指标中的根本,这意味着引入的哪怕纳秒级的性能损伤都会影响整体。

你可能感兴趣的:(悲哀!作为服务器,Top 1却是fib_table_lookup)