乾貨 |《深刻理解Elasticsearch》讀書筆記

題記

因爲以前已經梳理過Elasticsearch基礎概念且在項目中實戰過Elasticsearch的增刪改查、聚類、排序等相關操做,對ES算是有了必定的認知。node

可是,仍然對於一些底層的原理認知模糊,特買來《深刻理解Elasticsearch》過了一遍,將書中一些細節知識點結合官網文檔梳理以下。緩存

1——4章偏應用,跟着敲一遍代碼基本就能理解原理。 
5——9章偏理論一些。 
image.png安全

第5章 分佈式索引架構

一、如何選擇合適的分片和副本數?

目的:規劃索引及配置,適應應用的變化。服務器

正確認知:分片數索引建立後不能夠修改,副本數索引建立後能夠經過API隨時修改網絡

多副本的缺點:額外副本佔據了額外的存儲空間,構建索引副本的開銷也隨之增大。數據結構

同時要注意:若是不建立副本,當主分片發生問題時,可能會形成數據的丟失。架構

配置參考:最理想的分片數量應該依賴於節點的數量。app

參考公式:所需的最大節點數 = 分片數 *(副本數+1) 分佈式

舉例:你計劃5個分片和1個副本,那麼所須要的最大的節點數爲:5*(1+1)=10個節點。ide

二、可不能夠基於時間構建索引?

目的:選擇感興趣的索引上進行查詢,歷史索引(時間比較久)的按期刪除。 
正確操做方法:經過名稱爲logs_2017_01, logs_2017_02,…..logs_2017_12來構建索引。

第6章 底層索引控制

一、什麼是段?

Elasticsearch中的每一個分片包含多個segment(段),每個segment都是一個倒排索引;在查詢的時,會把全部的segment查詢結果彙總歸併爲最終的分片查詢結果返回。

在建立索引的時候,ES會把文檔信息寫到內存bugffer中(爲了安全,也一塊兒寫到translog),定時(可配置)把數據寫到segment緩存小文件中,而後刷新查詢,使剛寫入的segment可查。

雖然寫入的segment可查詢,可是尚未持久化到磁盤上。所以,仍是會存在丟失的可能性的。因此,ES會執行flush操做,把segment持久化到磁盤上並清除translog的數據(由於這個時候,數據已經寫到磁盤上,再也不須要了)。 

參考:http://t.cn/RjKOMv1

二、什麼是段合併?

因爲自動刷新流程每秒會建立一個新的段,這樣會致使短期內的段數量暴增。而段數目太多會帶來較大的麻煩。

1)消耗資源:每個段都會消耗文件句柄、內存和cpu運行週期; 
2)搜索變慢:每一個搜索請求都必須輪流檢查每一個段;因此段越多,搜索也就越慢。

ES經過在後臺進行段合併來解決這個問題。小的段被合併到大的段,而後這些大的段再被合併到更大的段

三、段合併作了什麼?

段合併的時候會將那些舊的已刪除文檔從文件系統中清除。 
被刪除的文檔(或被更新文檔的舊版本)不會被拷貝到新的大段中。

啓動段合併不須要你作任何事。進行索引和搜索時會自動進行。 
1)當索引的時候,刷新(refresh)操做會建立新的段並將段打開以供搜索使用。 
2) 合併進程選擇一小部分大小類似的段,而且在後臺將它們合併到更大的段中。這並不會中斷索引和搜索。

四、爲何要進行段合併?

1)索引段的個數越多,搜索性能越低而且消耗更多的內存; 
2)索引段是不可變的,你並不能物理上從中刪除信息。(能夠物理上刪除document,但只是作了刪除標記,物理上並無刪除) 
3)當段合併時,這些被標記爲刪除的文檔並無被拷貝至新的索引段中,這樣,減小了最終的索引段中的document數目。

五、段合併的好處是什麼?

1)減小索引段的數量並提升檢索速度; 
2)減小索引的容量(文檔數)——段合併會移除被標記爲已刪除的那些文檔。

六、段合併可能帶來的問題?

1)磁盤IO操做的代價; 
2)速度慢的系統中,段合併會顯著影響性能。

第7章 管理Elasticsearch

一、有了副本機制爲何還須要集羣備份?

Elasticsearch 副本提供了高可靠性;它們讓你能夠容忍零星的節點丟失而不會中斷服務。 
可是,副本並不提供對災難性故障的保護。對這種狀況,你須要的是對集羣真正的備份——在某些東西確實出問題的時候有一個完整的拷貝。

二、集羣如何備份?

使用 snapshot API備份你的集羣。 
它會拿到你集羣裏當前的狀態和數據而後保存到一個共享倉庫裏。這個備份過程是」智能」的。 

ES5.6集羣備份官網參考: http://t.cn/RjKEH9G

三、集羣備份分類?

完整備份——你的第一個快照會是一個數據的完整拷貝。 
增量備份——全部後續的快照會保留的是已存快照和新數據之間的差別。隨着你不時的對數據進行快照,備份也在增量的添加和刪除。這意味着後續備份會至關快速,由於它們只傳輸很小的數據量。

四、集羣能夠備份到哪裏?

要使用這個功能,你必須首先建立一個保存數據的倉庫。有多個倉庫類型能夠供你選擇:

  • 共享文件系統,好比 NAS

  • Amazon S3:亞馬遜Web雲服務

  • HDFS (Hadoop集羣分佈式文件系統)

  • Azure Cloud:微軟雲平臺

五、備份操做API?

PUT _snapshot/my_backup 

{

    "type": "fs", 

    "settings": {

        "location": "/mount/backups/my_backup" 

    }
}

注意:共享文件系統路徑必須確保集羣全部節點均可以訪問到。

第8章 提升性能

一、什麼狀況下會出現堆內存泄漏?

若是沒有足夠的堆內存來供你的應用在堆上建立新對象,JVM會拋出一個OutOfMemeory異常,這是一個內存出了問題的跡象,要麼是沒有足夠的內存給它,要麼是有內存泄漏,致使沒有釋放再也不使用的對象。

二、推薦的性能測試工具?

1)JMeter 
2)ab(Apache基準測試工具)

三、ES須要優化的緣由?

1)硬件問題——如機械硬盤和固態硬盤; 
2)不良的數據結構; 
3)糟糕的查詢設計——如wildcard模糊匹配很長的字符串。

四、後臺什麼在運行致使CPU飆升?如何排查?

熱點線程APi能向你提供查找問題根源所必需的信息。 

GET /_nodes/hot_threads?pretty

五、如何擴展集羣?

1)垂直擴展 
向Elasticsearch集羣添加更多的資源。 
制約因素——如:JVM最大支持31GB物理內存。

2)水平擴展 
索引多分片、多副本,集羣中分散處理之。

優勢:下降運行集羣的成本。 
版本升級後(如5.X升級到6.0),確保服務仍然可用。

六、集羣架構設計考慮因素?

當你在設計架構、決定節點數量、有多少個索引以及每一個索引的分片數量時,你須要把能接受的出現故障的節點數量考慮進去。

固然了,你還須要考慮性能,只不過冗餘和高可用應該是進行擴展時的一個因子。

七、大規模集羣節點角色如何設定?

爲了有一個徹底容錯和高可用的集羣,咱們應該區分節點,爲每一個節點一個設計好的角色,角色分類以下: 

1)路由節點或查詢聚合節點;

發送子查詢到其餘節點,收集和合並結果,以及響應發出查詢的客戶端。

node.master: false

node.data: false

2)數據節點;

node.master: false

node.data: true

3)候選主節點。

node.master: true

node.data: false

http.enabled: false

候選主節點禁用Http協議是爲了不意外地在這些節點上進行查詢。這樣候選主節點相比於數據節點和路由節點可使用更少的資源,能夠確保它們僅僅被用來處理和主節點相關的工做。

八、高負載場景Elasticsearch優化的常規建議?

這裏是建議,不是準則。 
(1)選擇正確的存儲 
如:選擇默認的default存儲類型。

(2)按需設定刷新頻率 
索引刷新頻率定義:文檔須要多長時間才能出如今搜索結果中。 
正確認知: 
1)刷新頻率越短,查詢越慢,且索引文檔的吞吐率越低。 
2)默認刷新頻率:1s刷新一次。 
3)無限的增長刷新時間是沒有意義的,由於超過必定的值(取決於你的數據負載和數據量)以後,性能提高變得微乎其微。

(3)線程池優化 
線程池優化的必要場景:你看到節點正在填充隊列而且仍然有計算能力剩餘,且這些計算能力能夠被指定用於處理待處理的任務。

(4)調整合並過程 
index.merge.policy.mery_factory低於默認值10,會致使更少的段,更低的RAM消耗,更快的查詢速度和更慢的索引速度; 
若大於10,致使索引由更多的分段組成,更高的RAM消耗,更慢的查詢速度和更快的索引速度。

(5)合理數據分佈 
高索引量的使用場景:把索引分散到多個分片上來下降服務器CPU和I/O子系統的壓力。

若是你的節點沒法處理查詢帶來的負載,你能夠增長更多的ES節點,並增長副本的數量,因而主分片的物理拷貝會部署到新增節點上。這樣會使得文檔索引慢一些,可是會給你同時處理更多查詢的能力。

9.高負載、高查詢頻率場景的建議

(1)啓動過濾器緩存和分片查詢緩存 
過濾器緩存配置:indices.cache.filter.size 
分片查詢緩存配置:indices.cache.query.enable

(2)優化查詢語句結構 
書本中的過濾器已再也不使用5.X以及更高版本。 
但,依然能夠優化查詢語句,返回覈對查詢一樣語句返回時間,進行權衡優化。

(3)使用路由 
有着相同路由值的數據都會保存到相同的分片上。

(4)並行查詢 
建議數據平均分配,多個節點能夠有相同的負載。

(5)字段數據緩存和斷路 
當使用聚合和排序等字段數據緩存相關操做時,遇到了內存相關的問題(內存泄漏或者GC停頓),能夠考慮使用 doc value。

(6)控制size和shard_size 
主要針對聚合操做。 
增長size和shard_size能使得聚合結果更準確,代價是:更多的網絡開銷和內存使用; 
減小size和shard_size能使得聚合不那麼精確,代價是:網絡開銷小和內存使用率低。

十、高負載、高索引吞吐量場景

(1)批量索引 
批量索引代替逐個索引文檔。

(2)doc values和索引速度的取捨 
一方面:咱們只關心更高的索引速度和更大的索引吞吐量,能夠考慮不適用doc values。 
另外一方面:若是有大量的數據,爲了使用聚合和排序功能而不產生內存相關問題,惟一選擇——使用 doc values。

(3)控制文檔字段 
方式一:_source 控制字段輸出; 
方式二:禁用_all。 
減小文檔的大小和其內文本字段的數量會讓索引稍快一些。

(4)索引的結構和副本 
1)主分片部署到全部的節點上,以便:並行的索引文檔,加快索引的速度。 
2)過多的副本致使索引速度降低。

(5)調整預寫日誌。

(6)存儲優化 
1)資金充足,建議購買SSD——緣由:速度優點明顯; 
2)資金不足,考慮ES使用多個數據路徑。 
3)不要使用共享或者遠程的文件系統保存索引——緣由:速度慢,總體性能降低。

(7)索引期間的內存緩存 
建議給每一個索引期間生效的分片分配512MB內存。 
indices.memeory.index_buffer_size是設置節點的,而不是分片。

小結

書中基於ES1.X版本的一些優化細節,可能在5.X、6.X甚至更高版本中有所不一樣,須要根據實戰須要、並結合最新官網文檔更新相關知識。 
ES仍然有很長的路要走,堅持、加油!

image.png

相關文章
相關標籤/搜索