从物联网防火墙himqtt源码谈哈希和红黑树的应用场景区别

himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,很多数据结构适合初学者收藏。

哈希和红黑树的详细教程很多,本文就不重复了,但初学者往往云里雾里,不知道实战项目该用谁,今天笔者就从结合himqtt的源码,从物联网安全角度来对比一下哈希数据结构和红黑树的应用场景。

一、哈希和红黑树基本原理

哈希(hash)也称散列,通过散列算法变成固定的输出到数组,所有的线性数据结构中,数组的定位速度最快,因为它可通过数组下标直接定位到相应的数组空间,就不需要一个个查找。

红黑树的自旋是天才的设计,是一种特殊的平衡二叉树数据结构,特点也是从几十万的数据里面几步就能查找到,速度快。

二、物联网安全使用场景

首先github上下载源码,https://github.com/qq4108863/himqtt ,在src\waf目录有hashmap.c和mqtt_rbtree.c ,分别是哈希和红黑树算法。

1、速度对比

物联网可能是数百万设备联网,对高并发要求很大,所以,对网络安全产品第一要求的是性能和速度。总体来说,哈希查找速度会比红黑树快,而且查找速度基本和数据量大小无关,属于常数级别;而RB树的查找速度是log(n)级别。

红黑树查找和删除的时间复杂度都是O(logn),Hash查找和删除的时间复杂度都是O(1)。 如果红黑树的树高度不深如小于8,采用的是整形数字查找,两者性能没有太多的差异。

也就是并非所有的场景,哈希都比红黑树快,要看代码的优化程度。himqtt使用的linux高并发EPOLL模式事件管理,就是红黑树。

2、数据预知

静态数据,可以基本预知大小,用哈希。如himqtt初始化的攻击规则就几百条在可控范围内,另外TOPIC黑白名单、URL地址等也不会太多,也是用的哈希就可以了。

动态数据,如统计IP地址、任务调度、epoll高并发事件管理,无法判断多少,可能很少,也可能巨多,用红黑树更佳。当然,如果大概知道设备IP地址数量在一定范围,如只有几千,完全也可以用哈希。

3、内存消耗

对内存要求严格的地方,如嵌入式系统,用红黑树。红黑树占用的内存更小(仅需要为其存在的节点分配内存),而哈希事先就应该分配足够的内存存储散列表,浪费内存。

对内存消耗无所谓的地方,如服务器有巨大的内存,用哈希。哈希最大的缺点是内存分配得小,可能元素就会冲突,冲突的元素大于8个成链表,效率还不如红黑树。 Java 的hashmap就是把哈希和红黑树结合在以前的。当同一个hash值的节点数不小于8时,不再采用单链表形式存储,而是采用红黑树。

4 复杂程度

哈希更简单,红黑树算法复杂一点,不过这都不是事,大神早开源了很多稳定的版本。

三、应用场景总结

红黑树是有序的,哈希是无序的,根据项目需求来选择,阿里巴巴的很多项目用红黑树更多,笔者认为主要还是和内存有关,如果内存要求苛刻的项目,就用红黑树;如果内存足够大,牺牲内存换取更快的速度,哈希完全适合。

himqtt开源版大量采用哈希算法,可能和速度并发要求有关。总之,数据结构是物联网安全最基础的学科。

从物联网防火墙himqtt源码谈哈希和红黑树的应用场景区别的更多相关文章

  1. 物联网防火墙himqtt源码之MQTT协议分析

    物联网防火墙himqtt源码之MQTT协议分析 himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWall,C语言编写,采用epoll模式支持数十万 ...

  2. JDK源码学习笔记——TreeMap及红黑树

    找了几个分析比较到位的,不再重复写了…… Java 集合系列12之 TreeMap详细介绍(源码解析)和使用示例 [Java集合源码剖析]TreeMap源码剖析 java源码分析之TreeMap基础篇 ...

  3. 首款物联网防火墙himqtt开源

    随着5G的推进和物联网的快速推进,MQTT已然是物联网(Internet of Things,IoT)不可或缺的标准协议,预计到2025年将有超过750亿台设备连接到互联网,但物联网方面的防火墙很少. ...

  4. C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

    C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...

  5. 【Java源码】集合类-JDK1.8 哈希表-红黑树-HashMap总结

    JDK 1.8 HashMap是数组+链表+红黑树实现的,在阅读HashMap的源码之前先来回顾一下大学课本数据结构中的哈希表和红黑树. 什么是哈希表? 在存储结构中,关键值key通过一种关系f和唯一 ...

  6. 结合java.util.TreeMap源码理解红黑树

    前言 本篇将结合JDK1.6的TreeMap源码,来一起探索红-黑树的奥秘.红黑树是解决二叉搜索树的非平衡问题. 当插入(或者删除)一个新节点时,为了使树保持平衡,必须遵循一定的规则,这个规则就是红- ...

  7. Java数据结构和算法 - TreeMap源码理解红黑树

    前言 本篇将结合JDK1.6的TreeMap源码,来一起探索红-黑树的奥秘.红黑树是解决二叉搜索树的非平衡问题. 当插入(或者删除)一个新节点时,为了使树保持平衡,必须遵循一定的规则,这个规则就是红- ...

  8. HashMap源码深入研究

    简介 HashMap是采用链表和位桶来来实现的,由于一个位桶存在元素太多会导致get效率低,因此在jdk1.8中采用的红黑树实现,当链表长度大于TREEIFY_THRESHOLD(值为8)时会转换为红 ...

  9. HashMap 源码详细分析(JDK1.8)

    一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

随机推荐

  1. jQuery获取父窗口的元素

    js获取父页面的元素可以用 $(window.parent.document).find("#customer_id").val();这里的customer_id表示父页面某一个元 ...

  2. C#上传下载文件

    方法一.通过Ajax方式上传文件(input file),使用FormData进行Ajax请求 <div  > <input type="file" name=& ...

  3. git 之 .gitignore文件

    所有空行或者以注释符号 # 开头的行都会被 Git 忽略 匹配模式最后跟反斜杠(/)说明要忽略的是目录 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反 *.a # 忽略所有 .a 结 ...

  4. 通过无线网络使用ADB ( Connect to android with ADB over TCP )

    之前用USB数据线连接电脑和android手机,用adb操控手机. 后来电脑前面板的USB全坏了,键盘.鼠标.USBKkey.打印机都需USB,  少一个USB口,只得对不常用设备进行插拔切换. 于是 ...

  5. codeforces#1290E2 - Rotate Columns (hard version)(子集dp)

    题目链接: https://codeforces.com/contest/1209/problem/E2 题意: 给出$n$行和$m$列 每次操作循环挪动某列一次 可以执行无数次这样的操作 让每行最大 ...

  6. 例子:Vue 配合 vue-resource 从接口获取数据

    vue-resource 是 vue 的一个与服务器端通信的 HTTP 插件,用来从服务器端请求数据. 结合例子——图片列表来写一下 Vue获取接口数据. html : <div id=&quo ...

  7. 转载:OutOfMemoryError系列(2): GC overhead limit exceeded

    这是本系列的第二篇文章, 相关文章列表: OutOfMemoryError系列(1): Java heap space OutOfMemoryError系列(2): GC overhead limit ...

  8. python 语法糖是什么意思

    语法糖指那些没有给计算机语言添加新功能,而只是对人类来说更“甜蜜”的语法.语法糖往往给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读.不过其并没有给语言添加什么新东西.

  9. Docker-compose的安装和使用

    一.简介 Compose 项目 是 Docker 官方的开源项目 , 负 责实 现对 Docker 容器 集群的快速编排,其前身 是开源项目 Fig, 目前仍然兼容 Fig格式的模板文件. 使用 一个 ...

  10. Object.keys() 遍历对象

    Object.keys()方法的运用与数组遍历 Object.keys()用于获得由对象属性名组成的数组,可与数组遍历相结合使用,用起来效果杠杠滴.数组遍历可以用for()或forEach()来实现, ...