基於二叉樹的高效IP檢索格式MMDB

来源:https://www.cnblogs.com/leavygood/archive/2023/02/14/17109967.html
-Advertisement-
Play Games

本篇文章適用於學習過其他面向對象語言(Java、Php),但沒有學過Go語言的初學者。文章主要從Go與Java功能上的對比來闡述Go語言的基礎語法、面向對象編程、併發與錯誤四個方面。 ...


 一、MMDB簡介

MMDB(MaxMind Database) 是MaxMind推出的一個數據存儲和檢索的資料庫格式,用於旗下針對IP檢索和存儲的Geo產品。 IP格式由二進位比特數組組成,很容易想到每個比特對應二叉樹一個節點,可以說二叉樹檢索特別適合於IP格式。 MMDB的構造過程正是把一顆數據位於葉子節點的二叉樹進行序列化。 序列化後是位元組數組,和其他檢索格式都是反序列化為結構化的記憶體形式不同,MMDB檢索時把整個mmdb文件載入為一個位元組數組即可。 檢索過程在位元組數組上操作,由於每個節點大小固定,通過簡單記憶體計算即可完成節點定位,不需要額外生成其他中間結構,可以說非常簡潔和高效。

 

Maxmind的GeoIP產品用於檢索以下網段的geo信息,其中最左一列是網段,第二列是geoname_id。根據網段找到geoname_id,再根據geoname_id找到下圖的數據。

 

 

 

二、構造過程

構造過程是生成一顆二叉檢索樹的過程。 假設只存儲一個網段“110”的數據,則可以得到二叉樹為:

 

只有葉子節點會存儲指向數據的引用。

三、MMDB總體格式

二叉樹經過序列化會得到一個位元組數組,數據格式如下圖:

 

節點序列存儲二叉樹的節點,數據信息則存儲在數據序列中,數據使用MMDB序列化格式(類似json)。 第三部分為元數據,存儲版本號、生成時間、資料庫類型、IP版本、語言、節點個數、節點記錄規格等。檢索過程需要使用這些進行記憶體定址來完成節點位置的計算。 第一個分隔符為16位元組的"NULL",即16個0。 第二個分隔符為"\xAB\xCD\xEFMaxMind.com"。

四、節點序列說明 

節點序列等於一個節點數組,每個節點由兩個記錄組成,分別對應二叉樹的左孩子和右孩子。

在IP檢索中,比特0對應第一個記錄,比特1對應第二個記錄。

如上圖所示,包含3個節點,第一個節點的兩個記錄為3和1,第二個節點為3和2,第三個節點為19和3。

當記錄數等於節點數3時,表示沒找到數據。當記錄數大於節點數3時,則為數據節點的記錄值。

數據偏移量的計算公式:數據偏移量 = 記錄值 - 節點個數 - 16(分隔符的長度)。

第三個節點記錄19表示數據偏移量為0,19-3(節點數)-16。

 

 五、檢索演算法

在一個總節點數為3的mmdb資料庫上,網段“110”的檢索過程

 

 

六、數據段說明

數據序列由數據頭和數據組成,數據頭記錄數據類型和數據大小,目前MMDB支持多種數據類型,包括int, string, map, bytes等。 程式讀到位元組數組後通過反序列化得到實際數據。

七、實驗例子 

 1、構造一個網段為“192.2.10.0/3”,對應二進位網路“110”的節點,數據為{"iso":156,"country_name":"China"},生成的節點序列為:

註意:上圖每三個位元組存儲一個記錄,中間16個0是分隔符。格式化列印後得到下圖,符號“-”表示空節點:

 

可以看到“110”網段根據二叉樹檢索演算法得到數據段的偏移量19,則數據段偏移量為19-3(節點數)-16=0。

 2、再加入一個網段為“64.2.10.0/3”,對應二進位網路“010”的節點,數據為{"iso":826,"country_name":"England"},生成的節點序列為:

格式化列印後得到下圖,符號“-”表示空節點:

 

可以看到“010”網段根據二叉樹檢索演算法得到數據段的偏移量21,則數據段偏移量為21-5(節點數)-16=0。而此時“110”網段的數據段的偏移量變成了50,則數據段偏移量為50-5(節點數)-16=29。

 

八、總結

1、生成過程使用二叉樹。

2、存儲和檢索都是序列化位元組數組格式。

3、MMDB是記憶體資料庫 。

參考鏈接

MaxMind DB File Format Specification

Enriching MMDB files with your own data using go

Building your own MMDB database for fun and profit

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文已收錄至Github,推薦閱讀 👉 Java隨想錄 微信公眾號:Java隨想錄 CSDN: 碼農BookSea 烈火試真金,逆境試強者。——塞內加 什麼是ThreadLocal 首先看下ThreadLocal的使用示例: public class ThreadLocalTest { priva ...
  • 教程簡介 轉換率優化定義 - 從定義,基礎知識,瞭解客戶,目標設置,誤區,優化計劃,用戶體驗和漏斗優化,目標網頁優化,降低退回和退出率,測試和優化,測量結果,學習轉換率優化優化技巧,結論。 教程目錄 轉換率優化 - 定義 轉換率優化 - 基礎知識 瞭解您的客戶 轉換率優化 - 目標設定 轉換率優化 ...
  • 前言 由於在2月13日,Autojs的作者發出公告將審查所有代碼,併在最新版刪除了無障礙截圖、通知監聽等功能,在打開所有版本都會提示強制更新,之前關註的公眾號都連夜刪除了教程文章,在搜索時,發現教程作者的文章在其它平臺還未刪除,為了保險起見,備份一下他的文章。由於他寫的文章很多,文章將通過爬蟲的方式 ...
  • 教程簡介 LINQ初學者教程 - 從簡單和簡單的步驟學習LINQ(語言集成查詢),從基本到高級概念,包括概述,環境設置,標準查詢運算符,LINQ to SQL,LINQ對象,LINQ到數據集,LINQ到XML, LINQ to Entities,LINQ Lambda表達式,LINQ with AS ...
  • 1.讓伺服器監聽客戶端的連接請求 1.1 代碼塊 #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include<stdio.h> #include<stdlib.h> #define BUFFER_LEN 1 ...
  • 大數處理方案 BigInteger 適合保存比較大的整數。 public class BigInteger_ { public static void main(String[] args) { //當我們編程中,需要處理很大的整數,long不夠用 //可以使用BigInteger的類來搞定 // ...
  • Seata是SpringCloud Alibaba開發出的一款開源的分散式事務解決方案,致力於提供高性能和簡單易用的分散式事務服務。Seata 將為用戶提供了 AT 、TCC 、SAGA 和 XA 事務模式,為用戶打造一站式的分散式解決方案。可以很好的解決分散式系統中事務的問題。Seata的主要特點... ...
  • 本文介紹在Anaconda環境中,安裝Python語言pydot與graphviz兩個模塊的方法。 最近進行隨機森林(RF)的樹的可視化操作,需要用到pydot與graphviz模塊;因此記錄一下二者具體的安裝方法。 相關環境的版本信息:Anaconda Navigator:1.10.0;Pytho ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...