客户端
Transport Client已经快要废弃了,官方推荐使用High Level REST Client。
常用命令
启停
systemctl start elasticsearch
systemctl stop elasticsearch
节点状态
curl http://myservice1:9200/_cat/nodes?v
ip 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?v
epoch 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的效率。
所以,这里头是有一个折中的。