Elasticsearch2.x Doc values
生活随笔
收集整理的這篇文章主要介紹了
Elasticsearch2.x Doc values
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文檔地址:
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/doc-values.html
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/docvalues-intro.html
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/docvalues.html
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/_deep_dive_on_doc_values.html#_deep_dive_on_doc_values
doc_values介紹
doc values是一個我們再三重復的重要話題了,你是否意識到一些東西呢?- 搜索時,我們需要一個“詞”到“文檔”列表的映射
- 排序時,我們需要一個“文檔”到“詞“列表的映射,換句話說,我們需要一個在倒排索引的基礎上建立的“正排索引”
在ES里這種“列式存儲”就是我們熟悉的“doc values”,默認情況下它是被啟用的,doc values在index-time(索引期)被創建:當一個字段被索引時,ES會把“詞”加入到倒排索引中,同時把這些詞也加入到面向“列式存儲”的doc values中(存儲在硬盤上)。 doc values通常被應用在以下幾個方面:
- 基于一個字段排序
- 基于一個字段聚合
- 執行某些filter上(如:geolocation filter)
- 在script(腳本)中引用了一個或多個字段
doc_values
大多數的字段默認情況下都會被索引,這使得他們可以被搜索到,倒排索引允許一個查詢基于一個詞表排序,也可以快速訪問包含某個詞的文檔列表。 排序、聚合,和在腳本中訪問一些字段值時都需要另一種不同的訪問方式,因為倒排索引不支持這種訪問,所以我們需要一種結構能查詢到文檔到詞的映射。 doc values是在索引期創建基于磁盤的數據結構,這種結構使得上述訪問成為可能。doc values支持絕大部分字段類型,除了“analyzed”類型的string字段。 所有的字段都默認支持doc values,如果你確定你不需要在某個字段上排序或者聚合或者在腳本中訪問,你可以disable掉: PUT my_index {"mappings": {"my_type": {"properties": {"status_code": { "type": "string","index": "not_analyzed"},"session_id": { "type": "string","index": "not_analyzed","doc_values": false}}}} }看如下的倒排索引結構 Term Doc_1 Doc_2 Doc_3 ------------------------------------ brown | X | X | dog | X | | X dogs | | X | X fox | X | | X foxes | | X | in | | X | jumped | X | | X lazy | X | X | leap | | X | over | X | X | X quick | X | X | X summer | | X | the | X | | X ------------------------------------如果我們想為每一個包含“brown”的文檔編輯一份完整的詞列表,我們可能會用如下查詢 GET /my_index/_search {"query" : {"match" : {"body" : "brown"}},"aggs" : {"popular_terms": {"terms" : {"field" : "body"}}} }看上面的查詢部分。倒排索引通過詞條排好了序,所以我們首先找到包含“brown”的詞條列表,然后跨列掃描所有包含“brown”的文檔,這里我們很幸運的找到了“Doc_1”和“Doc_2”。 然后在聚合部分,我們需要找Doc_1和Doc_2中找到所有的詞,在倒排索引的去做這個操作很非常昂貴的:意味著我們不得不迭代索引中的每一個詞,看它們是否包含在doc_1和doc_2中,這個過程是非常緩慢的,而且也是非常愚蠢的:因為隨著文檔詞量的增加,我們聚合的執行時間也會增加。 讓我們看看下面的結構: Doc Terms ----------------------------------------------------------------- Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer Doc_3 | dog, dogs, fox, jumped, over, quick, the -----------------------------------------------------------------有了這個結構我們就會很容易得到doc_1和doc_2所包含的詞條,我們只需要通過上面的結構把兩個集合合并起來就行了。
因此,查詢和聚合是非常復雜的,查詢文檔使用的是倒排索引,聚合文檔使用的是正排索引(doc_values) note:doc values不僅僅是用在聚合中,還被用在排序、腳本、子父文檔關系(這里暫不做介紹)。
深入Doc Values
前面講到的doc values給我們幾個印象:快速訪問、高效、基于硬盤。現在我們來看看doc values到底是如何工作的? doc values是在“索引期“隨著倒排索引一起生成的,也就是說doc values是基于每個索引段生成且是不可改變的(immutable),和倒排索引一樣,doc values也會被序列化到磁盤上,這使得它具有了高效性和可擴展性。 通過序列化一個數據結構到磁盤上,我們可以依賴操作系統的file system cache 替代JVM的堆內存,當我們的“工作集”小于OS可用內存時,操作系統會自然的加載這些doc values到內存。這時doc values的性能和在JVM堆內存中表現是一樣的。 但是當工作集大于操作系統可用內存時,操作系統將會按需加載doc values,這種情況下的訪問速度會明顯的慢于全量加載doc values的時候。但這種操作使得我們的服務器內存利用率遠超過服務器最大內存限制。試想一下,如果全量加載到doc values到內存中勢必會造成ES OutOfMemery。 NOTE:由于doc values不受JVM堆內存管理,所以我們可以把ES對內存設置得小一點,把更多的內存留給操作系統來換出(doc values),同時這也可以使JVM的GC工作在更小的堆內存上,更快更高效的執行GC。通常,我們配置JVM的堆內存基本和操作系統內存各占一半(50%),由于引進了doc values所以我們可以考慮把JVM的堆內存設置得小一些,比如我們可以在一個64G的服務器上設置JVM堆內存為4 - 16GB比設置堆內存為32G更加高效。
Column-store compression(列式存儲壓縮)
本質上doc values是一個被序列化的面向“列式儲存”的結構,我們前面討論過列式存儲在某些查詢操作上是有優勢的,不僅如此它們也更擅長數據壓縮,特別是數字,這對磁盤存儲和快速訪問來說是及其重要的。 為了了解它是如何壓縮數據的,我們看下面簡單的doc values結構 Doc Terms ----------------------------------------------------------------- Doc_1 | 100 Doc_2 | 1000 Doc_3 | 1500 Doc_4 | 1200 Doc_5 | 300 Doc_6 | 1900 Doc_7 | 4200 -----------------------------------------------------------------像上面這種每行一條數據的形式,我們可以得到連續的數字塊,如:[100,1000,1500,1200,300,1900,4200]。因為我們知道它們都是數字值可以被排列在一起通過一個一致的偏移量。 跟深層次的,這里有幾種壓縮方法可以運用在這些數字上。你可能知道上面的數字都是100的倍數,如果索引段上所有的的數字都共享一個“最大公約數”,那么就可以用這個最大公約數去壓縮數據。如上面的數字我們可以除以100,得到的數據是[1,10,15,12,3,19,42]。這樣這些數字會變得小一些,存儲時占用的比特數也會小一些。 doc values使用幾種手段來壓縮數字。轉載于:https://www.cnblogs.com/chennanlcy/p/6591788.html
總結
以上是生活随笔為你收集整理的Elasticsearch2.x Doc values的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 治标更治本,如何从根源防护DDoS***
- 下一篇: php敏感词过滤