ElasticSearch入門 第八篇:存儲

来源:http://www.cnblogs.com/ljhdo/archive/2017/05/09/5016852.html
-Advertisement-
Play Games

在ElasticSearch 2.4版本中,文檔存儲的介質分為記憶體和硬碟:記憶體速度快,但是容量有限;硬碟速度較慢,但是容量很大。同時,ElasticSearch進程自身的運行也需要記憶體空間,必須保證ElasticSearch進程有充足的運行時記憶體。為了使ElasticSearch引擎達到最佳性能,必... ...


這是ElasticSearch 2.4 版本系列的第八篇:

 

在ElasticSearch 2.4版本中,文檔存儲的介質分為記憶體和硬碟:記憶體速度快,但是容量有限;硬碟速度較慢,但是容量很大。同時,ElasticSearch進程自身的運行也需要記憶體空間,必須保證ElasticSearch進程有充足的運行時記憶體。為了使ElasticSearch引擎達到最佳性能,必須合理分配有限的記憶體和硬碟資源。

一,倒排索引(Inverted Index)

ElasticSearch引擎把文檔數據寫入到倒排索引(Inverted Index)的數據結構中,倒排索引建立的是分詞(Term)和文檔(Document)之間的映射關係,在倒排索引中,數據是面向詞(Term)而不是面向文檔的。

舉個例子,文檔和詞條之間的關係如下圖:

欄位值被分析之後,存儲在倒排索引中,倒排索引存儲的是分詞(Term)和文檔(Doc)之間的關係,簡化版的倒排索引如下圖:

從圖中可以看出,倒排索引有一個詞條的列表,每個分詞在列表中是唯一的,記錄著詞條出現的次數,以及包含詞條的文檔。實際上,ElasticSearch引擎創建的倒排索引比這個複雜得多。

1,段是倒排索引的組成部分

倒排索引是由段(Segment)組成的,段存儲在硬碟(Disk)文件中。索引段不是實時更新的,這意味著,段在寫入硬碟之後,就不再被更新。在刪除文檔時,ElasticSearch引擎把已刪除的文檔的信息存儲在一個單獨的文件中,在搜索數據時,ElasticSearch引擎首先從段中執行查詢,再從查詢結果中過濾被刪除的文檔,這意味著,段中存儲著被刪除的文檔,這使得段中含有”正常文檔“的密度降低。多個段可以通過段合併(Segment Merge)操作把“已刪除”的文檔將從段中物理刪除,把未刪除的文檔合併到一個新段中,新段中沒有”已刪除文檔“,因此,段合併操作能夠提高索引的查找速度,但是,段合併是IO密集型操作,需要消耗大量的硬碟IO。

在ElasticSearch中,大多數查詢都需要從硬碟文件(索引的段數據存儲在硬碟文件中)中獲取數據,因此,在全局配置文件elasticsearch.yml 中,把結點的路徑(Path)配置為性能較高的硬碟,能夠提高查詢性能。預設情況下,ElasticSearch使用基於安裝目錄的相對路徑來配置結點的路徑,安裝目錄由屬性path.home顯示,在home path下,ElasticSearch自動創建config,data,logs和plugins目錄,一般情況下不需要對結點路徑單獨配置。結點的文件路徑配置項:

  • path.data:設置ElasticSearch結點的索引數據保存的目錄,多個數據文件使用逗號隔開,例如,path.data: /path/to/data1,/path/to/data2;
  • path.work:設置ElasticSearch的臨時文件保存的目錄;

2,分詞和原始文本的存儲

映射參數index決定ElasticSearch引擎是否對文本欄位執行分析操作,也就是說分析操作把文本分割成一個一個的分詞,也就是標記流(Token Stream),把分詞編入索引,使分詞能夠被搜索到:

  • 當index為analyzed時,該欄位是分析欄位,ElasticSearch引擎對該欄位執行分析操作,把文本分割成分詞流,存儲在倒排索引中,使其支持全文搜索;
  • 當index為not_analyzed時,該欄位不會被分析,ElasticSearch引擎把原始文本作為單個分詞存儲在倒排索引中,不支持全文搜索,但是支持詞條級別的搜索;也就是說,欄位的原始文本不經過分析而存儲在倒排索引中,把原始文本編入索引,在搜索的過程中,查詢條件必須全部匹配整個原始文本;
  • 當index為no時,該欄位不會被存儲到倒排索引中,不會被搜索到;

欄位的原始值是否被存儲到倒排索引,是由映射參數store決定的,預設值是false,也就是,原始值不存儲到倒排索引中。

映射參數index和store的區別在於:

  • store用於獲取(Retrieve)欄位的原始值,不支持查詢,可以使用投影參數fields,對stroe屬性為true的欄位進行過濾,只獲取(Retrieve)特定的欄位,減少網路負載;
  • index用於查詢(Search)欄位,當index為analyzed時,對欄位的分詞執行全文查詢;當index為not_analyzed時,欄位的原始值作為一個分詞,只能對欄位的原始文本執行詞條查詢;

3,單個分詞的最大長度

如果設置欄位的index屬性為not_analyzed,原始文本將作為單個分詞,其最大長度跟UTF8 編碼有關,預設的最大長度是32766Bytes,如果欄位的文本超過該限制,那麼ElasticSearch將跳過(Skip)該文檔,併在Response中拋出異常消息:

operation[607]: index returned 400 _index: ebrite _type: events _id: 76860 _version: 0 error: Type: illegal_argument_exception Reason: "Document contains at least one immense term in field="event_raw" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped. Please correct the analyzer to not produce such terms. The prefix of the first immense term is: '[112, 114,... 115]...', original message: bytes can be at most 32766 in length; got 35100" CausedBy:Type: max_bytes_length_exceeded_exception Reason: "bytes can be at most 32766 in length; got 35100"

可以在欄位中設置ignore_above屬性,該屬性值指的是字元數量,而不是位元組數量;由於一個UTF8字元最多占用3個位元組,因此,可以設置

“ignore_above”:10000

這樣,超過30000位元組之後的字元將會被分析器忽略,單個分詞(Term)的最大長度是30000Bytes。

The value for ignore_above is the character count, but Lucene counts bytes. If you use UTF-8 text with many non-ASCII characters, you may want to set the limit to 32766 / 3 = 10922 since UTF-8 characters may occupy at most 3 bytes.

二,列式存儲(doc_values)

預設情況下,大多數欄位被索引之後,能夠被搜索到。倒排索引是由一個有序的詞條列表構成的,每一個詞條在列表中都是唯一存在的,通過這種數據存儲模式,你可以很快查找到包含某一個詞條的文檔列表。但是,排序和聚合操作採用相反的數據訪問模式,這兩種操作不是查找詞條以發現文檔,而是查找文檔,以發現欄位中包含的詞條。ElasticSearch使用列式存儲實現排序和聚合查詢。

文檔值(doc_values)是存儲在硬碟上的數據結構,在索引時(index time)根據文檔的原始值創建,文檔值是一個列式存儲風格的數據結構,非常適合執行存儲和聚合操作,除了字元類型的分析欄位之外,其他欄位類型都支持文檔值存儲。預設情況下,欄位的文檔值存儲是啟用的,除了字元類型的分析欄位之外。如果不需要對欄位執行排序或聚合操作,可以禁用欄位的文檔值,以節省硬碟空間。

"mappings": {
    "my_type": {
        "properties": {
        "status_code": { 
            "type":       "string",
            "index":      "not_analyzed"
        },
        "session_id": { 
            "type":       "string",
            "index":      "not_analyzed",
            "doc_values": false
        }
        }
    }
}

三,順排索引(fielddata)

字元類型的分析欄位,不支持文檔值(doc_values),但是,支持fielddata數據結構,fielddata數據結構存儲在JVM的堆記憶體中。相比文檔值(數據存儲在硬碟上),fielddata欄位(數據存儲在記憶體中)的查詢性能更高。預設情況下,ElasticSearch引擎在第一次對欄位執行聚合或排序查詢時((query-time)),創建fielddata數據結構;在後續的查詢請求中,ElasticSearch引擎使用fielddata數據結構以提高聚合和排序的查詢性能。

在ElasticSearch中,倒排索引的各個段(segment)的數據存儲在硬碟文件上,從整個倒排索引的段中讀取欄位數據之後,ElasticSearch引擎首先反轉詞條和文檔之間的關係,創建文檔和詞條之間的關係,即創建順排索引,然後把順排索引存儲在JVM的堆記憶體中。把倒排索引載入到fielddata結構是一個非常消耗硬碟IO資源的過程,因此,數據一旦被載入到記憶體,最好保持在記憶體中,直到索引段(segment)的生命周期結束。預設情況下,倒排索引的每個段(segment),都會創建相應的fielddata結構,以存儲字元類型的分析欄位值,但是,需要註意的是,分配的JVM堆記憶體是有限的,Fileddata把數據存儲在記憶體中,會占用過多的JVM堆記憶體,甚至耗盡JVM賴以正常運行的記憶體空間,反而會降低ElasticSearch引擎的查詢性能。

1,format屬性

fielddata會消耗大量的JVM記憶體,因此,儘量為JVM設置大的記憶體,不要為不必要的欄位啟用fielddata存儲。通過format參數控制是否啟用欄位的fielddata特性,字元類型的分析欄位,fielddata的預設值是paged_bytes,這就意味著,預設情況下,字元類型的分析欄位啟用fielddata存儲。一旦禁用fielddata存儲,那麼字元類型的分析欄位將不再支持排序和聚合查詢。

"mappings": {
    "my_type": {
      "properties": {
        "text": {
          "type": "string",
          "fielddata": {
            "format": "disabled" 
          }
        }
      }
    }
  }

2,載入屬性(loading)

loading屬性控制fielddata載入到記憶體的時機,可能的值是lazy,eager和eager_global_ordinals,預設值是lazy。

  • lazy:fielddata只在需要時載入到記憶體,預設情況下,在第一次搜索時,fielddata被載入到記憶體中;但是,如果查詢一個非常大的索引段(Segment),lazy載入方式會產生較大的時間延遲。
  • eager:在倒排索引的段可用之前,其數據就被載入到記憶體,eager載入方式能夠減少查詢的時間延遲,但是,有些數據可能非常冷,以至於沒有請求來查詢這些數據,但是冷數據依然被載入到記憶體中,占用緊缺的記憶體資源。
  • eager_global_ordinals:按照global ordinals積極把fielddata載入到記憶體。

四,JVM進程使用的記憶體和堆記憶體

1,配置ElasticSearch使用的記憶體

ElasticSearch使用JAVA_OPTS環境變數(Environment Variable)啟動JVM進程,在JAVA_OPTS中,最重要的配置是:-Xmx參數控制分配給JVM進程的最大記憶體,-Xms參數控制分配給JVM進程的最小記憶體。通常情況下,使用預設的配置就能滿足工程需要。

ES_HEAP_SIZE 環境變數控制分配給JVM進程的堆記憶體(Heap Memory)大小,順排索引(fielddata)的數據存儲在堆記憶體(Heap Memory)中。

2,記憶體鎖定

大多數應用程式嘗試使用儘可能多的記憶體,並儘可能把未使用的記憶體換出,但是,記憶體換出會影響ElasticSearch引擎的查詢性能,推薦啟用記憶體鎖定,禁用ElasticSearch記憶體的換進換出。

在全局配置文檔 elasticsearch.yml中,設置 bootstrap.memory_lock為ture,這將鎖定ElasticSearch進程的記憶體地址空間,阻止ElasticSearch記憶體被OS換出(Swap out)。

 

參考文檔:

Elasticsearch Reference [2.4] » Mapping » Mapping parameters


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 小狼咕咕最近開啟了微信小程式開發的徵程,由於微信小程式的前後臺通信必須通過https協議,所以小狼咕咕第一件要做的事就是配置一個能夠通過https訪問的後臺服務。小狼咕咕用的是阿裡雲ECS伺服器,Linux系統,安裝的tomcat。 打開阿裡雲盾——CA證書服務,找不到的朋友也可以在下圖的菜單中直接 ...
  • 如果轉載,請註明博文來源: www.cnblogs.com/xinysu/ ,版權歸 博客園 蘇家小蘿蔔 所有。望各位支持! 1 行記錄如何存儲 這裡引入兩個概念:堆跟聚集索引表。本部分參考MSDN。 1.1 堆表 堆表,沒有聚集索引的表格,可以創建一個或者多個非聚集索引。沒有按照某個規則進行存儲, ...
  • 一.準備教程 1.jdk:版本在1.7.x以上就可以(因為hadoop2.x以上只支持1.7.x以上的jdk,我的是1.8的) 2.Hadoop:2.7.3 二.ssh的配置以及驗證 配置ssh: 1.確認mac的遠程登錄是否開啟 系統偏好設置->共用->勾選遠程登錄. 當遠程登錄狀態為打開且為綠燈 ...
  • 表分區是一種思想,分區表示一種技術實現。當表的大小過G的時候可以考慮進行表分區,提高查詢效率,均衡IO。oracle分區表是oracle資料庫提供的一種表分區的實現形式。表進行分區後,邏輯上仍然是一張表,原來的查詢SQL同樣生效,同時可以採用使用分區查詢來優化SQL查詢效率,不至於每次都掃描整個表。 ...
  • 前段時間一個測試環境的mysql資料庫的root密碼找不到了,一個不重要的庫,安裝人員估計疏忽了...手動把密碼恢復了一下。記錄下來做個備註 1、進入my.cnf ,在[mysqld]欄位中添加 skip-grant-tables 2、重啟mysql服務 service mysqld restart ...
  • 在資料庫中,很多人員習慣使用SELECT COUNT(*)、SELECT COUNT(1)、SELECT COUNT(COL)來查詢一個表有多少記錄,對於小表,這種SQL的開銷倒不是很大,但是對於大表,這種查詢表記錄數的做法就是一個非常消耗資源了,而且效率很差。下麵介紹一下SQL Server、 O... ...
  • 問題: 兩張表 數據都非常多 A表中A1欄位 需要關聯B表主鍵 查詢 A1 欄位 存儲多個B表主鍵 格式為: 格式1:b1,b2,b3 格式2:b4 格式3:b5,b6 逗號分隔的占少數 這樣就導致在做關聯查詢時,必須使用 like '%...%', charindex ,又或者replace(A1 ...
  • " 1、視圖理論 " "1.1、視圖的存儲" "1.2、視圖的作用" "1.3、視圖的工作機制" "1.4、視圖的依賴性" "1.5、可更新的連接視圖" "1.6、內聯視圖" " 2、物化視圖 " "2.1、刷新物化視圖" "2.2、物化視圖日誌" "2.3、管理物化視圖" "2.4、物化視圖與索引 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...