Stories

Detail Return Return

簡單解釋一下ObjectId的生成過程 - Stories Detail

‌一.生成邏輯與組成部分‌

ObjectId的生成過程由四個核心組件協作完成,總計12字節(24位十六進制字符串)13:

‌1.時間戳(4字節)‌

  • 採用Unix時間戳(從1970年1月1日UTC開始的秒數),寫入時取當前時間的秒級精度值。
  • 例如:時間戳641c54b2(十六進制)轉換為十進制為1679507122,對應2023年3月23日15:05:22 UTC。
  • ‌作用‌:保證生成的ID按時間有序排列,便於範圍查詢和索引優化。

    ‌2.機器標識(3字節)‌

  • 基於運行MongoDB實例的主機名或MAC地址的哈希值生成,確保不同機器的ID不重複。
  • 例如:主機名server01.example.com通過哈希算法轉換為e67400。

    3. ‌進程ID(2字節)‌

  • 使用生成ID時的進程PID(Process ID),避免同一台機器上不同MongoDB進程產生衝突。
  • 例如:PID0035對應十進制53,表示MongoDB服務的進程號。

    ‌4.計數器(3字節)‌

  • 初始值為隨機數,後續每次生成ID時遞增,確保同一進程同一秒內可生成最多16,777,216個唯一ID(256^3)。
  • 例如:計數器001dc2表示首次生成時隨機起始值,下一次生成時變為001dc3。

    ‌二.生成流程‌

    ‌1.初始化階段‌

  • 進程啓動時計算並緩存機器標識和進程PID,後續生成ID時直接複用。

    ‌2.運行時生成‌

    生成步驟:

  • 獲取當前時間的秒級Unix時間戳 → 轉換為4字節十六進制
  • 加載預緩存的3字節機器標識
  • 獲取當前進程的2字節PID
  • 從計數器中讀取當前值 → 轉換為3字節 → 計數器+1
  • 拼接四部分生成完整ObjectId

    原子性保障‌:計數器使用原子操作保證併發場景下的線程安全。

    ‌3. 唯一性與有序性原理‌

  • ‌全局唯一‌:通過“機器標識+進程PID+計數器”三重機制,即使分佈式系統中多節點同時生成ID也不會重複。
  • ‌時間有序‌:時間戳作為ID前綴,使得按_id排序等價於按插入時間排序。

    ‌4. 手動生成示例‌

    通過MongoDB驅動可手動生成ObjectId:

    // Node.js示例:手動生成ObjectId
    const { ObjectId } = require('mongodb');
    const id = new ObjectId();
    console.log(id.toHexString()); // 輸出:641c54b2e674000035001dc2

    驅動內部遵循相同生成規則,保證與數據庫自動生成的ID兼容。

    ‌5. 性能與擴展性‌

  • ‌高效生成‌:無鎖設計+本地計算,每秒可生成百萬級ID。
  • ‌空間優化‌:相比UUID(16字節),ObjectId節省4字節存儲空間。

    通過以上機制,MongoDB的ObjectId在分佈式環境下實現了高效、唯一且有序的ID生成能力

Add a new Comments

Some HTML is okay.