LevelDB介紹和內部機制

介紹

????????LevelDB 是 Google 開源的高性能鍵值對嵌入式數據庫,具有一系列設計上的優勢,特別適合寫多讀少、對存儲空間要求高效的場景。

核心優勢

1. 高寫入性能(順序寫磁盤)

  • 基于 LSM-Tree(Log Structured Merge Tree)

  • 所有寫操作首先寫入內存(memTable)+ WAL;

  • 后臺異步 flush 到磁盤,避免頻繁隨機寫;

  • 大量寫入性能遠高于 B+Tree 類數據庫(如 SQLite)。

2. 數據壓縮與空間利用率高

  • 支持 Snappy 壓縮

  • 自動 Compaction(壓縮合并) 機制;

  • 清理刪除或覆蓋的舊版本,回收磁盤空間;

  • .sst 層級結構使數據有序緊湊。

3. 支持有序遍歷與范圍查詢

  • 支持通過 Iterator 順序遍歷鍵值;

  • 可高效進行范圍查詢(Range Scan):

4. 輕量、嵌入式、依賴少

  • 無服務器(serverless),直接嵌入你的應用;

  • 單一 .a 靜態庫或 .so 動態庫,無需依賴外部組件;

  • 跨平臺支持良好(Linux、macOS、Windows)。

5. Crash-safe 崩潰恢復機制

  • 所有寫入先寫入 .log 文件(Write-Ahead Log);

  • 崩潰后可自動恢復到一致狀態;

  • 無需額外事務機制即可保證寫入安全性。

6. 支持快照(Snapshot)和原子批處理(WriteBatch)

  • Snapshot: 提供一致性讀取視圖;

  • WriteBatch: 批量寫入操作可原子提交,提升性能并簡化邏輯。

使用場景

場景類型是否適合說明
批量數據寫入? 非常適合寫優化結構(LSM-tree),順序寫性能極高
嵌入式/邊緣設備存儲? 非常適合輕量、無服務端,資源開銷小
日志系統、緩存系統? 合適大量寫入、偶爾查詢
用戶畫像、指標記錄? 合適小 key-value、高速寫入
離線分析數據落地? 合適批量寫入,偶爾按 key 掃描或查詢
查詢很少、但插入頻繁的系統? 非常合適查詢通過前置緩存減少壓力

不太適合的場景

場景類型原因
高并發讀場景(每秒幾千次以上)讀放大嚴重,需大量優化(如加 Bloom Filter、前置緩存)
大量隨機讀 + 大量隨機寫寫放大 + 查詢慢
多表 join、事務一致性需求強不支持 SQL 和事務
需要按字段查詢、復雜查詢不支持索引,只有鍵排序

數據結構

  • 內存表(MemTable):最新寫入的數據,保存在內存中。

  • Immutable MemTable:舊內存表,尚未 flush。

  • SST 文件(磁盤):排序的 Key-Value 存儲在多層磁盤文件中。

  • Block Cache(塊緩存):LevelDB 會緩存 SST 文件中的數據塊(默認 8MB)。

文件結構

  • 000123.log:正在寫的 WAL
  • 000124.sst: L0 的第一個 SST 文件
  • 000125.sst: L0 的第二個 SST 文件(寫入后產生)
  • 000130.sst: L1 的文件(Compaction 后生成)
  • MANIFEST-000001:元數據文件
  • CURRENT:指向當前 MANIFEST

memTable

????????它是數據庫打開時創建的空內存結構,用于接收寫入。

生命周期如下:

  1. DB.open(),創建一個空的 memTable

  2. 寫入數據時(put()/delete()),首先寫 WAL(Write-Ahead Log),然后寫入 memTable

  3. memTable 的大小超過閾值(writeBufferSize)時,會:

    • 將當前 memTable 移入 immutable memTable

    • 異步觸發 flush 操作,將其寫入 .sst 文件;

    • 創建新的 memTable 接收寫入。

觸發時機會怎樣?
memTable flush提高 L0 score
Compaction 完成降低某層 score,增加下一層
寫入壓力上升多文件生成,score 提高
刪除數據未及時 compactscore 居高不下,空間占用大

compactionScore 是 LevelDB 內部的一個關鍵指標,它決定是否需要觸發 Compaction(壓縮),以及優先壓縮哪個 Level。

  • 每個 Level(L0 ~ L6)都有一個 compactionScore

  • 值越大,代表該 Level 越“擁堵”,越需要被壓縮;

  • compactionScore ≥ 1.0,LevelDB 會調度一次 Compaction;

  • 通常由 VersionSet::Finalize() 計算。

JAVA客戶端配置

參數默認值說明
createIfMissingfalse如果數據庫不存在,是否自動創建(通常你會手動設為 true
errorIfExistsfalse如果數據庫已存在,是否拋出異常
paranoidChecksfalse是否進行一致性檢查
verifyChecksumsfalse讀取時是否校驗數據塊的校驗和
cacheSize8 * 1024 * 1024(8MB)內存緩存大小
blockSize4 * 1024(4KB)每個 block 的大小
writeBufferSize4 * 1024 * 1024(4MB)寫緩沖區大小
maxOpenFiles1000打開的文件數上限(僅 native JNI 實現中有效)
compressionTypeSnappy是否啟用 Snappy 壓縮

使用邏輯

寫數據流程

  1. 寫入 WAL(Write-Ahead Log)

    1. ?寫入先追加到 .log 文件(順序寫);

    2. 保證宕機后數據可恢復;

    3. 默認采用 同步寫(Sync=true)才能確保持久化;

    4. .log 文件位于 Level 0

  2. 寫入 memTable(跳表)

    1. 同步寫入內存結構 memTable

    2. 快速寫入(無鎖 skiplist),數據可被讀取;

    3. 內存中結構,不會持久化;

    4. 達到 writeBufferSize 限制(默認 4MB)后變為 immutable memTable,進入 flush。

  3. 觸發 MemTable Flush,生成 SST 文件

    1. immutable memTable 轉為 SST 文件;

    2. 寫入磁盤(SST 為排序存儲);

    3. 這些文件是查詢的主要來源(也是 compaction 的輸入);

    4. 會和已有 Level 0 文件產生重疊。

  4. 進行 Compaction(壓縮)

    1. 定期觸發(或寫壓力大時自動觸發);

    2. 將多個 SST 文件合并、去重、合并覆蓋;

    3. 數據從 L0 -> L1 -> L2 逐層下推;

    4. 保證后期查詢高效,數據唯一性提升。

舉例

執行 db.put("user123", "value1"),可能流程如下:

  1. 日志:寫入 .log 文件中(WAL);

  2. 內存:寫入到 memTable

  3. 若 memTable 滿:

    • 轉為 immutable;

    • 后臺線程 flush 成一個新的 000123.sst

  4. 觸發 compaction,將多個 sst 合并入更低 level;

  5. .log 文件在 flush 成功后被刪除。

讀取方式

  1. 先查 memTable(內存表)

    1. memTable 是當前活躍寫入的跳表結構;

    2. 有序、支持二分查找;

    3. 如果找到了 key,直接返回對應的 value。

  2. 再查 immutable memTable(只讀內存表)

    1. memTable flush 到磁盤前,會被轉為 immutable;

    2. 查詢會優先在這查找;

    3. 如果 key 存在,會返回。

  3. 然后查各層 .sst 文件(從 Level 0 開始)

    1. Level 0:
      1. 文件之間的 key 區間可能重疊;

      2. 必須逐個文件遍歷查找;

      3. 優先查最新的文件(文件編號大 → 數據新);

    2. ?Level 1~N(通常到 Level 6):
      1. 每層中的文件 key 區間互不重疊;

      2. 可以通過 key 二分定位到最多一個文件

      3. 只需要在該文件中查找一次;

  4. 使用 Bloom Filter 加速排除(配置生效)

    1. 每個 .sst 文件都可帶一個 Bloom Filter;

    2. 在讀文件前先看 Bloom Filter 是否可能包含該 key;

      1. 否 → 立即跳過;

      2. 是 → 真正讀取磁盤文件;

    3. 可大幅降低磁盤 IO 次數,特別是 key 不存在時。

  5. 讀取 Block → 解壓縮 → 查找 KV

    1. .sst 文件是由多個 Block 組成的;

    2. 使用索引塊定位 block;

    3. 如果有 Snappy 壓縮,先解壓再查找;

    4. 查到 key 返回 value,否則繼續查下一個層級。

舉例

執行 db.get("user123"),可能流程如下:

  1. 不在 memTable;

  2. immutable memTable 也沒有;

  3. 查 L0 中的 3 個文件,(Bloom Filter 排除 2 個),只查 1 個;

  4. 沒找到,再查 L1;

  5. 在 L1 的某個 .sst 文件中命中

  6. 去除文件中的block

  7. 解壓 block → 返回 value。

重啟恢復步驟

  1. 讀取 .log 文件;

  2. 重建 memTable;

  3. 保證數據一致性;

  4. 再繼續寫入。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83531.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83531.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據庫-數據查詢-Like

引言 <模糊溝通> 父親(45歲,對外謙和,對內急躁,東北口音) 兒子(18歲,邏輯思維強,喜用生活化比喻) 母親(43歲,家庭矛盾調…

SD-WAN優化云應用與多云架構訪問的關鍵策略

1. SD-WAN如何優化企業對公有云和SaaS應用的訪問? 1.1 智能流量優化 SD-WAN通過應用識別技術,可以根據不同的業務應用流量需求,動態分配網絡資源。例如,SD-WAN能夠優先為釘釘、企業微信、金山文檔等關鍵SaaS應用分配低延遲、高帶…

JVM——對象模型:JVM對象的內部機制和存在方式是怎樣的?

引入 在Java的編程宇宙中,“Everything is object”是最核心的哲學綱領。當我們寫下new Book()這樣簡單的代碼時,JVM正在幕后構建一個復雜而精妙的“數據實體”——對象。這個看似普通的對象,實則是JVM內存管理、類型系統和多態機制的基石。…

專題:2025年跨境B2B采購買家行為分析及采購渠道研究報告|附160+份報告PDF匯總下載

原文鏈接:https://tecdat.cn/?p42612 在商業決策的復雜版圖中,數據是穿透迷霧的精準坐標。本報告匯總解讀聚焦2024年跨境B2B行業核心動態,以詳實數據為錨,串聯商品出口、品牌網站運營、獨立站流量生態三大關鍵領域。我們深入挖掘…

使用spring-ai-alibaba接入大模型

spring-ai-alibaba 是Spring AI生態里與阿里巴巴相關的組件,借助它能夠實現接入各類大模型。以下為你詳細介紹如何使用 spring-ai-alibaba 接入不同大模型: 接入open ai 項目環境準備 首先要創建一個Spring Boot項目,并且在 pom.xml 里添加…

字符串的向量處理技巧:KD樹和TF-IDF向量

使用下面的技術,可以構建不用DL的搜索引擎。 向量搜索引擎使用KD-Tree KD-Tree 搭建以字符串向量為索引的樹,以 O ( l o g n ) O(logn) O(logn) 的時間復雜度快速查找到最近的向量 代碼來源:https://github.com/zhaozh10/ChatCAD/blob/ma…

Modbus TCP 轉Canopen網關連接臺達伺服驅動器的配置案例

本案例是使用歐姆龍PLC通過開疆智能ModbusTCP轉Canopen網關連接臺達A2伺服驅動器的配置案例。 配置過程: 首先打開PLC組態軟件“Sysmac Studio”,新建項目并進行配置。 編寫ModbusTCP的通訊程序。 設置連接的IP地址,端口號等參數。 設置Modb…

Vim Z 開頭的視圖滾動/折疊命令完整學習筆記

Vim Z 開頭的視圖滾動/折疊命令完整學習筆記 文章目錄 Vim Z 開頭的視圖滾動/折疊命令完整學習筆記1. 核心概念2. 垂直滾動對齊命令2.1 基礎對齊2.2 重畫增強版 3. 橫向滾動命令3.1 字符級滾動3.2 半屏滾動 4. 代碼折疊命令4.1 基礎折疊操作4.2 高級折疊操作4.3 全局折疊控制4.…

【Keepalived】Keepalived-2.3.4 已恢復對 CentOS 7 支持

之前在CentOS 7.9系統中對 Keepalived 2.3.2、2.3.3 版本進行編譯和安裝測試,都出現了編譯報錯,且官方文檔中也給出了不再支持RHEL 7的申明,但是6月10日,Keeplived-2.3.4版本在CentOS 7.9系統中編譯、安裝成功。 對于此問題&#…

Java NIO 面試全解析:9大核心考點與深度剖析

文章目錄 🚀 Java NIO 面試全解析:9大核心考點與深度剖析📌 一、基礎概念:BIO/NIO/AIO 終極對比📌 二、Buffer核心機制:狀態機設計精髓Buffer狀態機原理 📌 三、零拷貝原理:高性能IO…

C++提高編—(模板,泛型,異常處理)

一 模板 1.1 模板概論 以下圖為例子,提供了三個西裝的證件照,誰都可以取拍照,可以是小孩,男女人,也可以是某些動物等等等。n那么我們這個模板也是這樣,它可以是任何類型,基礎類型,c…

Python圖像處理基礎(六)

Python圖像處理基礎(六) 文章目錄 Python圖像處理基礎(六)3.4 雙層圖像3.5 具有更多色階的位圖數據3.6 基于調色板的圖像3.6.1 超過 256 種顏色的圖像3.7 處理透明度3.7.1 Alpha 通道3.7.2 透明調色板條目3.7.3 透明顏色3.8 隔行掃描和交替像素排序3.4 雙層圖像 某些類型的…

卷積神經網絡(一)

第七章 卷積神經網絡 從今天開始學習卷積神經網絡的內容。 本章的主題是卷積神經網絡(Convolutional Neural Network,CNN)。 CNN被用于圖像識別、語音識別等各種場合,在圖像識別的比賽中,基于 深度學習的方法幾乎都以…

OpenCV 多邊形繪制與填充

一、知識點 1、void polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, const Scalar & color, int thickness 1, int lineType LINE_8, int shift 0 ); (1)、在圖像上繪制多邊形曲線。 (2)、參數說明: img: 輸入、輸出參數&#xff0…

C#接口代碼記錄

using System;namespace InterfacesExample {// 定義接口public interface INBAPlayable{void KouLan();}public interface ISupermanable{void Fly();}// 基類public class Person{public void CHLSS(){Console.WriteLine("人類吃喝拉撒睡");}}// Student 類實現多個…

SpringDataJpa實體類中屬性順序與數據庫中生成字段順序不一致的問題

自己寫的代碼覆蓋hibernate中的代碼 翻了翻源碼發現,很多地方都是使用LinkedHashMap或者是List來傳輸Entity里面的fields,于是感覺Hibernate應該是考慮到使用Entity里面定義的fields的順序來實現建表語句里的表字段順序的。   于是就一步步跟蹤下去&…

軟件架構期末復習

題型 填空題 20分,2分/空,10空 選擇題 30分,2分/題,15題 簡答題 30分,6分/題,5題(概念+分析) 案例分析題 20分,5個小題(綜合) 分值:體系結構、設計模式各占50% 考試內容 體系結構 SA基礎(SA03PPT):SA概念、SA與軟件過程(階段)的關系、SA核心概念模型(重要…

Oracle ADG 日常巡檢指南

一、基礎狀態檢查 數據庫角色與模式 SELECT db_unique_name, open_mode, database_role, switchover_status FROM v$database;預期狀態: 主庫:OPEN_MODEREAD WRITE, DATABASE_ROLEPRIMARY備庫:OPEN_MODEREAD ONLY WITH APPLY, DATABASE_ROLE…

【MV】key_moments 與 continuous_timeline的編排權衡

一、編排順序: key_moments → continuous_timeline* 建議使用順序:key_moments → continuous_timeline ?? 兩者關系 key_moments:從continuous_timeline中精選出來的重點(約11個關鍵時間點)continuous_timeline:完整的時間軸(37個片段,覆蓋每句歌詞)?? 實際編…

Tomcat線程模型

目錄 1 Linux I/O模型 2 Linux I/O模型分類 3 Tomcat支持的I/O模型 4 Tomcat I/O模型選型 5 Tomcat NIO實現 6 Tomcat異步IO實現 1 Linux I/O模型 I/O:在計算機內存和外部設備之間拷貝數據的過程程序通過cpu向外部設備發出讀指令,數據從外部設置拷貝至內…