天天看點

6.X elasticsearch實戰學習筆記_底層原理

一、反向索引

  1. 反向索引

    詞項(term) : 搜尋時的一個機關,代表文本中某個詞

    反向索引結果是一種将詞項映射得到文檔的資料結構

  2. 反向索引建立步驟

    a. 提取詞項

    首先對文檔分詞,英文文檔用空格分隔

    去除無實際意義的詞,如is、a、in、as等

    對單詞統一大小寫

    單複數,過去式、進行時轉換

    過濾标點符号

    【本步驟,将無用的過濾掉并統一詞項格式】

    b. 建立反向索引

    将詞項映射到文檔

    【将提取的詞項,映射到文檔,一個詞項可對應多個文檔】

    c. 建立詞項出現的頻率、位置和偏移量

    文檔ID:用于根據詞項定位文檔的原始資訊

    頻率:記錄詞項在文檔出現的次數,用于搜尋相關性算分

    位置:記錄在文檔中是第幾個關鍵字,用于詞組查詢

    偏移量:記錄開始和結束的位置,用于做高亮顯示

6.X elasticsearch實戰學習筆記_底層原理

二、 底層内部原理

  1. 反向索引不可變性

    反向索引寫進磁盤永不會被改變

  • 是以無需鎖,不必擔心多程序同時修改資料問題
  • 大部分讀請求直接請求記憶體,不命中磁盤
  • 不會因為資料改變而重建緩存中資料
  • 單個大的反向索引允許資料被壓縮
  • 不支援部分文檔更新
  • 新文檔可被搜尋,需重建整個反向索引,限制索引包含資料量,索引更新頻率
  1. Lucene按段搜尋(per-segment)
  • 段檔案(segment file):存儲反向索引的檔案,每個segment是一個反向索引。文檔寫入lucene,并且生成完整的segment後才能被搜尋
  • 送出點(Commit point):記錄所有已知段的檔案
  • 事務日志(translog):防止es當機導緻資料丢失,es每次寫入資料同時寫入translog。

ps:在反向索引的不可變前提下,實作反向索引的資料增删改

  • 使用更多索引,按段搜尋
  • 一個lucene索引包含:segment的集合、Commit point檔案
  • 按segment搜尋,每個segment是一個反向索引,通過增加新的索引反應最近的修改,而不重寫整個反向索引,當有資料查詢請求,每個反向索引都被周遊,從最早的開始,查詢完後對結果合并。
  • 實作按段搜尋,索引工作流程
    1. 當新文檔被索引時,先收集到記憶體緩存
    1. (送出緩存)将緩存中對象轉換為segment存儲到磁盤,在Commit point 記錄新段資訊
    1. (開啟新段)新的段被open,此時新段包含的文檔可被搜尋
    1. 清空記憶體緩存資料,等接受新文檔
  • 文檔的删除和更新
    1. 每個Commit point 包含一個.del檔案,該檔案會列出這些被删除文檔的段資訊
    1. 當一個文檔被删時,實際隻在.del檔案中被标記删除,被标記删除的文檔依然可被查詢得到,但在最終結果被傳回前從結果集中删除
    1. 當一個文檔更新時,舊文檔被标記删除,新文檔被索引到一個新的段,兩個文檔可能被一個查詢比對到,但在結果傳回前會在結果集中删除
  • ps:段合并後,标記删除的文檔會移除
  • 查詢流程
    1. 查詢被觸發
    1. 從Commit point 擷取已知段資訊,按順序查詢所有段
    1. 聚合所有段的查詢結果
    1. 較小成本實作新文檔添加到索引
  • 按段搜尋的問題
    1. 每次commit一個新segment,需将資料fsync到實體磁盤,fsync代價大,每次索引一個文檔就fsync一次,代價很大
  1. 近實時
  • 為解決按segment搜尋的問題,先将寫入内容緩存的lucene資料轉換為segment存入檔案系統緩存,等合适時機再将檔案系統緩存中的資料送出,fsync到磁盤持久化
    1. 先将文檔寫入記憶體緩存
    1. 将記憶體緩存中資料轉為segment,存入檔案系統緩存,重新reopen,該過程是refresh(一般1秒refresh一次)
    1. 等合适時機,将檔案系統緩存中資料送出,fsync到磁盤持久化
  • 引入檔案系統緩存的遺留問題
    1. 沒flush到磁盤的資料,若發生斷電、當機,緩存資料會丢失
  • 斷電、當機資料不丢失
  • es引入translog子產品,将将資料同時寫入記憶體緩存(lucene)和translog,資料發生丢失時,可從translog重新将資料恢複
  1. es索引資料完整流程
    1. 寫lucene和translog
  • 當索引文檔(寫資料時),先将文檔寫入lucene,此時lucene在記憶體中,然後寫translog,寫成功後将請求發給使用者
    1. 使搜尋可見
  • 将記憶體中對象轉為segment,再reopen,該操作為refresh
    1. 刷Translog日志
  • 将記憶體中的translog刷到磁盤,預設5秒一次
    1. 執行lucene送出(flush)
  • 将記憶體中segment刷到磁盤,更新commit point,清空translog,打開新的translog,預設translog達到512M,flush一次
  1. 段合并
  • 自動refresh,每秒會建立一個新的segment,不加處理會導緻搜尋變慢
  • 段合并流程
    1. 合并程序選一部分大小相似的segment,在背景 合并到更大的segment,不會中斷索引和搜尋
    1. 合并結束後,老segment被删,新segment被flush到磁盤,寫入一個包含新segment且排除舊的和較小的segment,新的commit point
    1. 新的segment被用來搜尋,老的segment被删

繼續閱讀