【技術分享】《深入理解Elasticsearch》讀書筆記

工程師甲發表於2017-11-28

題記

由於之前已經梳理過Elasticsearch基礎概念且在專案中實戰過Elasticsearch的增刪改查、聚類、排序等相關操作,對Elasticsearch算是有了一定的認知。但是,仍然對於一些底層的原理認知模糊,特買來《深入理解Elasticsearch》過了一遍,第一章到第四章偏應用,跟著敲一遍程式碼基本就能理解原理,第五章到第九章偏理論。現將書中一些細節知識點結合官網文件梳理如下。

第五章 分散式索引架構

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

  • 目的:規劃索引及配置,適應應用的變化。
  • 正確認知:分片數索引建立後不可以修改,副本數索引建立後可以通過API隨時修改。
  • 多副本的缺點:額外副本佔據了額外的儲存空間,構建索引副本的開銷也隨之增大。
  • 同時要注意:如果不建立副本,當主分片發生問題時,可能會造成資料的丟失。
  • 配置參考:最理想的分片數量應該依賴於節點的數量。
  • 參考公式:所需的最大節點數 = 分片數 *(副本數+1)
    舉例:你計劃5個分片和1個副本,那麼所需要的最大的節點數為:5*(1+1)=10個節點。

可不可以基於時間構建索引?

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

第六章 底層索引控制

什麼是段?

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

在建立索引的時候,ES會把文件資訊寫到記憶體bugffer中(為了安全,也一起寫到translog),定時(可配置)把資料寫到segment快取小檔案中,然後重新整理查詢,使剛寫入的segment可查。

雖然寫入的segment可查詢,但是還沒有持久化到磁碟上。因此,還是會存在丟失的可能性的。所以,ES會執行flush操作,把segment持久化到磁碟上並清除translog的資料(因為這個時候,資料已經寫到磁碟上,不再需要了)。
參考連結

什麼是段合併?

由於自動重新整理流程每秒會建立一個新的段,這樣會導致短時間內的段數量暴增。而段數目太多會帶來較大的麻煩。

  • 消耗資源:每一個段都會消耗檔案控制程式碼、記憶體和cpu執行週期;
  • 搜尋變慢:每個搜尋請求都必須輪流檢查每個段,所以段越多,搜尋也就越慢。

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

段合併做了什麼?

段合併的時候會將那些舊的已刪除文件從檔案系統中清除。

被刪除的文件(或被更新文件的舊版本)不會被拷貝到新的大段中。

啟動段合併不需要你做任何事。進行索引和搜尋時會自動進行。

  • 當索引的時候,重新整理(refresh)操作會建立新的段並將段開啟以供搜尋使用。
  • 合併程式選擇一小部分大小相似的段,並且在後臺將它們合併到更大的段中。這並不會中斷索引和搜尋。

為什麼要進行段合併?

  • 索引段的個數越多,搜尋效能越低並且消耗更多的記憶體;
  • 索引段是不可變的,你並不能物理上從中刪除資訊。(可以物理上刪除document,但只是做了刪除標記,物理上並沒有刪除)
  • 當段合併時,這些被標記為刪除的文件並沒有被拷貝至新的索引段中,這樣,減少了最終的索引段中的document數目。

段合併的好處是什麼?

  • 減少索引段的數量並提高檢索速度;
  • 減少索引的容量(文件數)——段合併會移除被標記為已刪除的那些文件。

段合併可能帶來的問題?

  • 磁碟IO操作的代價;
  • 速度慢的系統中,段合併會顯著影響效能。

第七章 管理Elasticsearch

有了副本機制為什麼還需要叢集備份?

Elasticsearch 副本提供了高可靠性;它們讓你可以容忍零星的節點丟失而不會中斷服務。

但是,副本並不提供對災難性故障的保護。對這種情況,你需要的是對叢集真正的備份——在某些東西確實出問題的時候有一個完整的拷貝。

叢集如何備份?

使用 snapshot API備份你的叢集。

它會拿到你叢集裡當前的狀態和資料然後儲存到一個共享倉庫裡。這個備份過程是”智慧”的。
ES5.6叢集備份官網參考

叢集備份分類?

完整備份——你的第一個快照會是一個資料的完整拷貝。

增量備份——所有後續的快照會保留的是已存快照和新資料之間的差異。隨著你不時的對資料進行快照,備份也在增量的新增和刪除。這意味著後續備份會相當快速,因為它們只傳輸很小的資料量。

叢集可以備份到哪裡?

要使用這個功能,你必須首先建立一個儲存資料的倉庫。有多個倉庫型別可以供你選擇:

  • 共享檔案系統,比如 NAS
  • HDFS (Hadoop叢集分散式檔案系統)

備份如何操作API?

PUT _snapshot/my_backup
{

"type": "fs",
"settings": {
    "location": "/mount/backups/my_backup"
}

}

注意:共享檔案系統路徑必須確保叢集所有節點都可以訪問到。

##第八章 提高效能

>####什麼情況下會出現堆記憶體洩漏?

>>如果沒有足夠的堆記憶體來供你的應用在堆上建立新物件,JVM會丟擲一個OutOfMemeory異常,這是一個記憶體出了問題的跡象,要麼是沒有足夠的記憶體給它,要麼是有記憶體洩漏,導致沒有釋放不再使用的物件。

>####推薦的效能測試工具?

>>- JMeter
- ab(Apache基準測試工具)

>####ES需要優化的原因?

>>- 硬體問題——如機械硬碟和固態硬碟;
- 不良的資料結構;
- 糟糕的查詢設計——如wildcard模糊匹配很長的字串。

>####後臺什麼在執行導致CPU飆升?如何排查?

>>熱點執行緒APi能向你提供查詢問題根源所必需的資訊。
GET /_nodes/hot_threads?pretty

>####如何擴充套件叢集?

>>- 垂直擴充套件
向Elasticsearch叢集新增更多的資源。
制約因素如:JVM最大支援31GB實體記憶體。
- 水平擴充套件
索引多分片、多副本,叢集中分散處理之。
優點:降低執行叢集的成本。
版本升級後(如5.X升級到6.0),確保服務仍然可用。

>####叢集架構設計考慮因素?

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

>>當然了,你還需要考慮效能,只不過冗餘和高可用應該是進行擴充套件時的一個因子。

>####大規模叢集節點角色如何設定?

>>為了有一個完全容錯和高可用的叢集,我們應該區分節點,為每個節點一個設計好的角色,角色分類如下:
- 路由節點或查詢聚合節點;
傳送子查詢到其他節點,收集和合並結果,以及響應發出查詢的客戶端。

node.master: false
node.data: false

- 資料節點

node.master: false
node.data: true

- 候選主節點

node.master: true
node.data: false
http.enabled: false


>>候選主節點禁用Http協議是為了避免意外地在這些節點上進行查詢。這樣候選主節點相比於資料節點和路由節點可以使用更少的資源,可以確保它們僅僅被用來處理和主節點相關的工作。

>####高負載場景Elasticsearch優化的常規建議?

>>這裡是建議,不是準則。
- 選擇正確的儲存,如:選擇預設的default儲存型別。
- 按需設定重新整理頻率
索引重新整理頻率定義:文件需要多長時間才能出現在搜尋結果中。
- 正確認知:
重新整理頻率越短,查詢越慢,且索引文件的吞吐率越低。
預設重新整理頻率:1s重新整理一次。
無限的增加重新整理時間是沒有意義的,因為超過一定的值(取決於你的資料負載和資料量)之後,效能提升變得微乎其微。
- 執行緒池優化
執行緒池優化的必要場景:你看到節點正在填充佇列並且仍然有計算能力剩餘,且這些計算能力可以被指定用於處理待處理的任務。
- 調整合並過程
index.merge.policy.mery_factory低於預設值10,會導致更少的段,更低的RAM消耗,更快的查詢速度和更慢的索引速度;
若大於10,導致索引由更多的分段組成,更高的RAM消耗,更慢的查詢速度和更快的索引速度。
- 合理資料分佈
高索引量的使用場景:把索引分散到多個分片上來降低伺服器CPU和I/O子系統的壓力。

>>如果你的節點無法處理查詢帶來的負載,你可以增加更多的ES節點,並增加副本的數量,於是主分片的物理拷貝會部署到新增節點上。這樣會使得文件索引慢一些,但是會給你同時處理更多查詢的能力。

>###高負載、高查詢頻率場景的建議

>>- 啟動過濾器快取和分片查詢快取
過濾器快取配置:indices.cache.filter.size
分片查詢快取配置:indices.cache.query.enable
- 優化查詢語句結構
書本中的過濾器已不再使用5.X以及更高版本。
但,依然可以優化查詢語句,返回核對查詢同樣語句返回時間,進行權衡優化。
- 使用路由
有著相同路由值的資料都會儲存到相同的分片上。
- 並行查詢
建議資料平均分配,多個節點可以有相同的負載。
- 欄位資料快取和斷路
當使用聚合和排序等欄位資料快取相關操作時,遇到了記憶體相關的問題(記憶體洩漏或者GC停頓),可以考慮使用 doc value。
- 控制size和shard_size
主要針對聚合操作。
增加size和shard_size能使得聚合結果更準確,代價是:更多的網路開銷和記憶體使用;
減少size和shard_size能使得聚合不那麼精確,代價是:網路開銷小和記憶體使用率低。

>####高負載、高索引吞吐量場景

>>- 批量索引
批量索引代替逐個索引文件。
- doc values和索引速度的取捨
一方面:我們只關心更高的索引速度和更大的索引吞吐量,可以考慮不適用doc values。
另一方面:如果有大量的資料,為了使用聚合和排序功能而不產生記憶體相關問題,唯一選擇——使用 doc values。
- 控制文件欄位
方式一:_source 控制欄位輸出;
方式二:禁用_all。
減少文件的大小和其內文字欄位的數量會讓索引稍快一些。
- 索引的結構和副本
1) 主分片部署到所有的節點上,以便:並行的索引文件,加快索引的速度。
2)過多的副本導致索引速度下降。
- 調整預寫日誌。
- 儲存優化
1)資金充足,建議購買SSD——原因:速度優勢明顯;
2)資金不足,考慮ES使用多個資料路徑。
3)不要使用共享或者遠端的檔案系統儲存索引——原因:速度慢,整體效能下降。
- 索引期間的記憶體快取
建議給每個索引期間生效的分片分配512MB記憶體。
indices.memeory.index_buffer_size是設定節點的,而不是分片。

##小結

>書中基於ES1.X版本的一些優化細節,可能在5.X、6.X甚至更高版本中有所不同,需要根據實戰需要、並結合最新官網文件更新相關知識。

作者:銘毅天下   文章轉載自http://blog.csdn.net/laoyang360

##加入釘釘技術討論群

<p style="text-align:center"><img src="https://yqfile.alicdn.com/fd66fe6dfb293dc9cd7e02122200196dd063f45e.jpeg" width = "200" height = "248" alt="dingQR"></p>
阿里雲Elasticsearch已正式釋出啦,Elastic開源官方聯合開發,整合5.5.3商業版本XPack功能,歡迎開通使用。


相關文章