小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
因业务的调整,elasticsearch需要扩容或者缩容的
因磁盘故障或停电,需要停机维护等需要关机重启的
在这方面因elasticsearch无中心化的特点,在扩缩容,停机维护方面可以让业务无感知,正常读写es集群
要实现以上功能,节点数必需在3个或5个以上,要么3个节点都是master,其他都是data节点。要么有3个节点既是master也是data
参数
es的数据冗余需要依靠一个参数: "number_of_replicas": "1",
假设你的集群是3个节点,上述参数设置为1 ,那就是有一个主分片和一个副本分片,总共有两份
如果一台节点挂掉,不影响集群读写。如果挂掉两个节点,那么有部分索引将无法写入,部分索引读取时只返回部分数据
状态
es分为三个状态:
- Green 所有的主分片和副本分片都已分配。集群100% 可用的。
- Yellow 所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。高可用性在某种程度上被弱化,集群此时还可以写入
- Red 至少一个主分片(以及它的全部副本)都在缺失,搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常
停机维护
停机维护的操作和集群升级相似,就是节点数据是不动的,节点关机再启动之后,马上可以投入服务,继续使用
但是因es无中心化特点,如果节点一旦关机,为保证服务可用性,数据会自动飘移到正常的节点,如果你的数据很大,这个动作很耗时间,且集群IO会很高,为此,需要在维护期间禁用分配
官网文档: www.elastic.co/guide/en/el…
分片文档: www.elastic.co/guide/en/el…
以下动作在kibana dev tools里面执行,后面的同样
1. 停止分配
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}
2. 执行同步
此步是可选的, 可不执行,等待集群自动完成
POST _flush/synced
3. 停机维护
停止es服务,然后关掉机器,接下来就可以更换磁盘,维护操作等后续操作
停止节点后,你的集群状态应该为Yellow,如果是Red说明有问题,查看所有索引副本是否设置为1
节点维护好之后,启动机器,启动服务,检查集群状态
systemctl stop elasticsearch.service
systemctl start elasticsearch.service
GET _cat/health
GET _cat/nodes
4. 启用分配
启用分配后,查看恢复进度
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
}
}
GET _cat/recovery
扩缩容
扩容
新增一个节点,配置和原集群一样,启动服务,当节点加入集群后,会自动发现集群并由集群重新组织,均匀的分配数据到节点
官方文档: www.elastic.co/guide/en/el…
缩容
要进行缩容,请确保在缩容后你的节点数据大于副本数,且是奇数
且确保现有的索引 副本数大于或等于1,如果副本数为0,且分片又在缩容机上,会导致该索引数据丢失
可以利用集群级分片分配筛选来剔除节点,关闭节点之前移除它的碎片,等分片迁移完成后,就可以停止节点了
PUT _cluster/settings
{
"transient" : {
"cluster.routing.allocation.exclude._ip" : "10.0.0.1"
}
}
GET _cat/health
官方文档: www.elastic.co/guide/en/el…
故障排除
由于异常死机或其它原因导致节点挂掉,或者没有执行禁用分配,就长时间的停掉一个节点。就会出现故障
UNASSIGNED
大部分的故障是数据问题,要么没有分配,要么分配次数到了,要么磁盘快满,不分配了等等
- INDEX_CREATED:由于创建索引的API导致未分配
- CLUSTER_RECOVERED :由于完全集群恢复导致未分配
- INDEX_REOPENED :由于打开open或关闭close一个索引导致未分配
- DANGLING_INDEX_IMPORTED :由于导入dangling索引的结果导致未分配
- NEW_INDEX_RESTORED :由于恢复到新索引导致未分配
- EXISTING_INDEX_RESTORED :由于恢复到已关闭的索引导致未分配
- REPLICA_ADDED:由于显式添加副本分片导致未分配
- ALLOCATION_FAILED :由于分片分配失败导致未分配
- NODE_LEFT :由于承载该分片的节点离开集群导致未分配
- REINITIALIZED :由于当分片从开始移动到初始化时导致未分配(例如,使用影子shadow副本分片)
- REROUTE_CANCELLED :作为显式取消重新路由命令的结果取消分配
- REALLOCATED_REPLICA :确定更好的副本位置被标定使用,导致现有的副本分配被取消,出现未分配
排错命令
查看集群状态
GET _cluster/health
查看分片的状态
GET /_cluster/health?level=shards
查看没有分配的原因
GET _cluster/allocation/explain?pretty
下面的请求返回 unassigned.reason 列,该列指示未分配分片的原因。
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason
查看正在恢复的分片
curl http://127.0.0.1:9200/_cat/recovery?active_only=true
查看所有索引的副本数
curl http://127.0.0.1:9200/_cluster/health?level=indices | jq .indices > test2222.txt
cat test2222.txt | jq .[].number_of_replicas | grep 0
查看所有分片的详情
curl http://127.0.0.1:9200/_cat/shards?v > shared111.txt
查看各节点文件打开数限制
GET _nodes/stats/process?filter_path=**.max_file_descriptors
查看节点详情
GET _nodes/process
分配重试次数达上限
如果停机时间过长,可能会造成分配次数达上限,导致后面机器启动了也不分配
错误信息提取
点击head插件上面灰色的方块,查看错误信息,或者查看es日志
解决方案
官方文档: www.elastic.co/guide/en/el…
然后重试分配由于太多后续分配失败而阻塞的分片
POST _cluster/reroute?retry_failed=true
分片数已达到设置的值
reached the limit of incoming shard recoveries [2]
出现上面的报错,是因为停机时没有设置禁用分配,机器在重启过程中,已经有一部分分片副本被复制了,此时产生了3个副本。
此问题不需要手动干预,只需要等一会集群自动重新组织,会主动删除多余的数据(一般删除最早的数据,也就是停机的那台)
分配被禁止
replica allocations are forbidden due to cluster setting [cluster.routing.allocation.enable=primaries
如果出现以上错误,是因为分配被禁止了,一般是手动禁止了,有可能是前面操作忘记开启分配了,
执行开启分配
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
}
}
主副分片不能存在同一个节点
the shard cannot be allocated to the same node on which a copy of the shard already exists
因为主分片和副本是不能在同一个节点的,如果报错,可以等集群自动调节,如果长时间未恢复,可手动指定分片到指定节点
官方文档: www.elastic.co/guide/en/el…
未实操过,且执行reroute时会有丢失数据风险,请注意不要在生产执行
POST /_cluster/reroute
{
"commands":[{
"allocate_replica":{
"index":"索引名",
"shard":4,
"node":"节点ID"
}
}]
}