客戶端
Transport Client已經快要廢棄了,官方推薦使用High Level REST Client。
常用命令
啟停
systemctl start elasticsearch
systemctl stop elasticsearch
節點狀態
curl http://myservice1:9200/_cat/nodes?vip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
xx.xx.xx.205 15 96 2 0.10 0.08 0.08 mdi - xx.xx.xx.205
xx.xx.xx.250 18 98 14 0.66 0.35 0.31 di - xx.xx.xx.250
xx.xx.xx.7 25 99 2 0.21 0.11 0.06 mdi - xx.xx.xx.7
xx.xx.xx.30 30 93 13 1.15 0.60 0.42 di - xx.xx.xx.30
xx.xx.xx.249 64 94 3 0.09 0.06 0.10 di - xx.xx.xx.249
xx.xx.xx.12 75 99 2 0.20 0.08 0.06 mdi * xx.xx.xx.12
xx.xx.xx.2 70 96 1 0.14 0.09 0.07 di - xx.xx.xx.2
xx.xx.xx.36 27 99 13 0.83 0.45 0.36 di - xx.xx.xx.36
注意node.role和master兩列,前者表示節點角色,有:mdi(master+data+ingest)和di(data+ingest)。
master列為星號的表示主節點。比如這里xx.xx.xx.12就是主節點。
集群健康狀態
curl http://myservice1:9200/_cat/health?vepoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1651459176 02:39:36 elasticsearch green 8 8 3796 1898 0 0 0 0 - 100.0%
各列含義:
cluster ,集群名稱
status,集群狀態 green代表健康;yellow代表分配了所有主分片,但至少缺少一個副本,此時集群數據仍舊完整;red代表部分主分片不可用,可能已經丟失數據。
node.total,代表在線的節點總數量
node.data,代表在線的數據節點的數量
shards, active_shards 存活的分片數量
pri,active_primary_shards 存活的主分片數量 正常情況下(replica=1), shards的數量是pri的兩倍。
relo, relocating_shards 遷移中的分片數量,正常情況為 0
init, initializing_shards 初始化中的分片數量 正常情況為 0
unassign, unassigned_shards 未分配的分片 正常情況為 0
pending_tasks,準備中的任務,任務指遷移分片等 正常情況為 0
max_task_wait_time,任務最長等待時間
active_shards_percent,正常分片百分比 正常情況為 100%
列出所有索引
curl http://myservice1:9200/_cat/indices?v
修改索引副本數
PUT test/_settings
{"index": {"number_of_replicas" : 1}
}
文檔增刪改查
指定ID創建一個索引,并往其中加入文檔,文檔格式為json
curl -XPUT -H "Content-Type: application/json" 'myservice1:9200/customer/external/1?pretty' -d '
{
"name": "yibei"
}'不指定ID的加入一個文檔
curl -XPOST -H "Content-Type: application/json" 'myservice1:9200/customer/external?pretty' -d '
{
"name": "xx3"
}'修改文檔內容
curl -XPOST -H "Content-Type: application/json" 'myservice1:9200/customer/external/1/_update?pretty' -d'
{
"doc":{"name": "lixiao","age":45}
}'從索引里根據ID取得某個文檔
curl -XGET 'myservice1:9200/customer/external/1?pretty'搜索所有文檔
curl -XPOST -H "Content-Type: application/json" 'myservice1:9200/customer/_search?pretty' -d '
{
"query": { "match_all": {} },
"from": 0,
"size":20
}'刪除索引
curl -XDELETE 'myservice1:9200/customer?pretty'查看恢復進程
curl -XGET 'myservice1:9200/_recovery'
文檔update or insert
參考這里:
使用doc_as_upsert:
curl -XPOST -H "Content-Type: application/json" 'myservice1:9200/customer/external/1/_update' -d '{"doc" : {"name" : "yibei1"},"doc_as_upsert" : true
}'
進階
shard/replica和ES節點
參看該文說明
節點down掉對集群影響的實驗
總共8個節點,分別看一下同時down掉1/2/3個節點對集群狀態和讀寫的影響。
8個節點的總分片和主分片數是:3796 1898
同時1個節點down掉,查看集群健康狀態:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1651460709 03:05:09 elasticsearch yellow 7 7 3322 1898 0 0 474 0 - 87.5%
集群狀態變為黃色,主分片未受影響,備份分片減少,未分配分片數為474,active_shards_percent從100%降為87.5%。
讀操作未受影響,寫操作略有點慢,但還是能寫入。
另外,我們注意到一點,這種情況相當于節點退出,ES會自動做shard relocation,因此shards和active_shards_percent會緩慢恢復。同時由于主分片未受損,大概20min左右,集群就會重新恢復到green狀態。
同時2個節點down掉,查看集群健康狀態:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1651468939 05:22:19 elasticsearch red 6 6 3405 1861 2 0 381 0 - 89.9%
集群狀態變為紅色,主分片有損失,active_shards_percent降到89.9%,這個值看來跟down掉的節點數并無線性關系。
讀操作未受影響,寫操作時如果正在做shard relocation,略有點慢,但還是能寫入的。
shards和active_shards_percent會緩慢恢復,但恢復不到100%的狀態,因為主分片已受損了,補償不回來的。過了一段時間,集群狀態最后也始終停留在red,此時active_shards_percent停留在98.3%,unassign有64個分片無法恢復,恰好就是損失的主分片數的2倍!
最后,我們將2個節點恢復,集群經過30s的shard relocation,即可恢復green狀態,active_shards_percent也為100%.
同時3個節點down掉,查看集群健康狀態:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1651462580 03:36:20 elasticsearch red 5 5 2641 1826 0 0 1155 0 - 69.6%
集群狀態變為紅色,主分片已受損,備份分片更是減少的厲害,active_shards_percent降到了69.6%。
讀操作未受影響,寫操作有時慢,有時還會超時,報錯:
{"error" : {"root_cause" : [{"type" : "unavailable_shards_exception","reason" : "[customer][4] primary shard is not active Timeout: [1m], request: [BulkShardRequest [[customer][4]] containing [index {[customer][external][G3sTg4ABDFINJI3kc3ug], source[\n{\n\"name\": \"liping2\"\n}]}]]"}],"type" : "unavailable_shards_exception","reason" : "[customer][4] primary shard is not active Timeout: [1m], request: [BulkShardRequest [[customer][4]] containing [index {[customer][external][G3sTg4ABDFINJI3kc3ug], source[\n{\n\"name\": \"liping2\"\n}]}]]"},"status" : 503
}
可能剛好寫到受損的主分片上了。再試一次,又成功了,應該是選了一個健康的主分片來寫。
三個節點down掉后,ES依然會自動做shard relocation,因此shards和active_shards_percent會緩慢恢復,但恢復不到100%的狀態,因為主分片已受損了,補償不回來的。過了40min,集群狀態最后也始終停留在red,此時active_shards_percent停留在96.2%,unassign有144個分片無法恢復,恰好就是損失的主分片數的2倍!
最后,我們將3個節點恢復,集群經過1~2min的shard relocation,即可恢復green狀態,active_shards_percent也為100%。
結論
- 節點退出后的shard relocation動作會比較慢,在relocation階段如果有業務查詢或修改也會比較慢;
- 節點加入后的shard relocation動作很快,基本上1~2min就可以恢復正常;
- replica=1時,僅僅down掉2個節點,就會導致集群的主分片受損,永遠陷入red狀態,并可能導致寫入超時(寫到受損主分片時);
- 分片可以認為是一塊為index預分配的空間,只在index新建或刪除時會變化,而在insert doc時并不會變;分片數在索引創建時確定,后續不能修改,除非用reindex重建索引。
為何分片數在索引創建后就不能修改
Reason that you can't change the primary shards are due to the fact, it will change the way data is split between primary shards and changing them will cause consistent hashing to break, which is very popular technique to horizontally scale and splitting the data technique.Replicas shards are just copy so you can increase and decrease as it doesn't make any impact on consistent hashing.If you want to change the primary shards, you have to create a new index and use alias API and Reindex API for efficiently doing it
replica與數據節點數的關系
ES有個選項,叫auto_expand_replicas,會自動根據data node數擴展replica,默認是關閉的。根據這個選項我們可以猜測,replica與data node數之間應該是有關系的,不能說數據節點在擴充,而replica始終不變,理論上replica也要隨之遞增。
那么,兩者間有沒有一個推薦的關系公式呢?
google了一下,有如下結論:
Another factor to consider with replicas is the number of nodes available. Replicas are always placed on different nodes from the primary shard, since two copies of the same data on the same node would add no protection if the node were to fail. As a result, for a system to support n replicas, there need to be at least n + 1 nodes in the cluster. For instance, if there are two nodes in a system and an index is configured with six replicas, only one replica will be allocated. On the other hand, a system with seven nodes is perfectly capable of handling one primary shard and six replicas.
考慮replica=1的情況,這時如果只down一個節點A,A上的主shard必定在其他完好的節點上有備shard(主備shard不能在同一個節點),所以即使A down掉了,也不會導致主shard受損,因為其他節點上的備shard會接替成為新的主shard。
這是我們上面做的第一個實驗的情況。
如果down了兩個節點,情況就不同了,很可能這倆節點上的主shard在其他完好節點上就沒有備shard,于是就有可能主shard受損。這是我們上面第二個實驗的情況,我們會看到,最后有1.7%的主分片受損。但,如果此時我們將replic調高到2,則這倆故障節點上的主shard在其他完好節點上必定會有備shard,這樣即使2個節點都down掉,也不會有主分片受損。
以此類推,down了三個節點時,如果replica=3,則必定在其他完好節點上有備shard,數據不會受損。
因此,若想數據完全不受損,必須滿足:
replica數=可能down掉的最大數據節點數
但replica不是沒有代價的,它就像數據庫的索引,會額外占用內存、磁盤空間,在提高查詢效率的同時,也會降低增刪doc的效率。
所以,這里頭是有一個折中的。