Linux栈搜索算法优化随想
0.发现物种
Linux堆栈作为一个纯软件实现,保留的硬件接口,但文章并不涉及硬件。
在Linux的协议栈实现中,由于没有硬件电路的固化,查找算法是难免的。比方路由查找,邻居查找。conntrack查找,socket查找,不一而足。其实。协议栈作为一个公共组织,为全部的数据包服务,假设一个数据包到达协议栈。处理逻辑必须帮它找到和它相关的数据结构,因此查找是必定的。即使在硬件中,也是这样。可是查找分为两种类型,这两种类型的查找对性能的影响是不一致的。
0.1.查不到不创建
像路由查找这类,假设查找不到路由项。那么就直接返回失败,数据包就此丢弃。对于这类查找。表项的创建和删除是特定事件(比方人为配置,网卡up/down等)触发的。不是自己主动的。查找结果的成功与失败所消耗的性能是一致的,所不同的协议栈对待成功与失败的方式不同,因此本文不关注这类查找。
0.2.查不到即创建
像conntrack查找。邻居查找这类,假设查找失败,将会建立一个新的表项,因此查找结果的成功与失败对性能的影响是全然不正确称的。
假设查找失败,性能损耗是巨大的,即使对于高效的hash算法,起码你要遍历完特定hash值指定的冲突链表才干发现失败,这在平均看来已经是一笔非常大的开销了,然后发现失败。这才是一个開始,接下来要分配内存,创建表项。这又是一笔非常大的花费,既消耗了时间又消耗了空间。尽管空间损耗不可避免。可是我希望在必须分配内存创建表项之前,用最快的速度发现查找失败。
0.3.介于0.1与0.2的查找
TCP socket查找介于0.1和0.2之间,对于Listen状态socket的查找。它的目标是创建一个客户socket,可是首先它要确保特定的TCP四元组不在ESTABLISHED状态或者TW状态的socket中被找到,假设存在大量的TW套接字,将会消耗大量的时间来证明“这么多TW socket中没有一个匹配它”。假设能高速说明这一点该多好啊。
而对于连Listen套接字都不匹配的元组,将会直接报告查找失败。
接下来我将不那么具体分析几种Linux内核协议栈中的查找方法。
2.nf_conntrack查找
Linux nf_conntrack优化的空间非常大非常大,測试表明,加入conntrack的内核协议栈在满载情况下PPS(Packet Per Second)会下降一半。长连接最大连接数下降一半。对于短连接。即使将各个timeout时间设置非常短,性能下降也非常明显。
新建conntrack表项的速度限制了新建连接的速度。而conntrack所能占用的内存大小以及一个conntrack表项持续的时间限制了最大的连接数量。在同一时候保持大量conntrack表项的情况下。假设HASHSIZE不够大,那么hash冲突链表将会非常长。新建连接,即NEW conntrack的创建将会极其损耗资源,由于它必须在经过极大消耗后才会发现查找失败,接下来才是干正事。假设在创建之前,高速发现查找失败,将是一件好事。
3.路由cache查找
对于相似cache的查找,也是相同的。比方路由cache的查找,我们知道,路由cache有一个过期时间,假设一台路由器的过境流量过多,将会有大量的路由项被cache,查找cache本身就是一笔非常大的开销,hash冲突的可能性非常大。费了这么大的劲还没有查到。不得不进入slow路径,简直气死人!
其实。在存在大量过境流量时,路由cache的查找开销将远远大于正规路由表查找的slow路径开销,或许正是由于这样,Linux最终还是取消了路由cache。
4.ipset查找
对于ipset中的表项查找也相似,今天在医院给小小看病的间隙。突然发现6.23版本号的ipset拥有了timeout參数,支持了超时时间本身能做非常多事,逻辑处理自己主动化了不少,可是协议栈并不知道一个表项是否已经由于过期而被删除,个人认为,像ipset查找这类,即使不携带timeout參数。假设能高速确定“不在set”中也是非常好的,当然不能明白确定“不在set中”的时候。再进行特定数据结构的查找,比方hash。tree查找。
5.Bloom过滤器
在上文中。我最终都表达了一种渴望,那就是尽快发现查找失败,这样就能够直接去干正事,而不必将时间花在一件必定失败的事上,这代价或许对于OpenWRT这种烟囱垃圾能付得起,可是对于登上大雅之堂的Linux而言,绝对付不起。
当然。差点儿全部的操作系统实现的协议栈,都和Linux一样。
怎样能高速发现查找失败。这是一个根本问题,可是再抽象一点,那就是怎样确定“一个元素一定不在一个集合中”。这件事有一个专门的理论去处理。那就是Bloom过滤器,它其实在时间复杂度和空间复杂度上的效率都非常高,可是天下没有免费的午餐,代价是什么?代价就是可能误判!尽管可能误判。可是这个算法还是能够确定一些事实的,假设它对每个推断的回答都是”可能“,那么它就是不可用的,我们总是希望确定一些事实。100%地确定一些事实!为了更好的说明,我将其写成一个函数r=B(x),假设返回0,那么就说明x不在集合中,假设返回1。那么就说明一个”可能“的事实。即x有y%的可能性不在集合中。具体y是多少,背后的数学其实也不复杂,但并非本文的重点。
正规的hash表是用一个hash算法将搜索范围缩小,然后在冲突链表中进行精确匹配,因此结果无疑是确定的。然而Bloom过滤算法并不维护冲突链表,它仅仅是逐步用多个不同的hash算法将搜索范围一步步缩小。即使这个范围再小,也还是有冲突的可能,而这种可能就是误判。
Bloom过滤算法在数据结构上设计地十分静止,假设使用N个hash算法,那么仅仅需维护一个N位的位图。为集合加入一个元素的时候,为该元素应用每个hash算法计算N个范围从0到N-1的hash值Si,并在位图中置位Si为1。如今推断元素x是否在集合中,为x计算N个hash值Xi,将位图上位于Xi上的全部值做与运算,结果为0的话。说明元素x一定不在集合中。假设它在的话,一定在加入的时候会将全部相关位设置为1。
6.应用Bloom过滤器
我在上述2-5小节所描写叙述的查找算法開始之前部署一个Bloom过滤器,是不是更好呢?假设这个Bloom算法设计地足够好,对于大多数情况,假设返回0,我就能够直接跳到创建操作的逻辑,省去了大量的遍历时间。假设返回1,那么仍然须要进行精确匹配。这相当于在我本来就认为不好的算法基础上又平添了一个Bloom过滤。情形恶化了。
可是这就是代价!这就是冒险!我能够将责任推到”这个Bloom算法设计地不够好“!还有一方面。须要权衡计算N个hash的开销和计算1个hash加上遍历的开销哪个大。此时不应该简单分析时间复杂度,由于对于Bloom。假设N确定了,那么时间复杂度无疑是O(1)。难道一定比hash表的效率更好吗?其实我们应该取加权统计值,而这个值依赖于严格的性能压力測试。
还是那句话,没有免费的午餐,要么使用硬件加速。此时你花费的是钱,要么设计一个良好的算法。此时你付出的冒险以及算法失败后的补偿。
7.分级hash查找
像MMU中的页表查找思想一样。也和BSD中的路由查找算法的思想一样。採用多层hash查找而不是单一hash加冲突链表遍历。
我以conntrack查找为例,我能够将conntrack简化为一个{IP1,IP2}对,第一个元素为键,第二个为值,这样就能够将conntrack的查找做成BSD系统的路由查找的样子,当中IP2能够被看成下一跳。
或者别的......
我并非说多级的hash算法比单独hash算法是更有效的,但多级hash表可以在超过CPU核心的计算。多级hash每个表都可以hash计算作为一个维度,每CPU多核计算维度hash值。位置维度的坐标,相比之下单hash我们不能利用多台CPU核心优势。你必须计算hash人才本地化的价值hash斗列表,以便通过冲突,。在更CPU多核时代,传统的方式来分析基于时间复杂度计算的性能可能已过时。
Linux栈搜索算法优化随想的更多相关文章
- Linux内核socket优化项
Linux内核socket优化项 vi /etc/sysctl.confnet.core.netdev_max_backlog = 30000 每个网络接口接收数据包的速率比内核处理这些包的速率快时 ...
- Linux实战教学笔记06:Linux系统基础优化
第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...
- Linux文件系统性能优化 (转)
http://blog.chinaunix.net/uid-7530389-id-2050116.html 由于各种的I/O负载情形各异,Linux系统中文件系统的缺省配置一般来说都比较中庸,强调普遍 ...
- Linux/Android 性能优化工具 perf
/***************************************************************************** * Linux/Android 性能优化工 ...
- linux系统基础优化16条知识汇总
优化的总结: 1.不用root管理,以普通用户的名义通过sudo授权管理. 2.更改默认的远程连接SSH服务端口,禁止root用户远程连接,甚至 要更改只监听内网IP. 3.定时自动更新服务区时间,使 ...
- Linux下启动时间优化专题
1. 过往优化总结 陆陆续续在Linux进行启动时间优化,之前有两份文档,分别从内核和用户空间两个方向进行了优化. <Android/Linux boot time分析优化>和<Bu ...
- MongoDB在Linux下常用优化设置
MongoDB在Linux下常用优化设置 以下是一些MongoDB推荐的常用优化设置.在生产环境下选取合适的参数值,例如预读值和默认文件描述符数目等,会对系统性能有很大的影响. 1.关闭数据库文件的 ...
- linux的性能优化
转一位大神的笔记. linux的性能优化: 1.CPU,MEM 2.DISK--RAID 3.网络相关的外设,网卡 linux系统性能分析: top:linux系统的负载,CPU,MEM,SWAP,占 ...
- Linux文件系统性能优化
本文绝大部分是转载自CSDN刘爱贵专栏: http://blog.csdn.net/liuben/archive/2010/04/13/5482167.aspx另外根据参考文档增补了一部分内容. 由于 ...
随机推荐
- Jquery浅克隆与深克隆是什么
Jquery浅克隆与深克隆是什么 一.总结 一句话总结:克隆的那些标签内容就是对应元素的html,事件就是那些绑定的事件. 1.jquery克隆的时候的注意事项是什么? 元素数据(data)内对象和数 ...
- jquery-12 jquery中的工具方法有哪些
jquery-12 jquery中的工具方法有哪些 一.总结 一句话总结:四个较常用方法.1.isArray();2.isFunction();3.isEmptyObejct();4.trim(); ...
- 【u121】教主的花园
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都 ...
- 几种常见web 容器比较 (tomcat、 jboss 、resin、 weblogic、 websphere、 glassfish)(转)
点击打开PDF下载链接 web 容器比较 tomcat jboss resin weblogic websphere glassfish 1. Tomcat是Apache鼎力支持的Java Web应用 ...
- jquery获取选中select的文本,值等
jquery获取select选择的文本与值获取select :获取select 选中的 text : $("#ddlregtype").find("option:s ...
- 以Graphicslayer为管理组来管理Element.
转自原文 以Graphicslayer为管理组来管理Element. 前言 在AE开发过程中,我们经常使用Element(元素).它的出现让地图与用户之间的交互增加了不少的效果.在地图上,可以通过各种 ...
- 基于 Android NDK 的学习之旅-----JNI 数据类型
经典老套流程,学编程语言东西,先学它最基础的数据类型,JNI也是如此.JNI 定义了一系列基本数据类型和引用数据类型与java想对应. 1.基本数据类型 下面一张表是描述了 Java 基本数据类型和J ...
- JAVA基本数据类型及其转换
Java语言是一种强类型语言.这意味着每个变量都必须有一个声明好的类型.Java语言提供了八种基本类型.六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型.Java另外还提供大数字对 ...
- Nginx与真实IP
配置了Nginx,Tomcat中的Web程序,获得的ip一直是"127.0.0.1",比较纳闷.获得远程ip,已经判断了很多情况,为什么会这样呢? 正解 proxy_set_hea ...
- MKNetworkKit的断点续传SIDownloader下载
comefrom:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d6f8b9042238fce098 ...