1. 程式人生 > >Elasticsearch運維經驗總結

Elasticsearch運維經驗總結

版本說明:5.6.4(要嚴格注意ES及其外掛、第三方工具的版本匹配關係)

系統負載:(日誌叢集,日均寫入10TB,保留7天)

1,出於高可用的考慮,同一個分割槽的多個副本不會被分配到同一臺機器

如下截圖所示,Index:queries,設定20副本,5分片。這個叢集當前有14個可用資料節點,queries的0分割槽在這14個數據節點上均有且僅有一個副本,剩餘​​的7個副本顯示UNASSIGNED,並不會在當前14個節點上重複分配

2,Local Gateway引數生效順序(僅在重啟master時生效)

  • gateway:expected_nodes,只要達到該值,立即可以進入恢復狀態,假如有恢復必要的話
  • gateway:recover_after_time,如果未達到expected_nodes值,則需要等待recover_after_time時長,不管你當前有多少個nodes了
  • gateway:recover_after_nodes,在達到recover_after_time的時間後,還需要達到recover_after_nodes的設定值,才能進入恢復狀態

3,避免所有索引被刪除

  • action.destructive_requires_name:true,通過該引數禁止通過正則進行index的刪除操作
  • curl -XDELETE http://localhost:9200/*/

4,避免使用虛擬記憶體(三選一)

  • 最佳方式:關閉作業系統的swap分割槽(swapoff -a)
  • 次選:vm.swappiness=0(僅在實體記憶體不夠時才使用swap分割槽)
  • 最後:bootstrap.memory_lock: true

5,叢集各類角色

  • node.master(顯示)
  • node.data(顯示)
  • node.ingest(顯示)
  • node.coordinatint(隱性)
  • Every node is implicitly a coordinating node. This means that a node that has all three node.master
    node.data and node.ingest set to false will only act as a coordinating node, which cannot be disabled.

6,master數量至少3個,避免腦裂

  • discovery.zen.minimum_master_nodes: 2

7,操作命令

  • 調整副本數:curl -XPUT http://localhost/yunxiaobai/_settings?pretty -d ‘{“settings”:{“index”:{“number_of_replicas”:”10″}}}’
  • 建立index:curl -XPUT ‘localhost:9200/yunxiaobai?pretty’
  • 插入資料:curl -XPUT ‘localhost:9200/yunxiaobai/external/1?pretty’ -d ‘ { “name”:”yunxiaobai” }’
  • 獲取資料:curl -XGET ‘localhost:9200/yunxiaobai/external/1?pretty’
  • 刪除索引:curl -XDELETE ‘localhost:9200/jiaozhenqing?pretty’
  • 遮蔽節點:curl -XPUT 127.0.0.1:9200/_cluster/settings?pretty -d ‘{ “transient” :{“cluster.routing.allocation.exclude._ip” : “10.0.0.1”}}’
  • 刪除模板:curl -XDELETE http://127.0.0.1:9200/_template/metricbeat-6.2.4
  • 調整shard重新整理時間:curl -XPUT http://localhost:9200/metricbeat-6.2.4-2018.05.21/_settings?pretty -d ‘{“settings”:{“index”:{“refresh_interval”:”30s”} }}’
  • 提交模板配置檔案:curl -XPUT localhost:9200/_template/devops-logstore-template -d @devops-logstore.json
  • 查詢模板: curl -XGET localhost:9200/_template/devops-logstor-template
  • 查詢執行緒池:http://localhost:9200/_cat/thread_pool/bulk?v&h=ip,name,active,rejected,completed

8,叢集健康狀態

  • green:所有的主分片和副本分片都正常執行。
  • yellow:所有的主分片都正常執行,但不是所有的副本分片都正常執行。
  • red:有主分片沒能正常執行。

9,故障節點分片延時分配

  • index.unassigned.node_left.delayed_timeout:1m,該配置表示一個節點故障1m後,系統會開始對該節點上的分片進行恢復操作。如果故障節點上的分片是主分片,那麼即使是延時分配,其他節點對應的分片副本也會被置為主分片,否則,該索引無法正常使用,僅僅是延時了副本的故障恢復。之所以有時候需要調整該值,是為了避免一些糟糕情況的發生,例如一臺機器宕機重啟,那麼因為啟動耗時超過一分鐘,所以系統會對該機器上的分片進行故障恢復,恢復完畢後,這臺機器啟動完畢服務恢復了,那麼這臺機器上的資料就沒有意義了,就被刪除了。這時候,因為這是一個空機器了,所以系統還會觸發平衡操作,這折騰就大了。設定為0時,表示不等待節點故障立即重新分配。Since elasticsearch 5.x index level settings can NOT be set on the nodes configuration like the elasticsearch.yaml, in system properties or command line arguments.In order to upgrade all indices the settings must be updated via the /${index}/_settings API.
  • cluster.routing.allocation.enable”:”none”,該引數配置生效時,可以建立索引,但是索引是處於不可用狀態的

10,名詞解釋

  • indexes和indices區別
    • indices一般在數學,金融和相關領域使用,而indexes使用則相對廣泛
    • indexes在美國、加拿大等國的英語裡比較常見。但indices盛行於除北美國家以外的英語裡。
  • index和lucene的區別
    • 在叢集級別上的索引稱為index
    • 在節點級別(各個分片都是一個lucene索引)稱為lucene

11,滾動升級(升級期間,叢集處於不可用狀態)

  • Disable shard allocation
    • curl -XPUT http://localhost:9200/_cluster/settings?pretty -d ‘{ “persistent”: {“cluster.routing.allocation.enable” : “none” } } ‘,此時可以建立索引,但是索引不可用
  • Stop non-essential indexing and perform a synced flush
    • curl -X POST “localhost:9200/_flush/synced” 此時叢集不對外進行響應
  • Shut down a single node
  • Upgrade the node you shut down
  • Upgrade any plugins
  • Start the upgraded node
  • Reenable shard allocation
    • curl -XPUT http://localhost:9200/_cluster/settings?pretty -d ‘{ “persistent”: {“cluster.routing.allocation.enable” : “all” } } ‘
  • Wait for the node to recover
  • Repeat

12,關鍵指標(參考x-pack)

  • indices.search.query_current/indices.search.query_total
  • indices.search.query_time_in_millis
  • indices.indexing.index_current/indices.indexing.index_total
  • indices.indexing.index_time_in_millis
  • jvm.mem.heap_used_percent
  • number_of_nodes(_cat/health)
  • active_shards_percent_as_number(_cat/health)
  • status(_cat/health)

13,如何設定索引的分片數比較合適

條件:

  • 每GB的堆對應的分片數量應低於20個
  • 每個節點有jvm堆記憶體 30G
  • fielddata 大小9G
  • 磁碟容量1490GB,則可用的磁碟容量為:1490GB*12.8%=1299.28GB約1299GB
  • 儘量保持分片大小一致

結論:

索引主分片規模為:
單個分片容量:1200GB/(30*20)=2.165GB
對於一個新建索引,預測總大小10GB,則共設定主分片:10GB/2GB=5個

14,叢集的索引副本數如何確定

  • 當ES的查詢操作較少時(每秒少於一個查詢操作),副本數為1即可保證了資料的冗餘(況且還有備份)
  • ES副本數為2時,可以提高查詢效能(副本可以分擔索引的查詢操作):代價為CPU,記憶體和檔案控制代碼

參考文獻:https://www.elastic.co/guide/en/elasticsearch/guide/2.x/replica-shards.html

https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index

15,es 配置多個 data path 時的分配策略

參考資料:https://cyberdak.github.io/es/2018/07/08/es-disk-allocate-strategy

16,ES叢集的備份和恢復

官方給出的ES叢集的資料備份方式

  • S3 Repository
  • Azure Repository
  • HDFS Repository
  • Google Cloud Storage Repository

以下是使用HDFS進行資料備份和恢復,HDFS備份是基於增量備份方式進行備份的,需要安裝repository-hdfs外掛並重啟叢集才能生效。

對於使用HDFS來進行備份的方式,這是一種增量備份的方式(同一個儲存庫下,資料是增量備份的,每次備份,系統僅備份發生變化的segment)

使用的API:

#HDFS配置和建立儲存庫

curl -XPUT  “http://localhost:9200/_snapshot/ my_backup”  -d ‘

 { 

       “type”: “hdfs”, 

       “settings”: {

                    “path”: “/back/es/”, #儲存庫路徑

                    “load_defaults”: “true”, #載入Hadoop預設配置

                    “compress”: “true”, 

                    “uri”: “hdfs://localhost:8020” } #Hadoop IP地址

 }

#建立快照

# snapshot_1為快照名稱

curl -XPUT “http://localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true ” -d ‘{

         “indices”: “index_1,index_2”, //注意不設定這個屬性,預設是備份所有索引                           

         “include_global_state”: false 

}

 

#ES資料恢復

#本叢集恢復,查詢要恢復的快照ID,執行如下命令恢復資料

curl -XPOST   http://localhost:9200/_snapshot/my_backup/backup_1/_restore’

17,curator外掛–ES索引管理外掛

  • curator安裝

pip install elasticsearch-curator

  • curator的配置檔案

curator需要兩個檔案來對叢集進行操作:curator.yml(curator的配置檔案),action_file.yml(curator執行的動作)

curator.yml格式:

更改hosts和port連線叢集的地址和埠,更改logfile為日誌路徑。

action_file.yml格式:

1:模式是匹配

2.:匹配的索引的名稱,支援正則

3,4:指刪除7天前的索引

5:多個任務需要按照順序新增

  • curator的執行命令

curator –config curator.yml action_file.yml

以上命名需要加上檔案的路徑

  • 執行成功後,會將執行的過程寫入日誌檔案中–logfile中。

18,自動任務

通過系統的crontab來執行自動任務

  • 新建執行指令碼

對於自動刪除索引這個任務來說,可以新建shell指令碼curator.sh

#!/bin/sh

/usr/bin/curator –config /root/.curator/curator_config.yml /root/.curator/action_file.yml

  • 新建自動任務

crontab -e

crontab格式

30 3 * * * /data1/curator/curator.sh

  • 檢視自動任務

crontab -l

19,監控

核心監控項:叢集健康狀態,功能監控,索引延遲,流量監控

黑:黑盒監控

白:白盒監控

監控項介紹:

  • pendin_task

pending task 反應了master節點尚未執行的叢集級別的更改任務(例如:建立索引,更新對映,分配分片)的列表。pending task的任務是分級別的(優先順序排序:IMMEDIATE>URGENT>HIGH>NORMAL>LOW>LANGUID),只有當上一級別的任務執行完畢後才會執行下一級別的任務,這也說明了:當出現HIGH級別以上的pending task任務時,備份和建立索引等一些低級別任務雖然任務對資源佔用不多,也將不會執行,返回異常,“ProcessClusterEventTimeoutException”。

20,kibana調優

  • 在啟動檔案的開頭新增如下配置項:NODE_OPTIONS=”–max-old-space-size=4096″   其中4096的單位為MB

21,推薦外掛

    • X-pack
    • ElasticHQ

  • x-pack許可證書過期的問題

x-pack許可證書分為試用的許可證書和註冊後的許可證書。安裝證書不用重啟節點

當x-pack禁用security functionality可以通過如下步驟來安裝證許可證書:

  1. 註冊elasticsearch
  2. 收到許可證郵件,下載許可證json檔案
  3. 通過如下API來進行安裝
curl -XPUT u elastic 'http://0.0.0.0:9200/_xpack/license?acknowledge=true&pretty' -H "Content-Type;application/json" -d @json

22,資料直接寫入ES還是使用ELK?

  • 直接寫入ES:適用於非核心場景,簡單直接依賴少
  • 需要引入Kafka:適用於核心場景,通過Kafka作為代理層,既可以提升ELK叢集整體的穩定性,也可以引入Hadoop生態做形式的資料分析。
    • 基於多ES叢集消費實現多叢集熱備,實現單叢集故障後快速切換到其他可用叢集
    • ES故障期間Kafka作為資料緩衝避免資料丟失,故障恢復後繼續消費故障期間的資料
    • 控制消費速率,避免ES被突增流量壓死
    • 實現批量寫操作,提升ES效能,分散式直接寫入ES很難做聚合

23,ES引入代理的優勢

  • 封禁部分高危操作,如調整叢集引數,刪除操作等
  • 封禁部分業務訪問,如非授權使用者,測試使用者等

24,叢集出現UNASSIGNED shards

叢集分片分配機制

ES叢集的分片分配由“allocators”和“deciders”控制,“allocators”負責返回給“deciders”一個滿足要求的nodes列表,“deciders”從列表中確定到底分片應分配到哪個nodes。
“allocators”按照各節點的分片數量來獲得合適的nodes列表(如果有分配權重則另說)
“deciders”根據一些過濾器來確定最終的分配nodes(分配的設定要求)
對於一個分片的分配,分為新建索引的分片分配,對於已經存在的索引,分為主分片和副本分片的分配
對於新建的索引,“allocators”尋找nodes列表的原則是保持叢集的平衡(各個nodes上的分片數儘量保持一致,不是nodes的size)
對於已經存在的索引的主分片:只會允許分配到良好的最新的副本分片上,之後會選擇其他副本(資料將有丟失)
參考資料:https://www.elastic.co/blog/red-elasticsearch-cluster-panic-no-longer

原因:

  • 有目的的延遲

  • 分片太多,節點不夠

  • 需要重啟分片分配

  • 磁碟量達到限制,禁止寫入新的索引

  • ES叢集的版本不一樣

處理流程:

  1. 檢視有哪些索引有UNASSIGEMED shards  注1

  2. 若對應的索引沒用(資料沒有用,索引可以刪除)直接刪除

  3. 檢視UNASSIGNED shards的詳細未分配原因  注2

  4. 針對不同的原因提供不同的解決辦法

注1:

curl -XGET “http://hb-dev-es.jdcloud.com:80/_cat/shards?h=index,shard,prirep,state,unassigned.reason” | grep UNASSIGNED

注2:

curl -XGET “http://hb-dev-es.jdcloud.com:80/_cluster/allocation/explain?pretty”

25,ES叢集重啟預案及影響分析

ES叢集重啟預案

es每個節點均是有狀態,不同索引分片配置設定不同,單個分片可能有冗餘,可能有1備份。因此,為不影響服務,升級或者重啟es服務需要逐個依次進行(滾動重啟)

#注:重啟操作應在叢集狀態為green時進行,重啟任一一個節點前後,都要保證在叢集狀態恢復到green狀態時。
#步驟1-禁用分片分配
#如果不禁止,當停止某一節點後,分片分配程序會進行UNASSIGNED分片的分配(當叢集狀態達到recovery要求,觸發恢復閾值時)。這樣的情況下,會造成大量的IO操作。但是禁用分片後,功能上會禁止新建索引。
curl -X PUT http://0.0.0.0:9200/_cluster/settings?pretty -d '{"transient": {"cluster.routing.allocation.enable": "none"}}'
#步驟2-驗證修改後的配置:
curl -X GET http://0.0.0.0:9200/_cluster/settings?pretty
#步驟3-執行同步重新整理
#這一步操作的原因是:當有分片在叢集重啟過程中並沒有發生更新,則跳過對這些分片的同步校驗,提高分片恢復的速度
curl -XPOST "http://0.0.0.0:9200/_flush/synced?pretty"
#步驟4-重啟client-node節點
#重啟client-node組節點有小概率導致寫入丟失(由於LB的輪詢策略:當一個節點離線後,10s內不會再將請求分配到該節點。可以通過不要立即重啟另外的client節點來避免此問題)
##子步驟1--重啟一個client-node組的節點
##子步驟2--確認節點加入叢集
##通過命令檢視叢集狀態和檢視節點數
curl -XGET http://0.0.0.0:9200/_cluster/health?pretty
##子步驟3--按照子步驟1-2重啟剩餘的client-node節點
#步驟5-重啟master節點
##子步驟1--重啟一個master-node的非master節點
##子步驟2--確認節點加入叢集
##子步驟3--重複子步驟1-2重啟剩餘的非master節點
##子步驟4--重複子步驟1-2重啟剩餘的master節點
##子步驟5--檢查master是否重新選舉成功(30s後會開始選舉:原因discovery.zen.ping_timeout:30s)
##master選舉過程中會堵塞寫操作,對search無影響,堵塞API的操作
#步驟6-重啟data-node節點
##子步驟1--重啟一個data-node組的data-node節點
##子步驟2--確認節點加入叢集
##子步驟3--重複子步驟1-2重啟剩餘的data節點
#步驟7-啟用分片分配
curl -X PUT http://0.0.0.0:9200/_cluster/settings?pretty -d '{"transient": {"cluster.routing.allocation.enable": "all"}}'


最後,常見日誌錯誤

 

  • 叢集名稱不一致:java.lang.IllegalStateException: handshake failed, mismatched cluster name
  • 配置檔案報錯:java.lang.IllegalArgumentException: node settings must not contain any index level settings
  • org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException: failed to process cluster event (put-mapping) within 30s
  • cluster state update task [put-mapping[type-2018-05-20-22-25-1526826326]] took [57.2s] above the warn threshold of 30s
  • [o.e.a.a.i.m.p.TransportPutMappingAction] failed to put mappings on indices [[[tpmonitor-elasticsearch/Vzr0MlOKRimGGCcMb0wIdA]]], type [type-2018-05-21-22-18-1526912288]
  • Failed to connect to server: 10.1.1.1/10.1.1.1:9000: try once and fail.
  • [2018-05-22T16:50:59,473][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [172-0] uncaught exception in thread [main]
    org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: Unable to access ‘path.data’ (/data10/elasticsearch)