當前位置:首頁 » 存儲配置 » elasticsearch存儲結構

elasticsearch存儲結構

發布時間: 2022-10-08 15:24:41

㈠ Elasticsearch

Elasticsearch是一個基於Lucene的實時分布式的搜索與分析引擎。Elasticsearch為所有類型的數據提供近乎實時的搜索和分析。無論結構化或非結構化文本、數字數據還是地理空間數據,Elasticsearch都可以有效地存儲和索引,以支持快速搜索。隨著你的數據和查詢量的增長,Elasticsearch的分布式特性使部署能夠隨著它而無縫增長。

Elasticsearch是一個 分布式文檔存儲 。Elasticsearch不是將信息存儲為列式數據行,而是存儲已序列化為JSON文檔的復雜數據結構。當集群中有多個Elasticsearch節點時,存儲的文檔會分布在整個集群中,並且可以從任何節點立即訪問

存儲文檔後,它會在近乎實時的情況下被索引並完全可搜索——1秒內。Elasticsearch使用一種稱為倒排索引的數據結構,它支持非常快速的全文搜索。倒排索引列出了出現在任何文檔中的每個唯一單詞,並標識了每個單詞出現的所有文檔。

索引是文檔的優化集合,每個文檔都是欄位的集合,欄位是包含數據的鍵值對。 默認情況下,Elasticsearch對每個欄位中的所有數據進行索引,並且每個索引欄位都有一個專用的優化數據結構。

Elasticsearch還具有無預定數據模式(schema-less)的能力,這意味著無需明確指定如何處理文檔中可能出現的每個不同欄位即可對文檔進行索引。啟用動態映射後,Elasticsearch會自動檢測新欄位並將其添加到索引中。只要開始索引文檔,Elasticsearch就會檢測並將布爾值、浮點和整數值、日期和字元串映射到適當的Elasticsearch數據類型。也可以定義規則來控制動態映射,明確定義映射以完全控制欄位的存儲和索引方式。

Elasticsearch提供了一個簡單REST API,用於管理集群以及索引和搜索數據。可以直接從命令行、應用程序客戶端或通過Kibana中的開發者控制台輕松提交請求。

Elasticsearch REST API支持結構化查詢、全文查詢和將兩者結合的復雜查詢。結構化查詢類似於在sql中構造的查詢類型。全文查詢查找與查詢字元串匹配的所有文檔,並按與搜索詞的匹配程度對它們進行排序。

除了搜索單個術語之外,還可以執行短語搜索、相似性搜索和前綴搜索。可以使用 Elasticsearch全面的JSON樣式查詢語言 (Query DSL) 訪問所有這些搜索功能。 您還可以構建SQL樣式的查詢以在Elasticsearch內本地搜索和聚合數據。

建議使用三個主節點三個數據節點集群,這里是演示

環境規劃

Index moles

Index management

可以通過Kibana Management或ILM API創建和管理索引生命周期策略。當您為Beats或Logstash Elasticsearch輸出插件啟用索引生命周期管理時,默認策略是自動配置的。

索引生命周期階段共分為五個階段:

在為日誌或指標等時間序列數據編制索引時,不能無限期地寫入單個索引。 為了滿足索引和搜索性能要求並管理資源使用情況,寫入索引直到滿足某個閾值,然後創建一個新索引並開始寫入它。 使用滾動索引能夠達到以下效果:

ILM能夠根據索引大小、文檔計數或年齡自動滾動到新索引。 當觸發 Rollover 時,會創建一個新索引,寫入別名會更新為指向新索引,所有後續更新都會寫入新索引。

索引生命周期操作

配置生命周期策略

啟動和停止索引生命周期管理

命令使用均已運行用戶執行

elasticsearch-keystore 命令管理 Elasticsearch 密鑰庫中的安全設置。

elasticsearch-node命令能夠在節點上執行某些不安全的操作,這些操作只能在關閉時執行。 此命令允許您調整節點的角色,不安全地編輯集群設置,並且即使在與磁碟上的數據不兼容的情況下,也可以在災難後恢復某些數據或啟動節點。

創建、列出和刪除基於文件的服務賬戶令牌。當創建第一個服務帳戶令牌時,此命令會在 $ES_HOME/config 目錄中創建一個 service_tokens 文件。 該文件默認不存在。Elasticsearch監視此文件的更改並動態重新載入它.

設置內置用戶的密碼。此命令僅供在Elasticsearch安全功能的初始配置期間使用。 它使用彈性引導密碼來運行用戶管理API請求。 如果Elasticsearch密鑰庫受密碼保護,則必須先輸入密鑰庫密碼,然後才能為內置用戶設置密碼。 為彈性用戶設置密碼後,引導密碼不再有效,無法使用該命令。

在某些情況下,分片副本的Lucene索引或事務日誌可能會損壞。 elasticsearch-shard命令能夠在無法自動恢復或從備份恢復的分片的良好副本時刪除分片的損壞部分。運行elasticsearch-shard時,將丟失損壞的數據。在運行elasticsearch-shard之前停止Elasticsearch。

使用基於文件的用戶身份驗證,則可以使用elasticsearch-users命令添加和刪除用戶、分配用戶角色和管理密碼。

參考官方文檔 REST APIs

快照是從正在運行的Elasticsearch集群中獲取的備份。 可以拍攝整個集群的快照,包括其所有數據流和索引。 還可以僅對集群中的特定數據流或索引進行快照。必須先注冊快照存儲庫,然後才能創建快照。

Elasticsearch以增量方式進行快照:快照過程只將數據復制到存儲庫中,而之前的快照還沒有復制到那裡,避免了不必要的重復工作或存儲空間。這意味著可以安全地以最小的開銷頻繁地進行快照。這種增量只適用於單個存儲庫,因為存儲庫之間沒有數據共享。快照在邏輯上也是相互獨立的,即使是在一個存儲庫內:刪除一個快照不會影響任何其他快照的完整性。

可以將快照恢復到正在運行的集群中,默認情況下包括快照中的所有數據流和索引。 也可以選擇僅從快照恢復集群狀態或特定數據流或索引。

可以使用快照生命周期管理來自動拍攝和管理快照。

快照包含構成索引或數據流支持索引的磁碟上數據結構的副本。這意味著快照只能被恢復到可以讀取索引的Elasticsearch版本中。版本兼容圖如下:

㈡ Elasticsearch之Doc Value與Fielddata

倒排索引在搜索包含指定term的doc時非常高效,但是在相反的操作時表現很差:查詢一個文檔中包含哪些term。具體來說,倒排索引在搜索時最為高效,但在排序、聚合等與指定filed相關的操作時效率低下,需要用 doc_values

倒排索引將term映射到包含它們的doc,而doc values將doc映射到它們包含的所有詞項,下面是一個示例:

當數據被逆置之後,想要收集到 Doc_1 和 Doc_2 的唯一 token 會非常容易。獲得每個文檔行,獲取所有的詞項,然後求兩個集合的並集。

其實,Doc Values本質上是一個序列化了的列式存儲結構,非常適合排序、聚合以及欄位相關的腳本操作。而且這種存儲方式便於壓縮,尤其是數字類型。壓縮後能夠大大減少磁碟空間,提升訪問速度。下面是一個數字類型的 Doc Values示例:

列式存儲意味著有一個連續的數據塊: [100,1000,1500,1200,300,1900,4200] 。因為我們已經知道他們都是數字(而不是像文檔或行中看到的異構集合),所以可以使用統一的偏移量來將他們緊緊排列。

而且,針對這樣的數字有很多種壓縮技巧。你會注意到這里每個數字都是 100 的倍數,Doc Values會檢測一個段裡面的所有數值,並使用一個最大公約數,方便做進一步的數據壓縮。

比如,這個例子中可以用100作為公約數,那麼以上數字就變為[1,10,15,12,3,19,42],可用很少的bit就能存儲,節約了磁碟空間。一般來說,Doc Values按順序來檢測以下壓縮方案:

String類型使用順序表,按和數字類型類似的方式編碼。String類型去重後排序,然後寫入一個表中,並分配一個ID號,然後這些ID號就被當做數字類型的Doc Values。這意味著字元串享有許多與數字相同的壓縮特點。

Doc Values是在欄位索引時與倒排索引同時生成,而且生成以後是不可變的。

Doc Value 默認對除了 analyzed String 外的所有欄位啟用(因為分詞後會生成很多token使得Doc Values效率降低)。但是當你知道某些欄位永遠不會進行排序、聚合以及腳本操作的時候可以禁用Doc Values以節約磁碟空間提升索引速度,示例如下:

以上配置以後,session_id欄位就只能被搜索,不能被用於排序、聚合以及腳本操作了。

還可以通過設定doc_values為true,index為no來讓欄位不能被搜索但可以用於排序、聚合以及腳本操作:

Doc Value的特點就是快速、高效、內存友好,使用由linux kernel管理的文件系統緩存彈性存儲。doc values在排序、聚合或與欄位相關的腳本計算得到了高效的運用,任何需要查找某個文檔包含的值的操作都必須使用它。如果你確定某個filed不會做欄位相關操作,可以直接關掉doc_values,節約內存,加快訪問速度。

上文說過,在排序、聚合以及在腳本中訪問field值時需要一個與倒排索引截然不同的數據訪問模式:不同於倒排索引中的查找term->找到對應docs的過程,我們需要直接查找doc然後找到指定某個filed中包含的terms。

大多數field使用索引時、磁碟上的doc_values來支持這種訪問模式,但是分詞了的String filed不支持Doc Values,而是使用一種叫FieldData的數據結構。

FieldData主要是針對analyzed String ,它是一種查詢時(query-time)的數據結構。

FieldData緩存主要應用場景是在對某一個field排序或者計算類的聚合運算時。它會把這個field列的所有值載入到內存,這樣做的目的是提供對這些值的快速文檔訪問。為field構建FieldData緩存可能會很昂貴,因此建議有足夠的內存來分配它,並保持其處於已載入狀態。

FieldData是在第一次將該filed用於聚合,排序或在腳本中訪問時按需構建 。FieldData是通過從磁碟讀取每個段來讀取整個反向索引,然後逆置term->doc的關系,並將結果存儲在JVM堆中構建的。

所以,載入FieldData是開銷很大的操作,一旦它被載入後,就會在整個段的生命周期中保留在內存中。

這了可以注意下FieldData和Doc Values的區別。較早的版本中,其他數據類型也是用的FieldData,但是目前已經用隨文檔索引時創建的Doc Values所替代。

JVM堆內存資源是非常寶貴的,能用好它對系統的高效穩定運行至關重要。FieldData是直接放在堆內的,所以必須合理設定用於存放它的堆內存資源數。ES中控制FieldData內存使用的參數是 indices.fielddata.cache.size ,可以用x%表示占該節點堆內存百分比,也可以用如12GB這樣的數值。默認狀況下,這個設置是無限制的,ES不會從FieldData中驅逐數據。如果生成的fielddata大小超過指定的size,則將驅逐其他值以騰出空間。使用時一定要注意,這個設置只是一個安全策略而並非內存不足的解決方案。因為通過此配置觸發數據驅逐,ES會立刻開始從磁碟載入數據,並把其他數據驅逐以保證有足夠空間,導致很高的IO以及大量的需要被垃圾回收的內存垃圾。

舉個例子來說:每天為日誌文件建一個新的索引。一般來說我們只對最近幾天數據感興趣,很少查詢老數據。但是,按默認設置FieldData中的老索引數據是不會被驅逐的。這樣的話,FieldData就會一直持續增長直到觸發 熔斷機制 ,這個機制會讓你再也不能載入更多的FieldData到內存。這樣的場景下,你只能對老的索引訪問FieldData,但不能載入更多新數據。所以,這個時候就可以通過以上配置來把最近最少使用的FieldData驅逐以夠新進來的數據騰空間。

FieldData是在數據被載入後再檢查的,那麼如果一個查詢導致嘗試載入超過可用內存的數據就會導致OOM異常。ES中使用了 FieldData Circuit Breaker 來處理上述問題,他可以通過分析一個查詢涉及到的欄位的類型、基數、大小等來評估所需內存。如果估計的查詢大小大於配置的堆內存使用百分比限制,則斷路器會跳閘,查詢將被中止並返回異常。

斷路器是工作是在數據載入前,所以你不用擔心遇到FieldData導致的OOM異常。ES擁有多種類型的斷路器:

可以根據實際需要進行配置。

FieldData是為分詞String而生,它會消耗大量的java 堆空間,特別是載入基數(cardinality)很大的分詞String filed時。但是往往對這種類型的分詞Field做聚合是沒有意義的。

值得注意的是,FieldData和Doc Values的載入時機不同,前者是首次查詢時,後者是doc索引時。還有一點,FieldData是按每個段來緩存的。

doc_values與fielddata一個很顯著的區別是,前者的工作地盤主要在磁碟,而後者的工作地盤在內存。

索引速度稍低這個是相對於fielddata方案的,其實仔細想想也可以理解。拿排序舉例,相對於一個在磁碟排序,一個在內存排序,誰的速度快不言自明。

在ES 1.x版本的官方說法是,

雖然速度稍慢,doc_values的優勢還是非常明顯的。一個很顯著的點就是它不會隨著文檔的增多引起OOM問題。正如前面說的,doc_values在磁碟創建排序和聚合所需的正排索引。這樣我們就避免了在生產環境給ES設置一個很大的 HEAP_SIZE ,也使得JVM的GC更加高效,這個又為其它的操作帶來了間接的好處。

而且,隨著ES版本的升級,對於doc_values的優化越來越好,索引的速度已經很接近fielddata了,而且我們知道硬碟的訪問速度也是越來越快(比如SSD)。所以 doc_values 現在可以滿足大部分場景,也是ES官方重點維護的對象。

所以我想說的是,doc values相比field data還是有很多優勢的。所以 ES2.x 之後,支持聚合的欄位屬性默認都使用doc_values,而不是fielddata。

Global Ordinals是一個在Doc Values和FieldData之上的數據結構,它為每個唯一的term按字典序維護了一個自增的數字序列。每個term都有自己的一個唯一數字,而且字母A的全局序號小於字母B。特別注意,全局序號只支持String類型的field。

請注意,Doc Values和FieldData也有自己的ordinals序號,這個序號是特定segment和field中的唯一編號。通過提供Segment Ordinals和Global Ordinals間的映射關系,全局序號只是在此基礎上創建,後者(即全局序號)是在整個shard分片中是唯一的。

一個特定欄位的Global Ordinals跟一個分片中的所有段相關,而Doc Values和FieldData的ordinals只跟單個段相關。因此,只要是一個新段要變得可見,那麼就必須完全重建全局序號。

也就是說,跟FieldData一樣,在默認情況下全局序號也是懶載入的,會在第一個請求FieldData命中一個索引時來構建全局序號。實際上,在為每個段載入FieldData後,ES就會創建一個稱為Global Ordinals(全局序號)的數據結構來構建一個由分片內的所有段中的唯一term組成的列表。

全局序號的內存開銷小的原因是它由非常高效的壓縮機制。提前載入的全局序號可以將載入時間從第一次搜索時轉到全局序號刷新時。

全局序號的載入時間依賴於一個欄位中的term數量,但是總的來說耗時較低,因為來源的欄位數據都已經載入到內存了。

全局序號在用到段序號的時候很有用,比如排序或者terms aggregation,可以提升執行效率。

我們舉個簡單的例子。比如有十億級別的doc,每個doc都有一個status欄位,但只有pending, published, deleted三個狀態數據。如果直接存整個String數據到內存,那麼就算每個doc有15位元組,那麼一共就是差不多14GB的數據。怎麼減少佔用空間呢?首先想到的就是用數字來進行編碼,碼表如下:

這樣的話,初始的那三個String就只在碼表內被存了一次。FieldData中的doc就可以直接用編碼來指向實際值:

這樣編碼以後,直接把數據量壓縮了十倍左右。但有個問題是FieldData是按每個段來分別載入、緩存的。那麼就會出現一個情況,如果一個段內的doc只有deleted和published兩個狀態,那麼就會導致該FieldData算出來的碼表只有0和1,這就和擁有3個狀態的段算出的FieldData碼表不同。這樣的話,聚合的時候就必須一個段一個段的計算,最後再聚合,十分緩慢,開銷巨大。

ES的做法是用Global Ordinals這種構建在FieldData之上的小巧數據結構,編碼會結合所有段來計算唯一值然後存放為一個序號碼表。這樣一來,term aggregation可以只在全局序號上進行聚合,而且只會在聚合的最終階段來計算從序號到真實的String值一次。這個機制可以提升聚合的性能3-4倍。

㈢ ElasticSearch 欄位類型介紹

ElasticSearch對字元串擁有兩種完全不同的搜索方式. 你可以按照整個文本進行匹配, 即關鍵詞搜索(keyword search), 也可以按單個字元匹配, 即全文搜索(full-text search).
對ElasticSearch稍有了解的人都知道, 前者的字元串被稱為not-analyzed字元, 而後者被稱作analyzed字元串。

text用於全文搜索的, 而keyword用於關鍵詞搜索.
(1)string
string類型在ElasticSearch 舊版本中使用較多,從ElasticSearch 5.x開始不再支持string,由text和keyword類型替代。
(2)text
當一個欄位是要被全文搜索的,比如Email內容、產品描述,應該使用text類型。設置text類型以後,欄位內容會被分析,在生成倒排索引以前,字元串會被分析器分成一個一個詞項。text類型的欄位不用於排序,很少用於聚合。

(3)keyword
keyword類型適用於索引結構化的欄位,比如email地址、主機名、狀態碼和標簽。如果欄位需要進行過濾(比如查找已發布博客中status屬性為published的文章)、排序、聚合。keyword類型的欄位只能通過精確值搜索到。

在滿足需求的情況下,盡可能選擇范圍小的數據類型。比如,某個欄位的取值最大值不會超過100,那麼選擇byte類型即可。迄今為止吉尼斯記錄的人類的年齡的最大值為134歲,對於年齡欄位,short足矣。欄位的長度越短,索引和搜索的效率越高。

index分析

store存儲

對於float、half_float和scaled_float,-0.0和+0.0是不同的值,使用term查詢查找-0.0不會匹配+0.0,同樣range查詢中上邊界是-0.0不會匹配+0.0,下邊界是+0.0不會匹配-0.0。

其中scaled_float,比如價格只需要精確到分,price為57.34的欄位縮放因子為100,存起來就是5734
優先考慮使用帶縮放因子的scaled_float浮點類型。

index分析

store存儲

日期類型表示格式可以是以下幾種:

ElasticSearch 內部會將日期數據轉換為UTC,並存儲為milliseconds-since-the-epoch的long型整數。
例子:日期格式數據

邏輯類型(布爾類型)可以接受true/false/」true」/」false」值

二進制欄位是指用base64來表示索引中存儲的二進制數據,可用來存儲二進制形式的數據,例如圖像。默認情況下,該類型的欄位只存儲不索引。二進制類型只支持index_name屬性。

在ElasticSearch中,沒有專門的數組(Array)數據類型,但是,在默認情況下,任意一個欄位都可以包含0或多個值,這意味著每個欄位默認都是數組類型,只不過,數組類型的各個元素值的數據類型必須相同。在ElasticSearch中,數組是開箱即用的(out of box),不需要進行任何配置,就可以直接使用。

在同一個數組中,數組元素的數據類型是相同的,ElasticSearch不支持元素為多個數據類型:[ 10, 「some string」 ],常用的數組類型是:

ip類型的欄位用於存儲IPv4或者IPv6的地址

index分析

store存儲

原文: https://blog.csdn.net/chengyuqiang/article/details/79048800

㈣ Elasticsearch之存儲原理

倒排索引被寫入磁碟後是不可變的,ES解決不變性和更新索引的方式是使用多個索引,利用新增的索引來反映修改,在查詢時從舊的到新的依次查詢,最後來一個結果合並。

ES底層是基於Lucene,最核心的概念就是 Segment(段) ,每個段本身就是一個倒排索引。

ES中的Index由多個段的集合和 commit point(提交點) 文件組成。

提交點文件中有一個列表存放著所有已知的段,下面是一個帶有1個提交點和3個段的Index示意圖:

Doc會先被搜集到內存中的Buffer內,這個時候還無法被搜索到,如下圖所示:

每隔一段時間,會將buffer提交,在flush磁碟後打開新段使得搜索可見,詳細過程如下:

下面展示了這個過程完成後的段和提交點的狀態:

通過這種方式,可以使得新文檔從被索引到可被搜索間的時間間隔在數分鍾,但是還不夠快。因為磁碟需要 fsync ,這個就成為性能瓶頸。我們前面提到過Doc會先被從buffer刷入段寫入文件系統緩存(很快),那麼就自然想到在這個階段就讓文檔對搜索可見,隨後再被刷入磁碟(較慢)。

Lucene支持對新段寫入和打開,可以使文檔在沒有完全刷入硬碟的狀態下就能對搜索可見,而且是一個開銷較小的操作,可以頻繁進行。

下面是一個已經將Docs刷入段,但還沒有完全提交的示意圖:

我們可以看到,新段雖然還沒有被完全提交,但是已經對搜索可見了。

引入refresh操作的目的是提高ES的實時性,使添加文檔盡可能快的被搜索到,同時又避免頻繁fsync帶來性能開銷,依靠的就是文件系統緩存OS cache里緩存的文件可以被打開(open/reopen)和讀取,而這個os cache實際是一塊內存區域,而非磁碟,所以操作是很快的,這就是ES被稱為近實時搜索的原因。

refresh默認執行的間隔是1秒,可以使用 refreshAPI 進行手動操作,但一般不建議這么做。還可以通過合理設置 refresh_interval 在近實時搜索和索引速度間做權衡。

index segment刷入到os cache後就可以打開供查詢,這個操作是有潛在風險的,因為os cache中的數據有可能在意外的故障中丟失,而此時數據必備並未刷入到os disk,此時數據丟失將是不可逆的,這個時候就需要一種機制,可以將對es的操作記錄下來,來確保當出現故障的時候,已經落地到磁碟的數據不會丟失,並在重啟的時候可以從操作記錄中將數據恢復過來。elasticsearch提供了translog來記錄這些操作,結合os cached segments數據定時落盤來實現數據可靠性保證(flush)。

文檔被添加到buffer同時追加到translog:

進行 refresh 操作,清空buffer,文檔可被搜索但尚未 flush 到磁碟。translog不會清空:

每隔一段時間(例如translog變得太大),index會被flush到磁碟,新的translog文件被創建,commit執行結束後,會發生以下事件:

下面示意圖展示了這個狀態:

translog記錄的是已經 在內存生成(segments)並存儲到os cache但是還沒寫到磁碟的那些索引操作 (注意,有一種解釋說,添加到buffer中但是沒有被存入segment中的數據沒有被記錄到translog中,這依賴於寫translog的時機,不同版本可能有變化,不影響理解),此時這些新寫入的數據可以被搜索到,但是當節點掛掉後這些未來得及落入磁碟的數據就會丟失,可以通過trangslog恢復。

當然translog本身也是磁碟文件,頻繁的寫入磁碟會帶來巨大的IO開銷,因此對translog的追加寫入操作的同樣操作的是os cache,因此也需要定時落盤(fsync)。translog落盤的時間間隔直接決定了ES的可靠性,因為宕機可能導致這個時間間隔內所有的ES操作既沒有生成segment磁碟文件,又沒有記錄到Translog磁碟文件中,導致這期間的所有操作都丟失且無法恢復。

translog的fsync是ES在後台自動執行的,默認是每5秒鍾主動進行一次translog fsync,或者當translog文件大小大於512MB主動進行一次fsync,對應的配置是 index.translog.flush_threshold_period 和 index.translog.flush_threshold_size 。

當 Elasticsearch 啟動的時候, 它會從磁碟中使用最後一個提交點去恢復已知的段,並且會重放 translog 中所有在最後一次提交後發生的變更操作。

translog 也被用來提供實時 CRUD 。當你試著通過ID來RUD一個Doc,它會在從相關的段檢索之前先檢查 translog 中最新的變更。

默認 translog 是每5秒或是每次請求完成後被 fsync 到磁碟(在主分片和副本分片都會)。也就是說,如果你發起一個index, delete, update, bulk請求寫入translog並被fsync到主分片和副本分片的磁碟前不會反回200狀態。

這樣會帶來一些性能損失,可以通過設為非同步fsync,但是必須接受由此帶來的丟失少量數據的風險:

flush 就是執行commit清空、幹掉老translog的過程。默認每個分片30分鍾或者是translog過於大的時候自動flush一次。可以通過flush API手動觸發,但是只會在重啟節點或關閉某個索引的時候這樣做,因為這可以讓未來ES恢復的速度更快(translog文件更小)。

滿足下列條件之一就會觸發沖刷操作:

整體流程:

刪除一個ES文檔不會立即從磁碟上移除,它只是被標記成已刪除。因為段是不可變的,所以文檔既不能從舊的段中移除,舊的段也不能更新以反映文檔最新的版本。

ES的做法是,每一個提交點包括一個 .del 文件(還包括新段),包含了段上已經被標記為刪除狀態的文檔。所以,當一個文檔被做刪除操作,實際上只是在 .del 文件中將該文檔標記為刪除,依然會在查詢時被匹配到,只不過在最終返回結果之前會被從結果中刪除。ES將會在用戶之後添加更多索引的時候,在後台進行要刪除內容的清理。

文檔的更新操作和刪除是類似的:當一個文檔被更新,舊版本的文檔被標記為刪除,新版本的文檔在新的段中索引。
該文檔的不同版本都會匹配一個查詢,但是較舊的版本會從結果中刪除。

通過每秒自動刷新創建新的段,用不了多久段的數量就爆炸了,每個段消費大量文件句柄,內存,cpu資源。更重要的是,每次搜索請求都需要依次檢查每個段。段越多,查詢越慢。

ES通過後台合並段解決這個問題。ES利用段合並的時機來真正從文件系統刪除那些version較老或者是被標記為刪除的文檔。被刪除的文檔(或者是version較老的)不會再被合並到新的更大的段中。

可見,段合並主要有兩個目的:

ES對一個不斷有數據寫入的索引處理流程如下:

合並過程如圖:

從上圖可以看到,段合並之前,舊有的Commit和沒Commit的小段皆可被搜索。

段合並後的操作:

合並完成後新的段可被搜索,舊的段被刪除,如下圖所示:

注意 :段合並過程雖然看起來很爽,但是大段的合並可能會佔用大量的IO和CPU,如果不加以控制,可能會大大降低搜索性能。段合並的optimize API 不是非常特殊的情況下千萬不要使用,默認策略已經足夠好了。不恰當的使用可能會將你機器的資源全部耗盡在段合並上,導致無法搜索、無法響應。

㈤ Elasticsearch是什麼以及核心概念

Elasticsearch是由Shay Banon發起的一個開源搜索伺服器項目,2010年2月發布。迄今,該項目已發展成為搜索和數據分析解決方案領域的主要一員,廣泛應用於聲名卓著或鮮為人知的搜索應用程序。此外,由於其分布式性質和實時功能,許多人把它作為文檔資料庫。 Elasticsearch架構簡單介紹如下。 索引 索引(index)是Elasticsearch對邏輯數據的邏輯存儲,所以它可以分為更小的部分。你可以把索引看成關系型資料庫的表。然而,索引的結構是為快速有效的全文索引准備的,特別是它不存儲原始值。如果你知道MongoDB,可以把Elasticsearch的索引看成MongoDB里的一個集合。如果你熟悉CouchDB,可以把索引看成CouchDB資料庫索引。Elasticsearch可以把索引存放在一台機器或者分散在多台伺服器上,每個索引有一或多個分片(shard),每個分片可以有多個副本(replica)。 文檔 存儲在Elasticsearch中的主要實體叫文檔(document)。用關系型資料庫來類比的話,一個文檔相當於資料庫表中的一行記錄。當比較Elasticsearch中的文檔和MongoDB中的文檔,你會發現兩者都可以有不同的結構,但Elasticsearch的文檔中,相同欄位必須有相同類型。這意味著,所有包含title欄位的文檔,title欄位類型都必須一樣,比如string。 文檔由多個欄位組成,每個欄位可能多次出現在一個文檔里,這樣的欄位叫多值欄位(multivalued)。每個欄位有類型,如文本、數值、日期等。欄位類型也可以是復雜類型,一個欄位包含其他子文檔或者數組。欄位類型在Elasticsearch中很重要,因為它給出了各種操作(如分析或排序)如何被執行的信息。幸好,這可以自動確定,然而,我們仍然建議使用映射。與關系型資料庫不同,文檔不需要有固定的結構,每個文檔可以有不同的欄位,此外,在程序開發期間,不必確定有哪些欄位。當然,可以用模式強行規定文檔結構。從客戶端的角度看,文檔是一個JSON對象(關於JSON格式的更多內容,參見中國en.wikipedia.org/wiki/JSON)。每個文檔存儲在一個索引中並有一個Elasticsearch自動生成的唯一標識符和文檔類型。文檔需要有對應文檔類型的唯一標識符,這意味著在一個索引中,兩個不同類型的文檔可以有相同的唯一標識符。 文檔類型 在Elasticsearch中,一個索引對象可以存儲很多不同用途的對象。例如,一個博客應用程序可以保存文章和評論。文檔類型讓我們輕易地區分單個索引中的不同對象。每個文檔可以有不同的結構,但在實際部署中,將文件按類型區分對數據操作有很大幫助。當然,需要記住一個限制,不同的文檔類型不能為相同的屬性設置不同的類型。例如,在同一索引中的所有文檔類型中,一個叫title的欄位必須具有相同的類型。 映射 在有關全文搜索基礎知識部分,我們提到了分析的過程:為建索引和搜索准備輸入文本。文檔中的每個欄位都必須根據不同類型做相應的分析。舉例來說,對數值欄位和從中國頁抓取的文本欄位有不同的分析,比如前者的數字不應該按字母順序排序,後者的第一步是忽略HTML標簽,因為它們是無用的信息噪音。Elasticsearch在映射中存儲有關欄位的信息。每一個文檔類型都有自己的映射,即使我們沒有明確定義。 現在,我們已經知道Elasticsearch把數據存儲在一個或多個索引上,每個索引包含各種類型的文檔。我們也知道了每個文檔有很多欄位,映射定義了Elasticsearch如何對待這些欄位。但還有更多,從一開始,Elasticsearch就被設計為能處理數以億計的文檔和每秒數以百計的搜索請求的分布式解決方案。這歸功於幾個重要的概念,我們現在將更詳細地描述。 節點和集群 Elasticsearch可以作為一個獨立的單個搜索伺服器。不過,為了能夠處理大型數據集,實現容錯和高可用性,Elasticsearch可以運行在許多互相合作的伺服器上。這些伺服器稱為集群(cluster),形成集群的每個伺服器稱為節點(node)。 分片 當有大量的文檔時,由於內存的限制、硬碟能力、處理能力不足、無法足夠快地響應客戶端請求等,一個節點可能不夠。在這種情況下,數據可以分為較小的稱為分片(shard)的部分(其中每個分片都是一個獨立的Apache Lucene索引)。每個分片可以放在不同的伺服器上,因此,數據可以在集群的節點中傳播。當你查詢的索引分布在多個分片上時,Elasticsearch會把查詢發送給每個相關的分片,並將結果合並在一起,而應用程序並不知道分片的存在。此外,多個分片可以加快索引。 副本 為了提高查詢吞吐量或實現高可用性,可以使用分片副本。副本(replica)只是一個分片的精確復制,每個分片可以有零個或多個副本。換句話說,Elasticsearch可以有許多相同的分片,其中之一被自動選擇去更改索引操作。這種特殊的分片稱為主分片(primary shard),其餘稱為副本分片(replica shard)。在主分片丟失時,例如該分片數據所在伺服器不可用,集群將副本提升為新的主分片

㈥ elasticsearch系統

Elasticsearch 是位於 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助於收集、聚合和豐富您的數據並將其存儲在 Elasticsearch 中。Kibana 使您能夠以交互方式探索、可視化和分享對數據的見解,並管理和監控堆棧。Elasticsearch 是索引、搜索和分析魔法發生的地方。

Elasticsearch為所有類型的數據提供近乎實時的搜索和分析。無論您擁有結構化或非結構化文本、數字數據還是地理空間數據,Elasticsearch都能以支持快速搜索的方式高效地存儲和索引它。您可以超越簡單的數據檢索和聚合信息來發現數據中的趨勢和模式。隨著您的數據和查詢量的增長,Elasticsearch的分布式特性使您的部署能夠隨之無縫增長。

相關內容:

cluster:代表一個集群,集群中有多個節點,其中有一個為主節點,這個主節點是可以通過選舉產生的,主從節點是對於集群內部來說的。es的一個概念就是去中心化,字面上理解就是無中心節點,這是對於集群外部來說的,因為從外部來看es集群,在邏輯上是個整體,你與任何一個節點的通信和與整個es集群通信是等價的。

shards:代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分布到不同的節點上。構成分布式搜索。分片的數量只能在索引創建前指定,並且索引創建後不能更改。

replicas:代表索引副本,es可以設置多個索引的副本,副本的作用一是提高系統的容錯性,當某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高es的查詢效率,es會自動對搜索請求進行負載均衡。

recovery:代表數據恢復或叫數據重新分布,es在有節點加入或退出時會根據機器的負載對索引分片進行重新分配,掛掉的節點重新啟動時也會進行數據恢復。

㈦ 分布式搜索引擎elasticsearch的架構原理

分布式搜索引擎:把大量的索引數據拆散成多塊,每台機器放一部分,然 後利用多台機器對分散之後的數據進行搜索,所有操作全部是分布在多台機器上進行,形成了 完整的分布式的架構。

近實時,有兩層意思:

集群包含多個節點,每個節點屬於哪個集群都是通過一個配置來決定的,
Node 是集群中的一個節點,節點也有一個名稱,默認是隨機分配的。默認節點會去加入一個名 稱為 elasticsearch 的集群。如果直接啟動一堆節點,那麼它們會自動組成一個elasticsearch 集群,當然一個節點也可以組成 elasticsearch 集群。

文檔是 es 中最小的數據單元,一個 document 可以是1條客戶數據、1條商品分類數據、1條 訂單數據,通常用json 數據結構來表示。每個 index 下的 type,都可以存儲多條 document。
1個 document 裡面有多個 field,每個 field 就是1個數據欄位。

es 集群多個節點,會自動選舉1個節點為 master 節點,這個 master 節點其實就是干一些管理 的工作的,比如維護索引元數據、負責切換 primary shard 和 replica shard 身份等。要是 master 節點宕機了,那麼會重新選舉1個節點為 master 節點。 如果是非 master節點宕機了,那麼會由 master 節點,讓那個宕機節點上的 primary shard 的身 份轉移到其他機器上的 replica shard。接著你要是修復了那個宕機機器,重啟了之後,master 節點會控制將缺失的 replica shard 分配過去,同步後續修改的數據之類的,讓集群恢復正常。 說得更簡單1點,就是說如果某個非 master 節點宕機了,那麼此節點上的 primary shard 不就 沒了。那好,master 會讓 primary shard 對應的 replica shard(在其他機器上)切換為 primary shard。如果宕機的機器修復了,修復後的節點也不再是 primary shard,而是 replica shard。

索引可以拆分成多個 shard ,每個 shard 存儲部分數據。拆分多個 shard是有好處的,一是支持橫向擴展,比如你數據量是 3T,3 個 shard,每個 shard 就 1T 的數據, 若現在數據量增加到 4T,怎麼擴展,很簡單,重新建1個有 4 個 shard 的索引,將數據導進 去;二是提高性能,數據分布在多個 shard,即多台伺服器上,所有的操作,都會在多台機器 上並行分布式執行,提高了吞吐量和性能。 接著就是這個 shard 的數據實際是有多個備份,就是說每個 shard 都有1個 primary shard ,負責寫入數據,但是還有多個 replica shard 。 primary shard 寫入數據之後, 會將數據同步到其他幾個 replica shard上去。
通過這個 replica 的方案,每個 shard 的數據都有多個備份,如果某個機器宕機了,沒關系啊, 還有別的數據副本在別的機器上,這樣子就高可用了。

總結:分布式就是兩點,1.通過shard切片實現橫向擴展;2.通過replica副本機制,實現高可用

基本概念

寫數據過程:客戶端通過hash選擇一個node發送請求,這個node被稱做coordinating node(協調節點),協調節點對docmount進行路由,將請求轉發給到對應的primary shard,primary shard 處理請求,將數據同步到所有的replica shard,此時協調節點,發現primary shard 和所有的replica shard都處理完之後,就反饋給客戶端。

客戶端發送get請求到任意一個node節點,然後這個節點就稱為協調節點,協調節點對document進行路由,將請求轉發到對應的node,此時會使用隨機輪詢演算法,在primary shard 和replica shard中隨機選擇一個,讓讀取請求負載均衡,接收請求的node返回document給協調節點,協調節點,返回document給到客戶端

es最強大的是做全文檢索,就是比如你有三條數據
1.java真好玩兒啊
2.java好難學啊
3.j2ee特別牛

你根據java關鍵詞來搜索,將包含java的document給搜索出來。

更新/刪除數據過程,首先還是write、merge操作,然後flush過程中:
1、write過程和上面的一致;
2、refresh過程有點區別

所謂的倒排索引,就是把你的數據內容先分詞,每句話分成一個一個的關鍵詞,然後記錄好每一個關鍵詞對應出現在了哪些 id 標識的數據。
然後你可以從其他地根據這個 id 找到對應的數據就可以了,這個就是倒排索引的數據格式 以及搜索的方式,這種利倒排索引查找數據的式,也被稱之為全文檢索。

Inverted Index就是我們常見的倒排索引, 主要包括兩部分:
一個有序的數據字典 Dictionary(包括單詞 Term 和它出現的頻率)。
與單詞 Term 對應的 Postings(即存在這個單詞的文件)
當我們搜索的時候,首先將搜索的內容分解,然後在字典里找到對應 Term,從而查找到與搜索相關的文件內容。

本質上,Stored Fields 是一個簡單的鍵值對 key-value。默認情況下,Stored Fields是為false的,ElasticSearch 會存儲整個文件的 JSON source。

哪些情形下需要顯式的指定store屬性呢?大多數情況並不是必須的。從_source中獲取值是快速而且高效的。如果你的文檔長度很長,存儲 _source或者從_source中獲取field的代價很大,你可以顯式的將某些field的store屬性設置為yes。缺點如上邊所說:假設你存 儲了10個field,而如果想獲取這10個field的值,則需要多次的io,如果從Stored Field 中獲取則只需要一次,而且_source是被壓縮過 的。

這個時候你可以指定一些欄位store為true,這意味著這個field的數據將會被單獨存儲(實際上是存兩份,source和 Stored Field都存了一份)。這時候,如果你要求返回field1(store:yes),es會分辨出field1已經被存儲了,因此不會從_source中載入,而是從field1的存儲塊中載入。

Doc_values 本質上是一個序列化的 列式存儲,這個結構非常適用於聚合(aggregations)、排序(Sorting)、腳本(scripts access to field)等操作。而且,這種存儲方式也非常便於壓縮,特別是數字類型。這樣可以減少磁碟空間並且提高訪問速度,ElasticSearch 可以將索引下某一個 Document Value 全部讀取到內存中進行操作.

Doc_values是存在磁碟的

在es中text類型欄位默認只會建立倒排索引,其它幾種類型在建立倒排索引的時候還會建立正排索引,當然es是支持自定義的。在這里這個正排索引其實就是Doc Value。

即上文所描述的動態索引

往 es 寫的數據,實際上都寫到磁碟文件里去了,查詢的時候,操作系統會將磁碟文件里的數據自動緩存到 filesystem cache 中去。

es 的搜索引擎嚴重依賴於底層的 filesystem cache ,你如果給 filesystem cache 更多的 內存,盡量讓內存可以容納所有的 idx segment file 索引數據文件,那麼你搜索的時候就 基本都是走內存的,性能會非常高。 性能差距究竟可以有多大?我們之前很多的測試和壓測,如果走磁碟一般肯定上秒,搜索性能 絕對是秒級別的,1秒、5秒、10秒。但如果是走 filesystem cache ,是走純內存的,那麼一 般來說性能比走磁碟要高一個數量級,基本上就是毫秒級的,從幾毫秒到幾百毫秒不等。

那如何才能節約filesystem cache這部分的空間呢?
當寫數據到ES時就要考慮到最小化數據,當一行數據有30幾個欄位,並不需要把所有的數據都寫入到ES,只需要把關鍵的需要檢索的幾列寫入。這樣能夠緩存的數據就會越多。 所以需要控制每台機器寫入的數據最好小於等於或者略大於filesystem cache空間最好。 如果要搜索海量數據,可以考慮用ES+Hbase架構。用Hbase存儲海量數據,然後ES搜索出doc id後,再去Hbase中根據doc id查詢指定的行數據。

當每台機器寫入的數據大於cache os太多時,導致太多的數據無法放入緩存,那麼就可以把一部分熱點數據刷入緩存中。

對於那些你覺得比較熱的、經常會有人訪問的數據,最好做個專門的緩存預熱系統,就是 對熱數據每隔一段時間,就提前訪問一下,讓數據進入 filesystem cache 里去。這樣下 次別人訪問的時候,性能肯定會好很多。

把熱數據和冷數據分開,寫入不同的索引里,然後確保把熱索引數據刷到cache里。

在ES里最好不要用復雜的關聯表的操作。當需要這樣的場景時,可以在創建索引的時候,就把數據關聯好。比如在mysql中需要根據關聯ID查詢兩張表的關聯數據:select A.name ,B.age from A join B where A.id = B.id,在寫入ES時直接去把相關聯數據放到一個document就好。

es 的分頁是較坑的,為啥呢?舉個例子吧,假如你每頁是 10 條數據,你現在要查詢第 100 頁,實際上是會把每個 shard 上存儲的前 1000 條數據都查到1個協調節點上,如果你有個 5 個 shard,那麼就有 5000 條數據,接著協調節點對這 5000 條數據進行一些合並、處理,再獲取到 最終第 100 頁的 10 條數據。
分布式的,你要查第 100 頁的 10 條數據,不可能說從 5 個 shard,每個 shard 就查 2 條數據, 最後到協調節點合並成 10 條數據吧?你必須得從每個 shard 都查 1000 條數據過來,然後根據 你的需求進行排序、篩選等等操作,最後再次分頁,拿到裡面第 100 頁的數據。你翻頁的時 候,翻的越深,每個 shard 返回的數據就越多,而且協調節點處理的時間越長,非常坑爹。所 以用 es 做分頁的時候,你會發現越翻到後面,就越是慢。

我們之前也是遇到過這個問題,用 es 作分頁,前幾頁就幾十毫秒,翻到 10 頁或者幾十頁的時 候,基本上就要 5~10 秒才能查出來一頁數據了。

解決方案嗎?
1)不允許深度分頁:跟產品經理說,你系統不允許翻那麼深的頁,默認翻的越深,性能就越差;
2)在APP或者公眾號里,通過下拉來實現分頁,即下拉時獲取到最新頁,可以通過scroll api來實現;
scroll 會1次性給你生成所有數據的1個快照,然後每次滑動向後翻頁就是通過游標 scroll_id 移動獲取下一頁,性能會比上面說的那種分頁性能要高很多很 多,基本上都是毫秒級的。 但是,唯1的缺點就是,這個適合於那種類似微博下拉翻頁的,不能隨意跳到任何一頁的場 景。也就是說,你不能先進到第 10 頁,然後去第 120 頁,然後再回到第 58 頁,不能隨意亂跳 頁。所以現在很多APP產品,都是不允許你隨意翻頁的,也有一些網站,做的就是你只能往 下拉,一頁一頁的翻。
初始化時必須指定 scroll 參數,告訴 es 要保存此次搜索的上下文多長時間。你需要確保用戶不會持續不斷翻頁翻幾個小時,否則可能因為超時而失敗。
除了用 scroll api ,也可以用 search_after 來做, search_after 的思想是使用前一頁的結果來幫助檢索下一頁的數據,顯然,這種方式也不允許你隨意翻頁,你只能一頁一頁往後 翻。初始化時,需要使用一個唯1值的欄位作為 sort 欄位。

㈧ 關於inner_hits

本文將從以下幾個方面回答有關inner_hits的一些問題:

inner_hits是ElasticSearch進行nested,has_parent,has_child搜索時的一個選項,用來標記命中文檔位置的。以官方文檔中的例子為例。

索引」blog「有一個類型為」nested「的欄位」comments「,我們寫入了一個文檔,其中包含了2個」comments「。下面我們對文檔進行搜索,我們先不添加」inner_hits「看一下結果是怎麼樣:

可以看到,這個結果和正常搜索沒有太多區別。

現在我們在搜索時加入」inner_hits「看一下效果,為了簡單起見,」inner_hits「不使用任何選項。

我們可以看到結果比剛才多了一個」inner_hits「塊:

可以看到,」inner_hits「中包含了關於此處文檔的一些匹配信息,其中比較重要的有兩個:

」nested「,告訴我們此次命中是文檔中的那個nested欄位,我們的例子里只有一個」nested「類型的欄位,而實際上一個索引中,默認最多可以有50個」nested「類型的欄位,這個值由索引的配置項」 index.mapping.nested_fields.limit 「控制。

」_source「,告訴我們當前命中的是哪個文檔。我們的例子里,查詢的條件是」number=2「,因此在 」_source「部分返回了對應的那個文檔。「inner_hits」有一個選項「_source」,默認值是true,如果將其置為false可以在返回結果中不顯示」_source「的內容。

在ElasticSearch中,nested對象是以獨立的隱藏文檔的方式進行存儲的,以上面的例子為例,id為1的文檔,有2個comments類型的nested對象,最終存儲在ES中的其實是三個文檔。而relation類型的對象,父子文檔的結構可以完全不同,卻是存儲在同一個索引中。在進行nested search或者has_child,has_parent search的時候我們可能需要知道,我們的搜索到底是匹配了哪些更細粒度的文檔。因此需要inner_hits。

最簡單的用法,如上文例子中使用的一樣。直接加入一個空的「inner_hits」塊即可。除此之外還有一些更細粒度的控制選項:

"from": 指定從文檔內部對象array的某個位置開始顯示inner_hits。比如說如果from指定為2,那麼位置在0和1的文檔即使在搜索中被匹配到了,也不會顯示在inner_hits里。

"size": 最多顯示inner_hits的文檔數。

"sorted": 返回inner_hits 對象的排序欄位。

"name": 當存在有多個nested欄位在搜索中被涉及到時,指定其中某個欄位作為inner_hits的顯示欄位。

更多可參考官方文檔的內容

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/search-request-inner-hits.html

由於nested search,has_parent search,has_child search的文檔對象存儲方式,在進行相關搜索時,會涉及到主文檔之外的其他文檔,我們需要一種手段來指出命中的原因。inner_hits應運而生,它可以支持命中文檔在多個文檔組成的array中的位置,以及具體是哪個nested對象被命中了。總而言之,這是一種幫助我們理解搜索結果的方式或者手段。

㈨ Elasticsearch的架構是什麼樣的

Elasticsearch是由Shay Banon發起的一個開源搜索伺服器項目,2010年2月發布。迄今,該項目已發展成為搜索和數據分析解決方案領域的主要一員,廣泛應用於聲名卓著或鮮為人知的搜索應用程序。此外,由於其分布式性質和實時功能,許多人把它作為文檔資料庫。
Elasticsearch架構簡單介紹如下。
索引
索引(index)是Elasticsearch對邏輯數據的邏輯存儲,所以它可以分為更小的部分。你可以把索引看成關系型資料庫的表。然而,索引的結構是為快速有效的全文索引准備的,特別是它不存儲原始值。如果你知道MongoDB,可以把Elasticsearch的索引看成MongoDB里的一個集合。如果你熟悉CouchDB,可以把索引看成CouchDB資料庫索引。Elasticsearch可以把索引存放在一台機器或者分散在多台伺服器上,每個索引有一或多個分片(shard),每個分片可以有多個副本(replica)。
文檔
存儲在Elasticsearch中的主要實體叫文檔(document)。用關系型資料庫來類比的話,一個文檔相當於資料庫表中的一行記錄。當比較Elasticsearch中的文檔和MongoDB中的文檔,你會發現兩者都可以有不同的結構,但Elasticsearch的文檔中,相同欄位必須有相同類型。這意味著,所有包含title欄位的文檔,title欄位類型都必須一樣,比如string。
文檔由多個欄位組成,每個欄位可能多次出現在一個文檔里,這樣的欄位叫多值欄位(multivalued)。每個欄位有類型,如文本、數值、日期等。欄位類型也可以是復雜類型,一個欄位包含其他子文檔或者數組。欄位類型在Elasticsearch中很重要,因為它給出了各種操作(如分析或排序)如何被執行的信息。幸好,這可以自動確定,然而,我們仍然建議使用映射。與關系型資料庫不同,文檔不需要有固定的結構,每個文檔可以有不同的欄位,此外,在程序開發期間,不必確定有哪些欄位。當然,可以用模式強行規定文檔結構。從客戶端的角度看,文檔是一個JSON對象(關於JSON格式的更多內容,參見http://en.wikipedia.org/wiki/JSON)。每個文檔存儲在一個索引中並有一個Elasticsearch自動生成的唯一標識符和文檔類型。文檔需要有對應文檔類型的唯一標識符,這意味著在一個索引中,兩個不同類型的文檔可以有相同的唯一標識符。
文檔類型
在Elasticsearch中,一個索引對象可以存儲很多不同用途的對象。例如,一個博客應用程序可以保存文章和評論。文檔類型讓我們輕易地區分單個索引中的不同對象。每個文檔可以有不同的結構,但在實際部署中,將文件按類型區分對數據操作有很大幫助。當然,需要記住一個限制,不同的文檔類型不能為相同的屬性設置不同的類型。例如,在同一索引中的所有文檔類型中,一個叫title的欄位必須具有相同的類型。
映射
在有關全文搜索基礎知識部分,我們提到了分析的過程:為建索引和搜索准備輸入文本。文檔中的每個欄位都必須根據不同類型做相應的分析。舉例來說,對數值欄位和從網頁抓取的文本欄位有不同的分析,比如前者的數字不應該按字母順序排序,後者的第一步是忽略HTML標簽,因為它們是無用的信息噪音。Elasticsearch在映射中存儲有關欄位的信息。每一個文檔類型都有自己的映射,即使我們沒有明確定義。
現在,我們已經知道Elasticsearch把數據存儲在一個或多個索引上,每個索引包含各種類型的文檔。我們也知道了每個文檔有很多欄位,映射定義了Elasticsearch如何對待這些欄位。但還有更多,從一開始,Elasticsearch就被設計為能處理數以億計的文檔和每秒數以百計的搜索請求的分布式解決方案。這歸功於幾個重要的概念,我們現在將更詳細地描述。
節點和集群
Elasticsearch可以作為一個獨立的單個搜索伺服器。不過,為了能夠處理大型數據集,實現容錯和高可用性,Elasticsearch可以運行在許多互相合作的伺服器上。這些伺服器稱為集群(cluster),形成集群的每個伺服器稱為節點(node)。
分片
當有大量的文檔時,由於內存的限制、硬碟能力、處理能力不足、無法足夠快地響應客戶端請求等,一個節點可能不夠。在這種情況下,數據可以分為較小的稱為分片(shard)的部分(其中每個分片都是一個獨立的Apache Lucene索引)。每個分片可以放在不同的伺服器上,因此,數據可以在集群的節點中傳播。當你查詢的索引分布在多個分片上時,Elasticsearch會把查詢發送給每個相關的分片,並將結果合並在一起,而應用程序並不知道分片的存在。此外,多個分片可以加快索引。
副本
為了提高查詢吞吐量或實現高可用性,可以使用分片副本。副本(replica)只是一個分片的精確復制,每個分片可以有零個或多個副本。換句話說,Elasticsearch可以有許多相同的分片,其中之一被自動選擇去更改索引操作。這種特殊的分片稱為主分片(primary shard),其餘稱為副本分片(replica shard)。在主分片丟失時,例如該分片數據所在伺服器不可用,集群將副本提升為新的主分片。

熱點內容
sqldist 發布:2025-05-14 18:08:18 瀏覽:161
人行外管局編譯 發布:2025-05-14 18:07:33 瀏覽:648
安卓手機如何使用大流量 發布:2025-05-14 17:47:34 瀏覽:81
精密模具編程 發布:2025-05-14 17:45:16 瀏覽:499
存儲順序和邏輯順序有什麼區別 發布:2025-05-14 17:44:30 瀏覽:275
安卓版設置里的隱身在哪裡 發布:2025-05-14 17:35:16 瀏覽:333
linuxshell密碼 發布:2025-05-14 17:21:11 瀏覽:200
安卓手機聽筒在哪裡關閉 發布:2025-05-14 17:16:20 瀏覽:456
我的世界炸毀50萬伺服器 發布:2025-05-14 17:16:07 瀏覽:123
存儲站源 發布:2025-05-14 17:14:20 瀏覽:864