成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Quickwit 101 - 基于對象存儲的分布式搜索引擎架構

開發 架構
你可能會疑惑,Quickwit 如何能夠在索引器每 10 秒提交一次的情況下生成包含 1000 萬份文檔的 split。答案在于 Quickwit 的合并管道,它負責將一組 split 合并,直到達到一定數量的文檔。

在本文中,我們將深入探討 Quickwit 的架構及其關鍵組件。本文與 Quickwit 的基準測試 配合閱讀效果更佳,該測試基于一個 23TB 的數據集。

  • https://quickwit.io/blog/benchmarking-quickwit-engine-on-an-adversarial-dataset

Quickwit 標志的靈感來源于 Paul 的想法,即軟件和動態藝術具有一種有趣的共性。如果你觀看 Theo Jansen 的作品,你會看到迷人的風力驅動雕塑在海灘上行走,其復雜程度讓人難以理解其工作原理。這種神秘感也類似于使用軟件的感受。當我們查看大型代碼庫時,這些復雜的構造能夠正常運行似乎有些神奇……然而,大多數時候它們確實可以正常工作。

  • https://github.com/fulmicoton
  • https://www.youtube.com/watch?v=LewVEF2B_pM&ab_channel=theojansen

但我們是工程師!我們不滿足于神奇的現象,我們想要了解事物的工作原理,并且不會僅僅因為軟件的美觀而做出決定……(是嗎?)。確實,如果我們不想讓引擎在關鍵時刻出問題并且能夠安心睡覺的話(我也犯過很多這樣的錯誤……),理解引擎內部工作原理是非常重要的。沒有必要涵蓋所有細節,建立一個系統的良好心理模型就足夠了,這樣可以理解它的局限性和如何高效地使用它。

這就是本文的目的:深入探討 Quickwit 的架構及其關鍵組件,以便你可以建立一個簡潔準確的系統心理模型?,F在讓我們開始吧!

計算與存儲解耦

Quickwit 架構的核心原則是計算與存儲的分離。我們的方法與 Datadog 通過 Husky 所做的非常相似(但早于他們),目標也是相同的:成本效益和可擴展性,同時避免集群管理的噩夢。

  • https://www.datadoghq.com/blog/engineering/introducing-husky/

這種方法使我們將索引(寫路徑)和搜索(讀路徑)完全分開。索引器和搜索器通過元存儲共享相同的世界視圖。索引器向存儲寫入數據并更新元存儲,而搜索器從存儲和元存儲讀取數據。

在當前的 Quickwit 中,元存儲通常由 PostgreSQL 數據庫支持。但是 Quickwit 還有一個更簡單的實現,其中元存儲由存儲在對象存儲上的簡單 JSON 文件支持;對于簡單的情況,無需依賴外部數據庫。這是本文選擇的配置。

圖片圖片

索引

為了向 Quickwit 提供數據,你通常會將 JSON 文檔發送到索引器的攝入 API。索引器然后對這些文檔進行“索引”:它將文檔流分割成短批次,并為每個批次創建一個索引片段(具體來說是一個文件)。我們可以配置生成這些片段的時間間隔(參見 commit_timeout_secs)。這些片段隨后上傳到 S3。

  • https://quickwit.io/docs/configuration/index-config#indexing-settings

在上傳開始時,索引器將元存儲中的片段元數據標記為 Staged。一旦上傳完成,狀態變為 Published,表示片段可用于搜索。從文檔攝入到搜索準備好的時間間隔稱為“搜索時間”,大致等于 commit_timeout_secs + upload_time。

這些步驟由一個處理管道實現,詳細信息見此 相關文章。

  • https://quickwit.io/blog/quickwit-actor-framework

圖片圖片

解析 ‘Split’

為了提供搜索查詢的上下文,理解 “split” 包含的內容至關重要,因為這是索引的數據單位。它是一個獨立的索引,具有自己的模式,并且包含了針對快速有效搜索和分析操作優化的數據結構:

  • 倒排索引:用于全文搜索。對于那些想深入了解的人,我強烈推薦閱讀 fulmicoton 的博客文章 1 和 2。

https://twitter.com/fulmicoton

https://fulmicoton.com/posts/behold-tantivy/

https://fulmicoton.com/posts/behold-tantivy-part2/

  • 列式存儲:用于排序和分析目的。
  • 行式存儲:用于根據文檔 ID 檢索文檔。
  • 熱緩存:可以將其視為索引的藍圖。包含前面數據結構的元數據,確保搜索器僅檢索必要的數據。熱緩存是搜索器檢索的第一部分數據;通常保留在內存中。

為了說明這一點,我們來看一個實際例子:一個包含 1000 萬條 GitHub 歸檔事件的 split,其中所有文檔字段都啟用了所有數據結構。

圖片圖片

split 的大小約為 15GB。與未壓縮的文檔大小相比,其壓縮比接近 3。需要注意的是,可以通過僅在相關字段上啟用特定存儲來優化這一比率。

最后,熱緩存具有一個很好的特性:它占 split 大小的比例不到 0.1%,大約 10MB,這意味著它可以輕松地放入 RAM 中。

關于合并的一點說明

你可能會疑惑,Quickwit 如何能夠在索引器每 10 秒提交一次的情況下生成包含 1000 萬份文檔的 split。答案在于 Quickwit 的合并管道,它負責將一組 split 合并,直到達到一定數量的文檔。這主要有兩個原因:

  • 性能提升:你不希望在每次搜索請求時打開許多小的 split。這也大大減少了元存儲需要處理的數據量。通過合并,我們最終可以在 PostgreSQL 中為每 1000 萬份文檔保留一行記錄。
  • 成本效益:你希望限制每次搜索請求中的 GET 請求次數。

搜索

在讀取側,當搜索器接收到搜索請求時,它會經歷以下步驟:

  1. 元存儲檢索:搜索器獲取 metastore.json 文件。
  2. split 列表:列出與搜索請求相關的 split。這一階段特別利用了搜索請求的時間范圍來排除不符合時間范圍的 split。
  3. 葉搜索執行:對于每個 split,執行并發的「葉搜索」。它包括:

(IO) 獲取 split 的熱緩存。

(IO) 預熱階段:對于每個詞條,它獲取發布列表的字節范圍,然后獲取發布列表本身。如果有必要,它還會獲取搜索所需的定位信息和列。為了便于閱讀,預熱階段在下面的圖表中表示為單一的獲取,但實際上可能是多次獲取。

(CPU) 搜索階段:在 split 上運行查詢。

  1. 結果聚合:聚合葉搜索的結果。
  2. 文檔獲取:搜索器從相關 split 中獲取文檔。
  3. 結果返回:最終將匹配的文檔和/或聚合返回給用戶。

這導致了以下讀取路徑:

圖片圖片

元存儲

讓我們回到索引器和搜索器共享的視圖:元存儲。它存儲了我們在前幾節部分看到的關于索引的關鍵信息:

  • 索引配置:文檔映射、時間戳字段、合并策略等。
  • split 元數據:如果你的數據集有一個時間字段,Quickwit 會特別存儲每個 split 的最小和最大時間戳值,從而在搜索時啟用基于時間的過濾。
  • 檢查點:對于每個數據源,一個“源檢查點”記錄了已處理的文檔的截止點。如果你使用 Kafka 作為數據源,檢查點包含每個分區的起始和結束偏移量,這些偏移量被索引到 Quickwit 中。這解鎖了恰好一次語義。

元存儲可以由 PostgreSQL 或存儲在對象存儲上的單個 JSON 文件支持。后者用于本文,因為它是最簡單的配置。以下是元存儲內容的一個快照:

metastore.json

{
    "index_uri": "s3://indexes/{my-index}",
    "index_config": {...},
    "splits": [
        {
            "split_id": "...",
            "num_docs": 10060714,
            "split_state": "Published",
            "time_range": {
                "start": 1691719200,
                "end": 1691936694
            },
            "split_footer": {
              "start": 1612940400,
              "end": 1616529599
            }
            ...
        }
    ],
    "checkpoints": {
      "a": "00000000000000000128",
      "b": "00000000000000060187",
      ...
    }
}

你注意到那個令人好奇的 split_footer 字段了嗎?那是……熱緩存的字節范圍!

分布式索引和搜索

分布式索引和搜索引入了一些挑戰:

  • 集群形成:Quickwit 使用了一個名為 Chitchat 的開源實現來形成集群,這個實現基于 Scuttlebutt。

https://quickwit.io/docs/overview/architecture#cluster-formation

https://www.cs.cornell.edu/home/rvr/papers/flowgossip.pdf

  • 元存儲寫入:在寫入路徑上,只有一個進程應該處理對元存儲文件的寫入。為此,一個單獨的 metastore 角色實例讀取/寫入 JSON 文件。其他集群成員向此實例發送讀取/寫入 gRPC 請求。
  • 索引任務分配:一個控制平面角色負責將索引任務分配給各個索引器。
  • 搜索工作負載分配:這需要一個 Map-Reduce 機制。接收搜索請求的搜索器承擔“根”角色,將葉子請求委托給“葉子節點”,然后聚合并返回結果。

以下是寫入路徑的可視化表示:

圖片圖片

類似地,對于讀取路徑:

圖片圖片

要進行更深入的了解,請參閱我們的 文檔。

  • https://quickwit.io/docs/overview/architecture
責任編輯:武曉燕 來源: 黑客下午茶
相關推薦

2022-08-15 14:56:30

搜索引擎分布式

2014-11-25 10:09:59

ElasticSear分布式搜索引擎Lucene

2020-07-31 09:55:27

Linux分布式Elasticsear

2011-06-20 18:23:06

SEO

2019-07-10 13:17:07

大數據搜索代碼

2022-10-14 07:42:50

LuceneHTTPWeb

2009-02-19 09:41:36

搜索引擎搜狐百度

2009-09-22 16:23:52

搜索引擎

2018-10-16 14:26:22

分布式塊存儲引擎

2020-03-20 10:14:49

搜索引擎倒排索引

2017-08-07 08:15:31

搜索引擎倒排

2024-03-18 00:00:01

分布式搜索引擎

2016-12-26 13:41:19

大數據搜索引擎工作原理

2010-06-13 16:27:28

搜索引擎

2023-12-07 09:17:44

java分布式

2010-04-20 11:43:46

2022-10-08 09:13:18

搜索引擎?站

2012-09-07 13:22:21

搜索搜狗

2025-05-16 08:58:47

Mongodb分布式存儲

2011-06-22 17:28:51

SEO
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲444kkkk在线观看最新 | 免费一级黄 | www国产亚洲精品 | 又黄又色 | av资源中文在线 | 国产美女黄色片 | 成人精品国产一区二区4080 | 国产精品一级在线观看 | 在线观看国产视频 | 国产高清视频一区 | 国产一区二区自拍 | 天堂久久久久久久 | 精品国产成人 | 嫩草影院网址 | 精品视频网 | 91 中文字幕 | 欧美一区 | 成人精品国产免费网站 | 波多野结衣一区二区三区在线观看 | 欧美一级一 | 性做久久久久久免费观看欧美 | 欧美一区二区在线免费观看 | 午夜免费视频 | 亚洲一区精品在线 | 亚洲一区中文字幕 | 日韩在线视频精品 | 中日韩欧美一级片 | 久久国产一区二区三区 | 亚洲精品国产电影 | 国产精品久久久久久久久久 | 99reav| 久久国产视频网站 | 成人性生交大片免费看r链接 | xxx.在线观看 | 欧洲精品一区 | 涩涩视频网站在线观看 | 九九热在线视频免费观看 | 黄色欧美视频 | 在线中文字幕日韩 | 亚洲精品在线免费观看视频 | 国产精品久久久久久久久久久久久久 |