Aerospike 大數據類型 (LDT) 架構深度解析:大型有序列表 (LLIST) 與子記錄儲存模型
Aerospike 大數據類型 (Large Data Types, LDT) 允許單一 Bin 儲存大量集合物件 (Integer/String/Map/List),突破單記錄 1MB 限制,適用於用戶時間軸、設備遙測、會話歷史等場景。本文深入解析 LDT 儲存架構、子記錄機制、LLIST 的 B+樹實現與元資料控制結構。
LDT 核心架構:子記錄模型
- 父記錄:包含 LDT 控制結構與 B+樹根節點指標。
- 子記錄:實際儲存資料元素的容器,大小約 2KB-200KB (由寫入塊大小決定)。
- 共享屬性:子記錄與父記錄共享 Partition ID、內部記錄鎖,隨父記錄遷移、受相同隔離機制保護。
- 非連續儲存:LDT 元素分散於多個子記錄,訪問單一元素僅涉及少數子記錄,避免讀取整個大集合。
- UDF 管理:子記錄的建立、分裂、合併、GC 由使用者定義函數 (UDF) 在資料庫內核執行。
大型有序列表 (LLIST) 詳細設計
邏輯特性
- 管理大規模有序列表,元素支援原始類型 (int, string, blob) 與複雜類型 (map, list)。
- 提供豐富操作:插入、刪除、範圍查詢、分頁、排名、計數、過濾、映射、聚合等。
- 支援使用者自定義比較函數 (UDF) 實現複雜排序邏輯。
物理實現:B+樹
- 根節點:駐留於父記錄的 LDT 控制結構中。
- 分支/葉節點:對應子記錄,每個子記錄包含多個鍵值對與子指標。
- 無深度限制:B+樹可無限增長,理論上列表大小無上限 (受限於儲存容量)。
- 分裂/合併:節點滿時分裂,刪除導致稀疏時合併,由 UDF 自動維護。
父記錄
└── LDT Control (Root Pointer)
│
├── 子記錄 A (Branch Node) → 子記錄 A1, A2 (Leaf Nodes)
│
└── 子記錄 B (Branch Node) → 子記錄 B1, B2 (Leaf Nodes)
LLIST 控制結構元資料
包含以下關鍵資訊:
- 元素總數、子記錄數量、樹高度。
- 排序規則 (預設/自定義比較函數)。
- 分頁/快取配置 (頁大小、預讀頁數)。
- 儲存配置 (子記錄目標大小、壓縮開關)。
- 版本/修改時間戳 (支援樂觀鎖/一致性檢查)。
其他 LDT 類型概覽
| 類型 | 名稱 | 適用場景 |
| LLIST | 大型有序列表 | 時間序列、日誌、排行榜、歷史記錄 |
| LMAP | 大型映射 | 鍵值緩存、屬性包、會話屬性 |
| LSET | 大型集合 | 標籤系統、去重集合、權限集合 |
| LSTACK | 大型堆疊 | 事件溯源、撤銷/重做、訊息隊列 |
效能與運維考量
- 記憶體佔用:LDT 元資料常駐記憶體,子記錄按需讀取;大量 LDT 可能增加記憶體壓力。
- 寫入放大:B+樹分裂、UDF 執行開銷、子記錄獨立寫入,寫入延遲高於單純 Bin 操作。
- 讀取放大:範圍查詢需遍歷多個葉子節點 (子記錄),建議配合分頁、限制回傳數量。
- GC 與碎片:刪除操作產生子記錄碎片,依賴 UDF 定期合併/重組,需監控
ldt_gc_interval。
- 備份恢復:
asbackup/asrestore 原生支援 LDT,但耗時較長,需規劃維護窗口。
使用建議
- 評估單記錄大小是否確實超過 1MB 才考慮 LDT,否則原生 List/Map 更輕量。
- 預估元素總數與增長率,設定合理的子記錄大小 (
page_size) 平衡樹高與分裂頻率。
- 嚴格控制 UDF 複雜度,避免長時間佔用資料庫 CPU 影響叢集穩定。
- 生產環境前進行壓力測試,驗證寫入/查詢延遲、記憶體增長、GC 行為。