chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

數據結構LSM tree核心實現講解

數據分析與開發(fā) ? 來源:sowhat1412 ? 作者:sowhat1412 ? 2021-09-30 14:19 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

LSM tree (log-structured merge-tree) 是一種對頻繁寫操作非常友好的數據結構,同時兼顧了查詢效率。LSM tree 是許多 key-value 型或日志型數據庫所依賴的核心數據結構,例如 BigTable、HBase、Cassandra、LevelDB、SQLite、Scylla、RocksDB 等。

LSM tree 之所以有效是基于以下事實:磁盤或內存的連續(xù)讀寫性能遠高于隨機讀寫性能,有時候這種差距可以達到三個數量級之高。這種現象不僅對傳統(tǒng)的機械硬盤成立,對 SSD 硬盤也同樣成立。如下圖:

LSM tree 在工作過程中盡可能避免隨機讀寫,充分發(fā)揮了磁盤連續(xù)讀寫的性能優(yōu)勢。

SSTable

LSM tree 持久化到硬盤上之后的結構稱為 Sorted Strings Table (SSTable)。顧名思義,SSTable 保存了排序后的數據(實際上是按照 key 排序的 key-value 對)。每個 SSTable 可以包含多個存儲數據的文件,稱為 segment,每個 segment 內部都是有序的,但不同 segment 之間沒有順序關系。一個 segment 一旦生成便不再修改(immutable)。一個 SSTable 的示例如下:

可以看到,每個 segment 內部的數據都是按照 key 排序的。下面我們來介紹每個 segment 是如何生成的。

寫入數據

LSM tree 的所有寫操作均為連續(xù)寫,因此效率非常高。但由于外部數據是無序到來的,如果無腦連續(xù)寫入到 segment,顯然是不能保證順序的。對此,LSM tree 會在內存中構造一個有序數據結構(稱為 memtable),例如紅黑樹。每條新到達的數據都插入到該紅黑樹中,從而始終保持數據有序。當寫入的數據量達到一定閾值時,將觸發(fā)紅黑樹的 flush 操作,把所有排好序的數據一次性寫入到硬盤中(該過程為連續(xù)寫),生成一個新的 segment。而之后紅黑樹便從零開始下一輪積攢數據的過程。

讀取/查詢數據

如何從 SSTable 中查詢一條特定的數據呢?一個最簡單直接的辦法是掃描所有的 segment,直到找到所查詢的 key 為止。通常應該從最新的 segment 掃描,依次到最老的 segment,這是因為越是最近的數據越可能被用戶查詢,把最近的數據優(yōu)先掃描能夠提高平均查詢速度。

當掃描某個特定的 segment 時,由于該 segment 內部的數據是有序的,因此可以使用二分查找的方式,在

O(logn) 的時間內得到查詢結果。但對于二分查找來說,要么一次性把數據全部讀入內存,要么在每次二分時都消耗一次磁盤 IO,當 segment 非常大時(這種情況在大數據場景下司空見慣),這兩種情況的代價都非常高。一個簡單的優(yōu)化策略是,在內存中維護一個稀疏索引(sparse index),其結構如下圖:

稀疏索引是指將有序數據切分成(固定大小的)塊,僅對各個塊開頭的一條數據做索引。與之相對的是全量索引(dense index),即對全部數據編制索引,其中的任意一條數據發(fā)生增刪均需要更新索引。兩者相比,全量索引的查詢效率更高,達到了理論極限值

O(logn),但寫入和刪除效率更低,因為每次數據增刪時均需要因為更新索引而消耗一次 IO 操作。通常的關系型數據庫,例如 MySQL 等,其內部采用 B tree 作為索引結構,這便是一種全量索引。

有了稀疏索引之后,可以先在索引表中使用二分查找快速定位某個 key 位于哪一小塊數據中,然后僅從磁盤中讀取這一塊數據即可獲得最終查詢結果,此時加載的數據量僅僅是整個 segment 的一小部分,因此 IO 代價較小。以上圖為例,假設我們要查詢 dollar 所對應的 value。首先在稀疏索引表中進行二分查找,定位到 dollar 應該位于 dog 和 downgrade 之間,對應的 offset 為 17208~19504。之后去磁盤中讀取該范圍內的全部數據,然后再次進行二分查找即可找到結果,或確定結果不存在。

稀疏索引極大地提高了查詢性能,然而有一種極端情況卻會造成查詢性能驟降:當要查詢的結果在 SSTable 中不存在時,我們將不得不依次掃描完所有的 segment,這是最差的一種情況。有一種稱為**布隆過濾器(bloom filter)**的數據結構天然適合解決該問題。布隆過濾器是一種空間效率極高的算法,能夠快速地檢測一條數據是否在數據集中存在。我們只需要在寫入每條數據之前先在布隆過濾器中登記一下,在查詢時即可斷定某條數據是否缺失。

布隆過濾器的內部依賴于哈希算法,當檢測某一條數據是否見過時,有一定概率出現假陽性(False Positive),但一定不會出現假陰性(False Negative)。也就是說,當布隆過濾器認為一條數據出現過,那么該條數據很可能出現過;但如果布隆過濾器認為一條數據沒出現過,那么該條數據一定沒出現過。這種特性剛好與此處的需求相契合,即檢驗某條數據是否缺失。

文件合并(Compaction)

隨著數據的不斷積累,SSTable 將會產生越來越多的 segment,導致查詢時掃描文件的 IO 次數增多,效率降低,因此需要有一種機制來控制 segment 的數量。對此,LSM tree 會定期執(zhí)行文件合并(compaction)操作,將多個 segment 合并成一個較大的 segment,隨后將舊的 segment 清理掉。由于每個 segment 內部的數據都是有序的,合并過程類似于歸并排序,效率很高,只需要

O(n)O(n)的時間復雜度。

在上圖的示例中,segment 1 和 2 中都存在 key 為 dog 的數據,這時應該以最新的 segment 為準,因此合并后的值取 84 而不是 52,這實現了類似于字典/HashMap 中“覆蓋寫”的語義。

刪除數據

現在你已經了解了 LSM tree 讀寫數據的方式,那么如何刪除數據呢?如果是在內存中,刪除某塊數據通常是將它的引用指向 NULL,那么這塊內存就會被回收。但現在的情況是,數據已經存儲在硬盤中,要從一個 segment 文件中間抹除一段數據必須要覆寫其之后的所有內容,這個成本非常高。LSM tree 所采用的做法是設計一個特殊的標志位,稱為 tombstone(墓碑),刪除一條數據就是把它的 value 置為墓碑,如下圖所示:

這個例子展示了刪除 segment 2 中的 dog 之后的效果。注意,此時 segment 1 中仍然保留著 dog 的舊數據,如果我們查詢 dog,那么應該返回空,而不是 52。因此,刪除操作的本質是覆蓋寫,而不是清除一條數據,這一點初看起來不太符合常識。墓碑會在 compact 操作中被清理掉,于是置為墓碑的數據在新的 segment 中將不復存在。

LSM tree 與 B tree 的對比

主流的關系型數據庫均以 B/B+ tree 作為其構建索引的數據結構,這是因為 B tree 提供了理論上最高的查詢效率 O(log n)

O(logn)。但對查詢性能的追求也造成了 B tree 的相應缺點,即每次插入或刪除一條數據時,均需要更新索引,從而造成一次磁盤 IO。這種特性決定了 B tree 只適用于頻繁讀、較少寫的場景。如果在頻繁寫的場景下,將造成大量的磁盤 IO,從而導致性能驟降。這種應用場景在傳統(tǒng)的關系型數據庫中比較常見。

而 LSM tree 則避免了頻繁寫場景下的磁盤 IO 開銷,盡管其查詢效率無法達到理想的 O(log n)

O(logn),但依然非???,可以接受。所以從本質上來說,LSM tree 相當于犧牲了一部分查詢性能,換取了可觀的寫入性能。這對于 key-value 型或日志型數據庫是非常重要的。

總結

LSM tree 存儲引擎的工作原理包含以下幾個要點:

寫數據時,首先將數據緩存到內存中的一個有序樹結構中(稱為 memtable)。同時觸發(fā)相關結構的更新,例如布隆過濾器、稀疏索引。

當 memtable 積累到足夠大時,會一次性寫入磁盤中,生成一個內部有序的 segment 文件。該過程為連續(xù)寫,因此效率極高。

進行查詢時,首先檢查布隆過濾器。如果布隆過濾器報告數據不存在,則直接返回不存在。否則,按照從新到老的順序依次查詢每個 segment。

在查詢每個 segment 時,首先使用二分搜索檢索對應的稀疏索引,找到數據所在的 offset 范圍。然后讀取磁盤上該范圍內的數據,再次進行二分查找并獲得結果。

對于大量的 segment 文件,定期在后臺執(zhí)行 compaction 操作,將多個文件合并為更大的文件,以保證查詢效率不衰減。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7324

    瀏覽量

    94286
  • SSD
    SSD
    +關注

    關注

    21

    文章

    3080

    瀏覽量

    122071
  • 過濾器
    +關注

    關注

    1

    文章

    444

    瀏覽量

    20904

原文標題:一種對頻繁寫操作非常友好的數據結構(核心實現講解)

文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發(fā)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    STM32H5開發(fā)陀螺儀LSM6DSV16X(1)----輪詢獲取陀螺儀數據

    本文將介紹如何通過輪詢(Polling)方式從LSM6DSV16X六軸慣性傳感器中獲取陀螺儀數據。輪詢模式是一種常用的傳感器讀取方式,主控MCU定期查詢陀螺儀輸出寄存器,無需依賴中斷機制即可實現
    的頭像 發(fā)表于 12-22 17:28 ?4407次閱讀
    STM32H5開發(fā)陀螺儀<b class='flag-5'>LSM</b>6DSV16X(1)----輪詢獲取陀螺儀<b class='flag-5'>數據</b>

    意法半導體LSM6DSV320X IMU傳感器在Linux平臺的驅動移植與姿態(tài)感知應用實現

    本期我們聚焦論壇網友短笛君的實測體驗。他首先分享了MEMS上位機體驗并進行MLC數據預采集,隨后實現LSM6DSV320X IMU傳感器在Linux平臺的驅動移植,并開發(fā)具備四元數和歐拉角解算的完整姿態(tài)感知應用,最后
    的頭像 發(fā)表于 12-11 14:31 ?6869次閱讀
    意法半導體<b class='flag-5'>LSM</b>6DSV320X IMU傳感器在Linux平臺的驅動移植與姿態(tài)感知應用<b class='flag-5'>實現</b>

    typedef結構體使用

    雖然結構體的出現能夠讓我們有一個更科學的數據結構來管理數據,但是每次使用結構體都需要struct...,未免顯得有些冗長和麻煩。有了typedef的助攻,我們就可以很輕松地給
    發(fā)表于 12-08 07:04

    `lv_obj_tree.h` 在 **LVGL v9** 中的位置和作用

    )已經封裝了這些邏輯,無需直接包含 lv_obj_tree.h。 總結 lv_obj_tree.h 是 LVGL 內部管理對象樹結構核心頭文件,位于 src/core/ 目錄,主要供
    發(fā)表于 11-13 15:49

    LSM6DSV16BX:集成機器學習核心與Qvar感應的先進慣性測量單元

    加速度、角速度和Qvar檢測數據。它具有專用配置、處理和濾波功能。LSM6DSV16BX在緊湊型封裝 (2.5mm x 3.0mm x 0.71mm) 中集成了UI傳感器、音頻加速度計和Qvar傳感器。
    的頭像 發(fā)表于 10-28 13:45 ?435次閱讀
    <b class='flag-5'>LSM</b>6DSV16BX:集成機器學習<b class='flag-5'>核心</b>與Qvar感應的先進慣性測量單元

    LSM6DSV16X:集成機器學習與靜電感應的高性能慣性測量單元

    STMicroelectronics LSM6DSV16X iNEMO慣性模塊是一款三軸數字加速度計和三軸數字陀螺儀。 LSM6DSV16X具有三個內核,用于處理三個獨立通道上的加速度和角速率數據
    的頭像 發(fā)表于 10-28 11:52 ?557次閱讀
    <b class='flag-5'>LSM</b>6DSV16X:集成機器學習與靜電感應的高性能慣性測量單元

    LSM6DSV iNEMO?慣性模塊:為下一代智能設備提供高性能運動感知

    的配置、濾波和處理功能。LSM6DSV在高性能模式下提升性能(0.65mA時),具有不間斷低功耗特性,實現最佳的消費者運動體驗。該器件嵌入了高級專用功能,例如有限狀態(tài)機和數據濾波,用于OIS、EIS和運動處理。
    的頭像 發(fā)表于 10-28 11:25 ?508次閱讀
    <b class='flag-5'>LSM</b>6DSV iNEMO?慣性模塊:為下一代智能設備提供高性能運動感知

    基于LSM6DSO16IS適配板數據手冊的技術解析與應用指南

    STMicroelectronics STEVAL-MKI229A適配器板用于評估LSM6DSO16IS MEMS器件。該板提供了有效、快速的系統(tǒng)原型設計解決方案,可直接在用戶的’應用程序內評估。
    的頭像 發(fā)表于 10-27 11:03 ?460次閱讀
    基于<b class='flag-5'>LSM</b>6DSO16IS適配板<b class='flag-5'>數據</b>手冊的技術解析與應用指南

    LSM6DSV16B:面向TWS與可穿戴設備的6軸IMU,融合傳感與低功耗智能

    于提供精確的加速度和角速度感測數據處理。 LSM6DSV16B具有專用于運動跟蹤、設備電源管理、游戲3D頭部跟蹤和增強音頻體驗的雙通道,提供無與倫比的多用性和功能。該器件還具有單獨通道,用于通過專用配置、處理和濾波實現振動檢測
    的頭像 發(fā)表于 10-25 14:28 ?987次閱讀
    <b class='flag-5'>LSM</b>6DSV16B:面向TWS與可穿戴設備的6軸IMU,融合傳感與低功耗智能

    LSM6DSV80X 6軸慣性測量單元技術解析

    STMicroelectronics LSM6DSV80X 6軸慣性測量單元 (IMU) 在單個元件中集成了兩個加速度計結構,可實現16g和80g的全量程傳感、嵌入式智能以及高達4000dps
    的頭像 發(fā)表于 10-15 17:42 ?740次閱讀
    <b class='flag-5'>LSM</b>6DSV80X 6軸慣性測量單元技術解析

    分享一個嵌入式學習階段規(guī)劃

    給大家分享一個嵌入式學習階段規(guī)劃: (一)基礎筑牢階段(約 23 天) 核心目標:打牢 C 語言、數據結構、電路基礎C 語言開發(fā):學變量 / 指針 / 結構體等核心語法,用 Dev-
    發(fā)表于 09-12 15:11

    【HZ-T536開發(fā)板免費體驗】6、使用protoc-gen-gorm生成標準化的數據結構

    在設計espnow協議的時候,考慮到我需要在esp32,Linux設備,web上使用相同的數據結構,那就需要考慮一下,是否使用一個通用的跨平臺序列化數據結構。這時候我想起了protobuf,這個就是
    發(fā)表于 08-26 00:32

    程序設計與數據結構

    的地址)出發(fā),采用推導的方式,深入淺出的分析了廣大C程序員學習和開發(fā)中遇到的難點。 2. 從方法論的高度對C語言在數據結構和算法方面的應用進行了深入講解和闡述。 3. 講解了絕大多數C程序員開發(fā)
    發(fā)表于 05-13 16:45

    RK3588 EVB開發(fā)板原理圖講解【八】 RK3588 power Tree

    本帖最后由 瑞芯微方案開發(fā)老王 于 2025-3-1 11:41 編輯 一、RK3588電源架構核心特點 ?多電源域設計? 芯片通常劃分為多個獨立電源域(Power Domain),例如
    發(fā)表于 03-01 11:38

    結構數據中臺:企業(yè)AI應用安全落地的核心引擎

    在數字化轉型浪潮中,非結構數據(如文檔、圖片、音視頻等)已成為企業(yè)核心資產,其價值挖掘能力直接影響AI應用的效能與安全性。然而,數據分散、多模態(tài)處理復雜、安全合規(guī)風險高等問題,嚴重制
    的頭像 發(fā)表于 02-27 17:06 ?960次閱讀