成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

ElasticSearch集群災難:別放棄,也許能再搶救一下

開發 前端
如果沒有顯示設置節點角色,es的每個節點都會含有以上三種角色。除此之后還有Remote-eligible node 、ml-node和Transform nodes等角色需要顯示的配置,節點才會有該角色。
1 前言

Elasticsearch作為一個分布式搜索引擎,自身是高可用的;但也架不住一些特殊情況的發生,如:

集群超過半數的master節點丟失,ES的節點無法形成一個集群,進而導致集群不可用;

索引shard的文件損壞,分片無法被正常恢復,進而導致索引無法正常提供服務

本地盤節點,多數據節點故障,舊節點無法再次加入集群,數據丟失

針對上述的情況,今天來聊一聊相關的解決方案。

2 基礎知識

2.1 集群經典架構

在聊解決方案之前,首先來看一看ES集群層面的基本知識,es的集群組成通常如圖1-1所示

圖 1-1 es常用集群架構圖 1-1 es常用集群架構

如圖1-1所示,為生產環境es集群的經典架構,主要由專有主節點、專有協調節點和數據節點組成:

  • 專有主節點(Master-eligible node): 具有master角色的節點,這使其有資格被選為主節點,只存儲集群元信息包含cluster、index、shard級別的元數據;該種角色節點被選舉為master之后,將作為整個ES集群的大腦,負責維護集群層面的元信息,創建刪除索引等工作。該種節點的個數必須為奇數,通常我們固定為3個,如果該類節點丟失半數,es集群將無法維持es節點形成一個集群。
  • 專有協調節點(網關節點): 該種節點不具有任何角色,僅僅用來處理es請求;比如(1)將寫請求的數據歸類轉發到數據所屬的節點(2)查詢請求的二次聚合計算。通常我們也會給該類節點保留ingest角色 ,ingest的主要作用是對數據進行預處理;比如:字段重命名、給數據文檔打上指紋和清洗數據等功能主要通過pipeline能力進行處理
  • 數據節點(Data node): 存儲數據和集群元信息,執行與數據相關的操作,如CRUD、搜索和聚合。在數據節點上打上不同的屬性,可以使其成為hot、warm、cold數據節點,在es7.9版本之后配置略有不同,但是原理基本不變。

如果沒有顯示設置節點角色,es的每個節點都會含有以上三種角色。除此之后還有Remote-eligible node 、ml-node和Transform nodes等角色需要顯示的配置,節點才會有該角色。

2.2 集群元信息

集群完全啟動主要包含選舉主節點、元信息、主分片、數據恢復等重要階段;如圖2-1所示[1]。

圖 2-1 es集群啟動流程圖 2-1 es集群啟動流程

主節點選舉的過程,不是本文的重點,而是集群元信息的選舉。被選舉出的master和集群元信息新舊程度沒有關系;master節點被選舉出來之后,它所要完成的第一個任務,即是選舉集群元信息。

(1)Master選舉成功之后,判斷其持有的集群狀態中是否存在STATE_NOT_RECOVERED_BLOCK,如果不存在,則說明元數據已經恢復,跳過gateway恢復過程,否則等待。org.elasticsearch.gateway.GatewayService#clusterChanged

//跳過元數據恢復
if (state.blocks().hasGlobalBlock(STATE_NOT_RECOVERED_BLOCK) == false) {
            // already recovered
            return;
 }
 //此處省略部分代碼。
 //進入gateway恢復過程   
performStateRecovery(enforceRecoverAfterTime, reason);

(2)Master從各個節點主動獲取元數據信息。org.elasticsearch.gateway.Gateway#performStateRecovery

# 獲取元信息核心代碼
 final String[] nodesIds = clusterService.state().nodes().getMasterNodes().keys().toArray(String.class);
        logger.trace("performing state recovery from {}", Arrays.toString(nodesIds));
        final TransportNodesListGatewayMetaState.NodesGatewayMetaState nodesState = listGatewayMetaState.list(nodesIds, null).actionGet();

(3)從獲取的元數據信息中選擇版本號最大的作為最新元數據;元信息包括集群級、索引級。

## org.elasticsearch.gateway.Gateway#performStateRecovery

    public void performStateRecovery(final GatewayStateRecoveredListener listener) throws GatewayException {
# 省略若干行代碼

## 進入allocation階段;
## final Gateway.GatewayStateRecoveredListener recoveryListener = new GatewayRecoveryListener();
## listener為 GatewayStateRecoveredListener   
 listener.onSuccess(builder.build());    
}

(4)兩者確定之后,調用allocation模塊的reroute,對未分配 的分片執行分配,主分片分配過程中會異步獲取各個shard級別元數據。

#主要實現方法為如下方法   
#org.elasticsearch.gateway.GatewayService.GatewayRecoveryListener#onSuccess
## 主要工作是構建集群狀態(ClusterState),其中的內容路由表 依賴allocation模塊協助完成,調用 allocationService.reroute 進 入下一階段:異步執行分片層元數據的恢復,以及分片分配。updateTask線程結束.

ES中存儲的數據:(1)state元數據信息;(2)index Lucene生成的索引文件;(3)translog事務日志。元數據信息:

  • nodes/0/_state/*.st,集群層面元信息MetaData(clusterUUID 、 settings 、templates等);
  • nodes/0/indices/{index_uuid}/_state/*.st,索引層面元信息IndexMetaData( numberOfShards 、mappings等);
  • nodes/0/indices/{index_uuid}/0/_state/*.st,分片層面元信息ShardStateMetaData(version 、indexUUID、primary等)。

上述信息被持久化到磁盤:持久化的state不包括某個分片存在于哪個節點這種內容路由信息,集群完全重啟時,依靠gateway的recovery過程重建RoutingTable和RoutingNode。當讀取某個文檔時, 根據路由算法確定目的分片后,再從RoutingTable中查找分片位于哪個節點,然后將請求轉發到目的節點[1]。

?? 注意:在es7.0.0之后es的元信息存儲方式發生變化;es7.0.0之后元信息存儲改使用lucene的方式存儲,見pr50928 Move metadata storage to Lucene)

7.10.2 專有主節點,集群元數據

./
|-- _state
|   |-- _39h.cfe
|   |-- _39h.cfs
|   |-- _39h.si
|   |-- node-0.st
|   |-- segments_50d
|   `-- write.lock
`-- node.lock

6.8.13 專有主節點,集群元數據

./
|-- _state
|   |-- global-230.st
|   `-- node-2.st
|-- indices
|   |-- -hiy4JnoRfqUJHTJoNUt4Q
|   |   `-- _state
|   |       `-- state-4.st
|   `-- ylJKVlqISGOi8EkpxHE_2A
|       `-- _state
|           `-- state-6.st
`-- node.lock

3 災難場景與處理方法

3.1 master節點丟失

?? 注意本文所述的master節點個數,假設前提均為3個

場景1 master節點丟失過半

master節點是控制整個集群;當該種節點角色丟失過半,由于集群中投票節點永遠不可能達到quorum無法選主,將無法維持es節點形成一個集群;雖然集群無法形成一個集群,但所仍幸master-eligible節點存活,我們可以使用如下手段進行處理。

es7.0.0版本之前

  • 修改剩余節點的elasticsearch.yaml配置如下,修改quorum的個數,然后啟動剩余的節點,形成一個新的集群;

discovery.zen.minimum_master_nodes: 1
discovery.zen.ping.unicast.hosts:
- masters-0

  • 重建補充之前丟失的master-eligible節點,加入集群之后.3 將集群配置修改為舊的配置,再逐一重啟下集群中的節點,先從master-eligible開始.

es7.0.0(包含)版本之后.

在es7.0.0版本之后,由于es修改集群的啟動配置,新增配置discovery.seed_hosts 和cluster.initial_master_nodes;es集群第一次啟動時稱為bootstrap,該過程將配置文件中的cluster.initial_master_node作為初始的投票節點Voting configurations,投票節點具有選舉master和commit cluster state的權利,超過半數以上同意即投票成功。如果在集群健康的場景下,我們需要下線超過半數的master-eligible;則必須首先使用投票配置排除API從投票配置中排除受影響的節點。

POST _cluster/voting_config_exclusions?node_names={node_names}
POST _cluster/voting_config_exclusions?node_ids={node_ids}
DELETE _cluster/voting_config_exclusions

但是如果丟失的master節點超過半數,則可以使用新的集群處理工具elasticsearch-node unsafe-bootstrap pr37696 和elasticsearch-node detach-cluster pr37979

面對丟失半數master-eligible,es7.0.0(包含)版本之后的處理步驟如下:1 使用bin/elasticsearch-node unsafe-bootstrap命令讓唯一主節點以不安全的方式改寫投票節點,就像重新進行bootstrap一樣,自己使用持久化的cluster state形成一個新集群2 其他數據節點無法加入新集群因為UUID不同(es使用UUID作為節點和集群的唯一表示,每個節點都會持久化當前集群的UUID),使用bin/elasticsearch-node detach-cluster命令讓節點離開之前的集群3 啟動數據節點和新的master-eligible節點(如下補充兩個新的master-eligible),他會加入新集群中

cluster.initial_master_nodes:
- {master-0}
- {new-master-1}
- {new-master-2}
discovery.seed_hosts:
- {master-ip-0}
- {new-master-ip-1}
- {new-master-ip-2}

場景2 master節點全部丟失

es7.0.0版本之前

1 關閉 security 功能(如果開啟了, 最好先關閉security插件功能):

1.1 因為新啟動的master節點, 沒有數據節點(如果只配置了一個master的角色), security插件的初始化無法完成, 各類接口不好調用

1.2 如果給新啟動的master節點, 配置了master and data角色, 則security插件會初始化成功. 會插入index, 但是這個index會和原來的data節點上保存的沖突. 不知道怎么解.elastic官方xpack-security;關閉鑒權:xpack.security.enabled:false2 啟動足夠的新master-eligible節點形成一個新集群.

discovery.zen.minimum_master_nodes: 2
discovery.zen.ping.unicast.hosts:
- {new-masters-1}
- {new-masters-2}
- {new-masters-3}

3 修改數據節點的為新master的地址,并且刪除掉節點上的_state(因為新集群的cluster UUID不一致),同上

4 啟動數據節點,數據被恢復加入到集群

es7.0.0(包含)版本之后

已經沒有cluster state了,唯一的希望是數據節點上的index數據;恢復方式借助elasticsearch-node 工具

1 關閉security功能(如果開啟了, 最好先關閉security插件功能),原因同上

2 啟動足夠的新master-eligible節點形成一個新集群

cluster.initial_master_nodes:
- {new-master-0}
- {new-master-1}
- {new-master-2}
discovery.seed_hosts:
- {new-master-ip-0}
- {new-master-ip-1}
- {new-master-ip-2}

3 bin/elasticsearch-node detach-cluster命令讓數據節點離開之前的集群

./bin/elasticsearch-node detach-cluster
------------------------------------------------------------------------

    WARNING: Elasticsearch MUST be stopped before running this tool.

------------------------------------------------------------------------

You should only run this tool if you have permanently lost all of the
master-eligible nodes in this cluster and you cannot restore the cluster
from a snapshot, or you have already unsafely bootstrapped a new cluster
by running `elasticsearch-node unsafe-bootstrap` on a master-eligible
node that belonged to the same cluster as this node. This tool can cause
arbitrary data loss and its use should be your last resort.

Do you want to proceed?

Confirm [y/N] y
Node was successfully detached from the cluster

4 查詢dangling索引,GET /_dangling, 改api 引入es7.9版本于 pr581765 啟動數據節點并使用Import dangling indexAPI將index數據import到cluster state中(官方推薦,es7.9版本之后). 或者 配置gateway.auto_import_dangling_indices: true引入于es7.6版本pr49174(es7.6.0-7.9.0可用該配置,在7.6版本之前不需要配置默認加載dangling索引)并啟動數據節點

POST /_dangling/{index-uuid}?accept_data_loss=true

6 導入完成之后,索引recovery之后即可進行讀寫

注意

Q1: 為什么7.6.0之后需要配置,才能處理懸空索引(dangling index)才能讓數據加入新集群,7.6.0之后沒有懸空索引嗎?A1: 其實也是有的,只不過在es2版本將配置移除(對應pr10016),默認自動加載dangling index(es2.0-es7.6); 具體實現于org.elasticsearch.gateway.DanglingIndicesState#processDanglingIndices es7.6再次引入dangling配置,es7.9引入dangling index rest api

Q2: 什么是 dangling 索引?A2: 當一個節點加入集群時,如果發現存儲在其本地數據目錄中的任何分片(shard)不存在于集群中,將認為這些分片屬于“懸空”索引。懸空索引產生的場景(1)在 Elasticsearch 節點離線時刪除了多個cluster.indices.tombstones.size 索引,節點再次加入集群集群 (2)master節點丟失,數據節點重新加入新的集群等

3.2 數據節點故障

數據節點災難故障之后,無法恢復加入集群;可將數據物理復制到新的節點,然后按照master節點丟失的方式,將數據節點加入集群即可。

3.3 分片不能夠自動分配

查看索引分片為什么無法分配,POST_cluster/allocation/explain

3.3.1 分片正常

如果分片數據正常,那么我們可以嘗試重試分配分片任務;POST _cluster/reroute?retry_failed

獲取索引的shard在那些節點上,使用_shard_stores api

GET indexName1/_shard_stores

使用cluster reroute重新分配

# 嘗試分配副本 
POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_replica": {
        "index": "{indexName1}",
        "shard": {shardId},
        "node": "{nodes-9}"
      }
    }
  ]
}

如果是主分片無法分配,可以嘗試如下命令進行分配

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_stale_primary": {
        "index": "{indexName1}",
        "shard": {shardId},
        "node": {nodes-9},
        "accept_data_loss": true
      }
    }
  ]
}

如果主分片確實是無法分配,只能選擇丟失該分片的數據,分配一個空的主分片

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_empty_primary": {
        "index": "{indexName1}",
        "shard": {shardId},
        "node": "{nodes-9}",
        "accept_data_loss": true
      }
    }
  ]
}

es5.0版本之前參考;https://www.elastic.co/guide/en/elasticsearch/reference/2.4/cluster-reroute.html

3.3.2 分片數據損壞

shard corrupted

錯誤參考Corrupted elastic index

shard-tool es6.5版本引入,該操作需要stop節點elasticsearch-shard 工具es6.5版本引入 pr33848elasticsearch-shard remove-corrupted-data 的 es7.0.0引入 pr32281

bin/elasticsearch-shard remove-corrupted-data --index {indexName} --shard-id {shardId}
## 示列:修復索引twitter的0號分片
bin/elasticsearch-shard remove-corrupted-data --index twitter --shard-id 0

## 如果--index和--shard-id換成索引分片目錄參數--dir,則直接修復data和translog
bin/elasticsearch-shard remove-corrupted-data --dir /var/lib/elasticsearchdata/nodes/0/indices/P45vf_YQRhqjfwLMUvSqDw/0

修復完成之后,啟動節點,如果分片不能夠自動分配,使用reroute命令進行shard分片

POST /_cluster/reroute{
  "commands":[
    {
      "allocate_stale_primary":{
        "index":"index42",
        "shard":0,
        "node":"node-1",
        "accept_data_loss":false
      }
    }
  ]}

5版本之前可以通過索引級別配置,進行修復index.shard.check_on_startup: fix ,該配置在es6.5版本移除 pr32279

translog 損壞

修復translog操作,需要stop節點。

修復工具 elasticsearch-translog es5.0.0 引入pr19342elasticsearch-shard remove-corrupted-data translog的 es7.4.1開始引入,pr47866elasticsearch-shard 可以直接清除translog,也可以像上文中指定--dir那樣進行修復translog

bin/elasticsearch-shard remove-corrupted-data --index  --shard-id   --truncate-clean-translog
## 示列:修復索引twitter的0號分片
bin/elasticsearch-shard remove-corrupted-data --index twitter --shard-id 0 --truncate-clean-translog

清除完成之后使用cluster reroute 進行恢復

5版本之前可以通過索引級別配置,進行修復index.shard.check_on_startup: fix ,該配置在es6.5版本移除 pr32279

segments_N文件丟失

該種場景的文件損壞是最難修復的;官方還未提供工具,我們正在自己調研中

4 參考

[1] elasticsearch集群啟動流程

[2]https://www.elastic.co/guide/en/elasticsearch/reference/7.9/dangling-indices-list.html

[3]https://www.elastic.co/guide/en/elasticsearch/reference/7.10/node-tool.html

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2018-04-25 06:46:52

2021-10-15 22:19:15

電腦藍屏重啟

2025-06-26 01:25:00

2021-05-12 10:59:39

Kubernetes容器集群

2024-03-27 08:21:06

2023-06-27 17:37:08

Kubernete容器集群

2016-07-08 14:26:55

云計算

2021-07-27 11:31:29

運維架構技術

2021-04-21 14:19:52

javaignalHandle接口

2021-03-31 11:35:43

CountDownLaJava進階開發

2011-12-22 20:56:44

Android

2019-12-26 15:33:57

RedisHash架構

2021-08-10 07:27:42

Elasticsear集群開源

2022-02-17 08:53:38

ElasticSea集群部署

2022-03-24 13:36:18

Java悲觀鎖樂觀鎖

2010-03-17 17:33:47

云計算

2009-11-17 11:14:25

Oracle擴展

2021-12-27 18:00:30

對象數組Java

2025-01-10 11:07:28

2020-12-10 08:44:35

WebSocket輪詢Comet
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 操网站 | 天天久久 | 久久男人 | 香蕉久久网 | 日韩精品视频中文字幕 | 免费一级黄色录像 | 国产精品久久久久久吹潮 | 超碰成人免费观看 | 久久免费精品 | 久久久一| 国产激情亚洲 | 国产精品网址 | 中文字幕在线观看 | 日韩精品在线免费观看视频 | 国产精品毛片一区二区三区 | 国产精品精品久久久 | 久草在线在线精品观看 | 国产精品日产欧美久久久久 | 男人阁久久 | 青青草国产在线观看 | 欧美精三区欧美精三区 | 日韩成人在线视频 | 日韩欧美中文字幕在线观看 | 久久久久久亚洲精品 | 五月婷婷在线播放 | 二区高清 | 日韩理论电影在线观看 | 日韩二区三区 | 欧美电影一区 | 岛国av一区二区三区 | 国产aⅴ爽av久久久久久久 | 日韩a v在线免费观看 | 色欧美综合 | 羞羞的视频免费在线观看 | 国产伦精品一区二区 | 精品一区二区三区电影 | 在线成人一区 | 91影视 | 国产一区二区三区色淫影院 | 国产精品久久99 | 精品蜜桃一区二区三区 |