我需要一个简单的类来计算网络监控系统中IP地址的分布(直方图)。可能存在1到10个 10 数据包,其中包含1到2个 32 地址(或者更多,如果我们有IPv6接口)。我理想的是一个C ++类,它将自动创建直方图,然后,当达到限制时,开始通过某种前缀路由组合不太流行的节点。
有人知道这样的事情,还是我需要写它?
谢谢!
答案 0 :(得分:5)
您所描述的内容听起来像 Count-Min sketch 数据结构的完美用例。该数据结构用于近似来自数据流的各种元素的频率,并且可以被调谐以精确地消耗一定量的存储器。此外,鉴于固定的内存限制,您可以调整它的准确程度以及与您希望的确切答案的接近程度。我的理解是,谷歌使用这种数据结构来识别频繁的搜索,而不必使用大量的磁盘空间。
另外,数据结构永远不会低估给定值的真实频率。也就是说,如果您想查询您查看给定IP地址的频率,Count-Min草图将始终为您提供一个不小于真实数字的值。
Count-Min草图非常容易实现 - 您只需要一堆不同的哈希函数和一个2D数组。您还可以找到Count-Min草图的各种不同实现 at Google's page on the data structure.
希望这有帮助!
答案 1 :(得分:2)
+1到@templatetypedef。
为了完整性,如果需要存储确切的计数,则无法存储确切的数字。但是,根据您的要求,您可能能够显着减少所需的空间(例如,10。*。*。*和192.68。*。* ips永远不会被公开路由;以及许多其他,例如25。*。*。*,目前尚未公开发布)。您也可以(再次根据您的要求)能够将大量不太重要的ips统计在一起。
如果您可以将空间要求降低到足够远,则可以使用bitset
尽可能紧凑地将计数存储在内存中。如果没有简单的方法将ip-address映射到bitset-address,则需要使用类似succinct trie的内容来映射它们。一个简洁的trie每个ip-group需要一个字节(amoritized)。
而且,如果你不能降低它,你可能需要使用数据库,并接受性能损失。
答案 2 :(得分:0)
您可以查看边界网关协议(BGP)或GRiDA算法。
答案 3 :(得分:0)
我开发了一种解决这个问题的算法。该算法将IP地址计数存储在基数树/前缀树中。每个节点记录地址的下一位,如果是终端节点,则记录计数。在节点太多的情况下,节点从树的范围开始组合;首先组合具有最低计数的叶子的节点。
非常优雅,非常快。如果有兴趣,我可以发布C ++代码。