海量路由表的快速检索问题-Hash/Trie/快速交换

在论坛上经常会有人问,到底是使用Trie算法保存路由表还是用Hash算法。那么我首先要明白,你要保存多大的路由表。简单的答案如下:
少量:Hash算法
大量:Trie算法
但是,仅仅这么回答会显得很业余,真的很业余。但是如果回答多了,恐怕也不是什么好事,关键看问者是谁,目的做甚。因此简单且完整的回答必须毫无针对性,只能写作日志供日后回忆了。

以Linux内核为例,如果是少量的路由表,Hash算法的性能会很高,一共32个Hash桶,每一个前缀一个,所有的路由表项挂在这些Hash桶的冲突
链表上,由于路由表项并不是很多,因此统计上看,每一个冲突链表的长度也不会太长,查询操作很简单,唯一不确定的就是遍历冲突链表,由于该链表很短,因此
很高效。
      
从Hash路由表的组织上看,Hash桶的数量是固定的,那么必然地,随着路由表项的增加,冲突链表的长度也会增加,如果是大量的路由表项,Hash算法
的性能会下降。那么此时Trie算法的优势就显而易见了,原因我不想多解释,这大早上的,一会儿还要去上班,不想一日的开始就讨论痛苦的细节,但是还是可
以从感性的角度说一点。如果你把Hash算法的核心看成了“它规划了32个Hash桶”,那么Trie算法的核心就是“它比较了IP地址的32个位”,不
考虑空间消耗,它最多可以在一棵32层的树中经过32次比较操作后得到答案,然而正如我的一篇命题作文里说的那样,这棵树肯定会被压缩,优化,因此代价可
能会是多了一些回溯,少量遍历操作,但是本质是一样的。
      
因此,不要用Hash存储大量的路由表。如何二者结合各取其优,很容易想到将Hash算法冲突链表给Trie化,这样的意义是可以做到提前了解到匹配或者
不匹配,不匹配的话还要进入下一个Hash桶,冲突链表的Trie化统计上看,提前感知“快速失败”,除非你的路由项前缀的32位明细的,不然的话,总有
退到24位前缀桶,16位前缀桶的时候...不管怎么说,确实比单纯的遍历Hash冲突链表要好。或者反过来,Trie算法中融入Hash操作,都是可以
的。
      
算法的纠结到此为止,如果你的回答到此结束,可以说你对系统的理解很深,但是你被问题本身捆住了。如果有人问我路由表到底是用什么数据结构存储呢?到底是
Hash算法快还是Trie算法快呢?如果我回答都不快!使用快速交换最快!那么提问者可能会觉得我的回答没有解释它的问题。然而我却给了更好的方案。接
下来谈谈我的方案。
      
高端的路由器(如果你没有碰过Cisco/华为的路由器,请绕道),一般会将路由子系统单独作为控制平面来运作,而数据平面的核心则是快速交换。路由表通
过静态配置,动态路由协议,路由重定向,链路层发现等生成,然后会通过一系列的硬件接口将路由表的表项注入到交换板,整个交换板上有一张硬件交换表。交换
板上的任何操作都和路由子系统是独立的,你可以将其看作是两个独立的系统。路由子系统由单独的CPU控制,这是一个慢速的系统,而交换子系统甚至可以没有
CPU,完全的片上转发,当然,它可能还是会有CPU,用来路由和处理非常规的控制报文以及管理报文。
      
至于交换板的内部什么样子,可以买一本大学教材来看。必须要理解的是,交换板是硬件的,它的设计思路和软件完全不同,很多高效的算法会因为成本问题,空间
损耗问题被直接pass。并且,交换技术大多是索引定位技术,而不是搜索技术,因为搜索算法依赖很多中间状态,而在硬件上,很难维护有状态的系统或者说需
要大量的空间维护状态信息。我们可以通过CPU Cache来理解交换机制,交换表可以看作是路由表的Cache,真是这么回事儿。CPU
Cache和交换表都使用TCAM存储器,这是一个可以高速定位索引标记的存储器。表项存储在一个规整的硬件表中,通过标记来索引,而索引则是通过各种
“算法”来获取的,通过TCAM来完成。最常见的不是什么tree算法,而是Hash算法,因为它足够简单。当然,我的这篇《以DxR算法思想为基准设计出的路由项定位结构图解》文章中展示了另一种方案。
       好了,小小起床了,虽然还没写完,也不写了,新的一天开始了。

时间: 2024-10-10 02:40:37

海量路由表的快速检索问题-Hash/Trie/快速交换的相关文章

海量路由表可以使用HASH表存储吗-HASH查找和TRIE树查找

千万别!很多人这样说,也包括我.Linux内核早就把HASH路由表去掉了,现在就只剩下TRIE了,不过我还是希望就这两种数据结构展开一些形而上的讨论. 1.hash和trie/radix hash 和tire其实是可以统一在一起的.具有相同hash值的多个项具有一个共同的特征,这个特征怎么提取呢?无疑这就是hash函数的工作.而trie树 (或者radix树,管它呢)的一棵子树也有共同的特征,这个特征怎么提取呢?无疑这就是该子树根节点的父节点指示的某些bits在这棵子树的每一个节点 都具有相同的

Elastic Search如何快速检索

Elastic Search如何快速检索 http://www.infoq.com/cn/articles/database-timestamp-02 Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤.特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询.倒排索引很多地方都有介绍,但是其比关系型数据库的b-tree索引快在哪里?到底为什么快呢? 笼统的来说,b-tree索引是为写入优化的索引结构.当我们不需要支持快速的更新的时

在WPF中让ListBox和ComboBox的快速检索功能失效

问题来源: 自定义一个ComboBox,用来显示日期.后台数据使用的是DateTime,经过Converter转化成“2015年01月01日”样子的成字符串用于显示. 但是,在实际使用中,不停的按下“[”键,光标会从以一个元素一下一下的向下移动. 经过调查,这是ComboBox的“快速检索”功能在作祟. 关于快速检索: WPF中ListBox和ComboBox有一个“快速检索”的功能. 比如在ListBox里,按下“a”键,光标会定位到第一个首字母为“a”的Item上. ComboBox也是一样

字段他表选择中的快速检索设置

我们在设置平台数据库字段的编辑类型为他表选择时,通常设置如下: 这样设置的运行效果如下所示: 上面这种设置方法,也可以实现他表选择的功能,但是我们要选择人员只能点击图中向下箭头,进入选择界面,输入筛选条件,进行筛选:那么如果我们想要直接在申请人后边的框中输入筛选条件,进行选择人员要怎么办呢? 我们可以在他表选择设置时,设置一下快速检索: 运行效果如下:   我们可以看到,在上面的设置中,我们将姓名的快速检索设置为:包含:而输入码的快速检索设置为了:左匹配 这是怎么回事呢? 为了更好的说明,我们先

层次关系表格,不用递归,快速检索。HierarchyId

最近这几天写了个T4自动实现EF code first和Ado的存储过程.使用过程中发现了一个Sql的类型为HierarchyId.看到时真是百思不得齐姐.算了查一下MSDN吧.从微软官网找到了HierarchyId类型.悲催了.这个字段没有对应C# CLR类型.使用EF6时报错,提示我应该是用Byte[]类型,执行一遍程序.还是有错误,算了谷歌吧.谷歌了一下,发现有解决方案了,什么HierarchyId而且不是SQLTypes的HierarchyId,哦 EF没有找到,最后Nuget获取到了

Oracle - SQL语句实现数据库快速检索

SQL语句实现数据库快速检索 有时候在数据库Debug过程中,需要快速查找某个关键字. 1:使用PLSQL Dev自带的查找数据库对象,进行对象查找 缺点:查找慢.耗时. 2:使用SQL语句对数据库对象进行查找 查找数据库一般对象 1 SELECT * FROM DBA_SOURCE T WHERE UPPER(T.TEXT) LIKE '%关键字%' 查找数据库脚本 1 SELECT * FROM DBA_JOBS T WHERE UPPER(T.WHAT) LIKE '%关键字%'; 原文地

本地快速检索文件

文件搜索是我们在计算机使用过程中常用的操作.Windows系统自带的搜索功能检索速度太慢,检索效果差强人意.第三方的本地文件查找工具很多,如"Everything本地文件搜索".但这款小有名气的工具经笔者测试发现,文件搜索效果并不理想,文件直接检索不出来.在工具的使用过程中,笔者亲测发现另一款皮实好用的真正神器--那就是"360桌面助手".好用才是硬道理,下面介绍一下这款工具的使用. 一.打开姿势 我们首先需要安装好这款工具,在360安全卫士的功能大全里面可以找到它

JavaScript 上万关键字瞬间匹配——借助Hash表快速匹配算法

来源: http://www.cnblogs.com/index-html/archive/2013/04/17/js_keyword_match.html http://www.etherdream.com/funnyscript/Keyword/Keyword.html 适用于多关键字.大文本匹配,若关键字只有一个,则只是最朴素的字符串匹配(逐个匹配),没显示作用. var treeSearch = {     makeTree: function(strKeys) {         "u

bzoj2085 [Poi2010]Hamsters 矩阵快速幂+字符串hash

题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2085 题解 考虑暴力 DP 的做法.令 \(dp[i][j]\) 表示以 \(j\) 为开头的子串,并且已经总共出现 \(i\) 次的最小长度. \[ dp[i][j] = \min_{k=1}^n\{dp[i-1][k] + len_j - LC(j, k) \} \] 其中 \(LC(j, k)\) 表示最长的 \(j\) 的后缀等于 \(k\) 的前缀. 然后这个东西可以用矩阵来加速.