当前位置: 首页 > article >正文

Hash 的工程优势: port range 匹配

昨天和朋友聊到 “如何匹配一个 port range”,觉得挺有意思,简单写篇散文。

回想起十多年前,我移植并优化了 nf-HiPAC,当时还看不上 ipset hash,后来大约七八年前,我又舔 nftables,因为用它可直接写多维树匹配,更早之前,Linux 内核 Hash 路由查找算法被 trie 替代时,我就写文捧过一番,我是有多么看不上 Hash,似乎任何一棵 Tree 都吊打 hash。

多年以后反思,如果再让我做同样的需求,我定会 Hash 做到底,不会再动 Tree 的主意。Hash 实现最简单,并可随内存线性扩展,在大多数场景下也不会比 Tree 差,只有纯理工科背景且未被工程教训毒打过的副经理才会拎出 Tree 更好的例外作为替换 Hash 的理由。

匹配 port range,想当然的算法是构建区间查找树,当年看 Linux 内核 mmap 实现时看到过 Linux 文件映射就是用区间树实现,所以但凡和区间关联的,我都会去安利区间树,也因此当年优化 nf-HiPAC 时也就是选定了它,但在实现过程中遇到了极大的困难,于是我就偷了个懒。

有意思的是,这个偷懒很值得。

我没有用实际 rule 中的 port range 直接构建区间树,而将整个 port 空间分为一致 500 个端口一组的等距区间,然后将实际 rule 的 port range 往上盖,在等距边界处做 split。比如 rule 的 range 1234~1400,则 1000~1500 等距区间就被分为了 3 部分,这 3 部分作为匹配 1000~1500 后的二级匹配,执行一个线性遍历就完了。

我当时非常看不起线性遍历,所以一直耿耿于怀,我当时不知道,几十以内的线性遍历其实是无伤遍历,更何况个位数。巧的是我当时能力不足以让我继续优化成 Tree,就保留了 “二分等距区间查找 + 线性遍历” 的 “拙劣” 实现,没想到它工作得非常好。

回想起来,这种等距区间分割,让规则中的 port range 适配它的做法,依然属于横竖颠倒,拨云见日。我对这种方法论的掌握已经深入了内心,下意识而为之。

现如今,我连等距区间树也要扔掉,用 hash 替代等距区间树,就是另一个新的算法:
在这里插入图片描述
Hash 相比树的缺点在于要遍历冲突链表,比如 Linux 内核里的 hlist。假设 hash 算法足够优秀(没得说,都不差),hlist 中元素的个数是可随着内存增加减小的,而树的操作无论多好的 CPU 始终是 log 级。

虽然 Hash 要额外处理冲突,但树也不是一步到位的,加上树的平衡,锁等复杂操作,在通用软件场景下,其性价比远小于 Hash。假设 50000 并发,2000 个 hash bucket,平均只需要遍历 25 次,而采用二叉树需要 15 次操作,但算上其插入,平衡操作,是要比 hash 更昂贵的。二叉树只在更大并发时才凸显优势,其操作量随数据量 log 增长,而线性增长的 hash 操作亦可通过增加内存抵消操作数量。但如若真遇到海量并发,通用软件本身就成了瓶颈。

确保下面的区域:
在这里插入图片描述
显然,x 会随内存增加向右线性延展,,而 log 曲线 y = α ⋅ log ⁡ 2 x y=\alpha\cdot\log_2{x} y=αlog2x 则会因 CPU 性能提升而下压。纯算法分析,log 下压更明显,但纯算法分析,Hash 简直就是 O(1),所以二者并非简单的时间空间较劲二选一,而是呼吁架构的改变。

其实说白了就是 Hash 简单易实现没 bug,特别是频繁增删查的场景,一个反面案例来自 David Miller 对 IPv6 路由查找的 “优化”,惹了不少麻烦(详见 3.10 内核中 IPv6 的缺陷),要是用 Hash 实现,不可能有这事。

说点形而上。

Hash 和 Tree 实际上代表了计算在空间和时间分别展开的两个方向,Hash 的 O(1) 约束下,1 倍的规模增量可带来1 次操作增量,需要 1 倍的内存来抵消这 1 次的操作以维持 O(1),操作时间不变,对于二叉树,1 倍的规模增量同样带来 1 次操作增量(每增加 1 层,叶子节点数量增加 1 倍),但这次操作无法抵消,时间永远随规模增加而单调递增,然而由于二叉树在操作过程中天然保序,就意味着其不真需要额外预留 1 倍空间以支撑规模。

时间不可压缩,但空间可压缩,这是时空的本质不同,接受一个随规模递增得慢的时间,去压缩空间,这是所有机器的实现方式。背后是一个选择问题,我们是选择在时间中等待,去压缩空间,还是选择线性扩展空间,只为不等待,还是那个 “矩” 的长宽权衡。

直白说,空间不可无限扩展,我们倾向于压缩它,我们设计的机器也是,而时间总是流逝不可压缩,我们倾向于高效利用它,我们设计的机器也是。物件越来越多时,我们倾向于将它们分类叠放以便查找而不是在更大的空间平摊以便一眼瞅,空间的扩张总有极限,而时间却无限延展。空间是共享的,我们的一生时间却是私人的。

但我们还是希望有套稍微大一点哪怕极简的房子,在多数场景,它比紧凑的装修和储物分类更简单,更令人舒适,这还不够的话,就看看我们智人的历史,看看我们作为自己是如何学会 “集约(字面意思)” 的,我们的所谓文明,就是这种方式,所以我们设计的机器也是这种方式,但在大多数时间,我们却是用相反的方式:
在这里插入图片描述

首先要地盘,其次不要太大,这就是选择 hash 的理由。

浙江温州皮鞋湿,下雨进水不会胖。

相关文章:

Hash 的工程优势: port range 匹配

昨天和朋友聊到 “如何匹配一个 port range”,觉得挺有意思,简单写篇散文。 回想起十多年前,我移植并优化了 nf-HiPAC,当时还看不上 ipset hash,后来大约七八年前,我又舔 nftables,因为用它可直…...

同为.net/C#的跨平台运行时的mono和.net Core有什么区别?

Mono 和 .NET Core(现已统一为 .NET)都是 .NET 生态的跨平台实现,但它们在设计目标、技术特性和应用场景上有显著区别。以下是详细对比: ​​1. 历史背景​​ ​​项目​​​​诞生时间​​​​开发者​​​​当前状态​​​​Mo…...

前端安全直传MinIO方案

目的:前端直接上传文件到Minio,不通过服务器中转文件。密钥不能在前端明文传输。 ## 一、架构设计 mermaid sequenceDiagram 前端->>后端: 1.请求上传凭证 后端->>MinIO: 2.生成预签名URL 后端-->>前端: 3.返回预签名URL 前端->…...

HackMyVM-Dejavu

信息搜集 主机发现 ┌──(root㉿kali)-[~] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:39:60:4c, IPv4: 192.168.43.126 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.43.1 c6:45:66:05:91:88 …...

LeetCode Hot100(动态规划)

70. 爬楼梯 题目: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 题解: 不难发现,每一次都是从i-1或者i-2爬上来的,我们加起来求和即可 class So…...

Opencv实用操作5 图像腐蚀膨胀

相关函数 腐蚀函数 img1_erosion cv2.erode(img1,kernel,iterations1) (图片,卷积核,次数) 膨胀函数 img_dilate cv2.dilate(img2,kernel1,iterations1) (图片,卷积核,次数)…...

【赵渝强老师】OceanBase的部署架构

OceanBase数据库支持无共享(Shared-Nothing,SN)模式和共享存储(Shared-Storage,SS)模式两种部署架构。 一、 无共享(Shared-Nothing,SN)模式 在SN模式下,各…...

(18)混合云架构部署

文章目录 🚀 混合云架构部署:Java应用的云原生之旅🌩️ 混合云架构简介⚡ Java应用云原生部署五大核心技术1️⃣ 容器化与编排技术2️⃣ 服务网格与API网关3️⃣ CI/CD自动化流水线4️⃣ 多云管理平台5️⃣ 云原生Java框架与运行时 &#x1f…...

c/c++的opencv霍夫变换

OpenCV中的霍夫变换 (C/C) Hough Transform 霍夫变换 (Hough Transform) 是一种在图像分析中用于检测几何形状(如直线、圆形等)的特征提取技术。它通过一种投票机制在参数空间中寻找特定形状的实例。OpenCV 库为 C 开发者提供了强大且易用的霍夫变换函数…...

AAOS系列之(七) --- AudioRecord录音逻辑分析(一)

一文讲透AAOS架构,点到为止不藏私 📌 这篇帖子给大家分析下 AudioRecord的初始化 1. 场景介绍: 在 AAOS 的 Framework 开发中,录音模块几乎是每个项目都会涉及的重要组成部分。无论是语音控制、车内对讲(同行者模式)…...

MySQL大表结构变更利器:pt-online-schema-change原理与实战指南

MySQL大表结构变更利器:pt-online-schema-change原理与实战指南 MySQL数据库运维中,最令人头疼的问题之一莫过于对大表进行结构变更(DDL操作)。传统的ALTER TABLE操作会锁表,导致业务长时间不可用,这在724小时运行的互联网业务中是不可接受的。本文将深入剖析Percona To…...

LangChain【3】之进阶内容

文章目录 说明一 LangChain Chat Model1.1 少量示例提示(Few-Shot Prompting)1.2 Few-Shot示例代码1.3 示例选择器(Eample selectors)1.4 ExampleSelector 类型1.5 ExampleSelector案例代码1.6 LangServe工具1.7 LangServe安装1.8 langchain项目结构1.9 …...

大规模JSON反序列化性能优化实战:Jackson vs FastJSON深度对比与定制化改造

背景:500KB JSON处理的性能挑战 在当今互联网复杂业务场景中,处理500KB以上的JSON数据已成为常态。 常规反序列化方案在CPU占用(超30%)和内存峰值(超原始数据3-5倍)方面表现堪忧。 本文通过Jackson与Fas…...

【OpenSearch】高性能 OpenSearch 数据导入

高性能 OpenSearch 数据导入 1.导入依赖库2.配置参数3.OpenSearch 客户端初始化4.创建索引函数5.数据生成器6.批量处理函数7.主导入函数7.1 函数定义和索引创建7.2 优化索引设置(导入前)7.3 初始化变量和打印开始信息7.4 线程池设置7.5 主数据生成和导入…...

HTML5有那些更新

语义化标签 header 头部nav 导航栏footer 底部aside 内容的侧边栏 媒体标签 audio 音频播放video 视频播放 dom查询 document.querySelector,document.querySelectorAll他们选择的对象可以是标签,也可以是类(需要加点),也可以是ID(需要加#) web存储 localStorage和sessi…...

AWS EC2 实例告警的创建与删除

在AWS云环境中,监控EC2实例的运行状态至关重要。通过CloudWatch告警,用户可以实时感知实例的CPU、网络、磁盘等关键指标异常。本文将详细介绍如何通过AWS控制台创建EC2实例告警,以及如何安全删除不再需要的告警规则,并附操作截图与…...

STM32 搭配 嵌入式SD卡在智能皮电手环中的应用全景评测

在智能皮电手环及数据存储技术不断迭代的当下,主控 MCU STM32H750 与存储 SD NAND MKDV4GIL-AST 的强强联合,正引领行业进入全新发展阶段。二者凭借低功耗、高速读写与卓越稳定性的深度融合,以及高容量低成本的突出优势,成为大规模…...

黑马点评项目01——短信登录以及登录校验的细节

1.短信登录 1.1 Session方式实现 前端点击发送验证码,后端生成验证码后,向session中存放键值对,键是"code",值是验证码;然后,后端生成sessionID以Cookie的方式发给前端,前端拿到后&a…...

【笔记】Windows 系统安装 Scoop 包管理工具

#工作记录 一、问题背景 在进行开源项目 Suna 部署过程中,执行设置向导时遭遇报错:❌ Supabase CLI is not installed. 根据资料检索,需通过 Windows 包管理工具Scoop安装 Supabase CLI。 初始尝试以管理员身份运行 PowerShell 安装 Scoop…...

LVS + Keepalived高可用群集

目录 一:keepalived双击热备基础知识 1.keepalived概述及安装 1.1keepalived的热备方式 1.2keepalived的安装与服务控制 (1)安装keepalived (2)控制keepalived服务 2.使用keepalived实现双击热备. 2.1主服务器的…...

MySQL之约束和表的增删查改

MySQL之约束和表的增删查改 一.数据库约束1.1数据库约束的概念1.2NOT NULL 非空约束1.3DEFAULT 默认约束1.4唯一约束1.5主键约束和自增约束1.6自增约束1.7外键约束1.8CHECK约束 二.表的增删查改2.1Create创建2.2Retrieve读取2.3Update更新2.4Delete删除和Truncate截断 一.数据库…...

Greenplum:PB级数据分析的分布式引擎,揭开MPP架构的终极武器

一、Greenplum是谁?—— 定位与诞生背景 核心定位:基于PostgreSQL的开源分布式分析型数据库(OLAP),专为海量数据分析设计,支撑PB级数据仓库、商业智能(BI)和实时决策系统。 诞生背…...

Oracle数据库性能优化的最佳实践

原创:厦门微思网络 以下是 Oracle 数据库性能优化的最佳实践,涵盖设计、SQL 优化、索引管理、系统配置等关键维度,帮助提升数据库响应速度和稳定性: 一、SQL 语句优化 1. 避免全表扫描(Full Table Scan)…...

云原生时代 Kafka 深度实践:02快速上手与环境搭建

2.1 本地开发环境搭建 单机模式安装 下载与解压:前往Apache Kafka 官网,下载最新稳定版本的 Kafka 二进制包(如kafka_2.13-3.6.0.tgz,其中2.13为 Scala 版本)。解压到本地目录,例如/opt/kafka&#xff1a…...

Redis7 新增数据结构深度解析:ListPack 的革新与优化

Redis 作为高性能的键值存储系统,其核心优势之一在于丰富的数据结构。随着版本迭代,Redis 不断优化现有结构并引入新特性。在 Redis 7.0 中,ListPack 作为新一代序列化格式正式登场,替代了传统的 ZipList(压缩列表&…...

分布式爬虫架构设计

随着互联网数据的爆炸式增长,单机爬虫已经难以满足大规模数据采集的需求。分布式爬虫应运而生,它通过多节点协作,实现了数据采集的高效性和容错性。本文将深入探讨分布式爬虫的架构设计,包括常见的架构模式、关键技术组件、完整项…...

汽配快车道:助力汽车零部件行业的产业重构与数字化出海

汽配快车道:助力汽车零部件行业的数字化升级与出海解决方案。 在当今快速发展的汽车零部件市场中,随着消费者对汽车性能、安全和舒适性的要求不断提高,汽车刹车助力系统作为汽车安全的关键部件之一,其市场需求也在持续增长。汽车…...

Windows 11 家庭版 安装Docker教程

Windows 家庭版需要通过脚本手动安装 Hyper-V 一、前置检查 1、查看系统 快捷键【winR】,输入“control” 【控制面板】—>【系统和安全】—>【系统】 2、确认虚拟化 【任务管理器】—【性能】 二、安装Hyper-V 1、创建并运行安装脚本 在桌面新建一个 .…...

PyQt6基础_QtCharts绘制横向柱状图

前置: pip install PyQt6-Charts 结果: 代码: import sysfrom PyQt6.QtCharts import (QBarCategoryAxis, QBarSet, QChart,QChartView, QValueAxis,QHorizontalBarSeries) from PyQt6.QtCore import Qt,QSize from PyQt6.QtGui import QP…...

《TCP/IP 详解 卷1:协议》第2章:Internet 地址结构

基本的IP地址结构 分类寻址 早期Internet采用分类地址(Classful Addressing),将IPv4地址划分为五类: A类和B类网络号通常浪费太多主机号,而C类网络号不能为很多站点提供足够的主机号。 子网寻址 子网(Su…...