(九)elasticsearch常见问题总结
文章目录
- (九)elasticsearch常见问题总结
- 1:问题汇总
- 1.1:分片未分配:unassigned_shards
- 1:unassigned原因
- 2:ALLOCATION_FAILED 分片分配失败解决
- 3:CLUSTER_RECOVERED集群重启恢复而未分配
- 4:DANGLING_INDEX_IMPORTED悬空索引分配失败
- 5:INDEX_CREATED创建索引后分配失败
- 6:NODE_LEFT节点掉线延迟分配
- 7:禁止了分片分配导致副本分片未分配
- 1.2:es写入报:Elasticsearch exception [type=es_rejected_execution_exception, reason=rejected
- 1.3:节点启动报:java.lang.IllegalStateException: failed to obtain node locks
- 1.4:高内存/高cpu使用率解决
- 1.5:大分片处理
- 2:实战记录
- 2.1:es写入异常,写入缓慢
- 2.2:es的节点个数规划
1:问题汇总
1.1:分片未分配:unassigned_shards
现象:GET _cluster/health看到unassigned_shards
分析出未分配的分片信息及未分配的原因:用kibana或者curl均可
方式1:kibana
获取故障分片:get _cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason
具体原因查看:GET /_cluster/allocation/explain
{
"index": "index",
"shard": 0, //shardnum。shardnum:可由GET _cat/shards?v 查看获取
"primary": false
}
方式2:用curl分析原因
curl -XGET "http://ip:port/_cat/shards?v&h=index,shard,prirep,state,node,unassigned.reason" > shards.txt
获取索引名:cat shards.txt | grep UNASSIGNED
获取具体的分片失败原因:curl -XGET "http://IP:PORT/_cluster/allocation/explain?pretty" -H 'Content-Type:application/json' -d '{"index":"indexName","shard":shardnum,"primary":false}'
shardnum:可由GET _cat/shards?v 查看获取,
1:unassigned原因
结果的explanation中有unassigned具体未分配原因,分片unassigned的类型包括:
ALLOCATION_FAILED: 由于分片分配失败而未分配。
CLUSTER_RECOVERED:由于完整的集群恢复而未分配。
DANGLING_INDEX_IMPORTED: 由于悬空索引而未分配。
EXISTING_INDEX_RESTORED: 由于恢复到封闭索引而未分配。
FORCED_EMPTY_PRIMARY:上次修改分片的分配是通过使用集群重新路由API 强制一个空的主分片。
INDEX_CLOSED: 未分配,因为索引已关闭。
INDEX_CREATED: 由于 API 创建索引而取消分配。
INDEX_REOPENED: 由于打开封闭索引而未分配。
MANUAL_ALLOCATION: 分片的分配最后由集群重新路由API修改。
NEW_INDEX_RESTORED: 由于恢复到新索引而未分配。
NODE_LEFT:由于托管它的节点离开集群而未分配。
NODE_RESTARTING:与 类似NODE_LEFT,不同之处在于节点是使用 Node shutdown API注册为重新启动的。
PRIMARY_FAILED: 分片初始化为副本,但主分片在初始化完成前失败。
REALLOCATED_REPLICA:识别出更好的副本位置并导致现有副本分配被取消。
REINITIALIZED:当分片从启动回到初始化时。
REPLICA_ADDED:由于显式添加副本而未分配。
REROUTE_CANCELLED: 由于显式取消重新路由命令而未分配。
解决根本目的是找到未分配的原因解决并分配
2:ALLOCATION_FAILED 分片分配失败解决
执行 POST _cluster/reroute?retry_failed=true
3:CLUSTER_RECOVERED集群重启恢复而未分配
发生情形:集群停止前关闭了分片分配,开启后没有开启分片分配导致的没有分配
解决:
PUT _cluster / settings {
"persistent" : { "cluster.routing.allocation.enable" : null } }
4:DANGLING_INDEX_IMPORTED悬空索引分配失败
发送情形:在集群有节点离线的时候执行了删除索引的命令,导致分配在离线节点上的分配未能分配导致的。
解决:
- 1:列出悬空索引:GET /_dangling 从结果中可以发现索引的名称和UUID
- 2:重新执行delete index重新删除索引或者导入索引。
- 3:导入或删除索引:
POST/DELETE /_dangling/<index-uuid>?accept_data_loss=true
5:INDEX_CREATED创建索引后分配失败
发送情形:一般是对索引创建或者分配分配做了限制导致路由后分配失败了。
解决:根据GET /_cluster/allocation/explain中的原因查看是哪个参数导致的进行参数调整。
再执行 POST _cluster/reroute?retry_failed=true
6:NODE_LEFT节点掉线延迟分配
发生情形:由于节点掉线导致的分配一般为了保持节点掉线的集群稳定性,所以设置的离线后延迟分配。
PUT _all / _settings { “设置” :{ “index.unassigned.node_left.delayed_timeout” :“5m” } }
解决:取消延迟分配的设置
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "0"
}
}
7:禁止了分片分配导致副本分片未分配
routing.allocation.enable" : “all”
开启
curl -XPUT 'localhost:9200/_cluster/settings'-d
'{ "transient":
{"cluster.routing.allocation.enable" : "all" }
}'
其他未分配常规原因及解决方案:
1、单节点索引分片总数超限
2、已达到每个节点的分片总数
重新配置其对应的配置,或进行集群均衡,触发分配等
curl -XPUT "http://194.168.223.20:24100/_cluster/settings?pretty&master_timeout=180s"
-H 'Content-Type:application/json' -d '{"transient":{"cluster.routing.allocation.allow_rebalance":"indices_primaries_active"}}'
再执行手动重新分片:POST _cluster/reroute?retry_failed=true
执行完分片会移动分配:GET _cluster/health 查看unassigned_shards是否减少
1.2:es写入报:Elasticsearch exception [type=es_rejected_execution_exception, reason=rejected
ElasticsearchException[Elasticsearch exception [type=es_rejected_execution_exception, reason=rejected execution of processing of [114475]
[indices:data/write/bulk[s][p]]: request: BulkShardRequest [[index][11]] containing [52] requests, target allocation id:sWzFdprSRRCQzyeBZGqttQ,
primary term: 1 on EsThreadPoolExecutor[name =ip/write, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@d44250d
[Running, pool size = 40,active threads = 40, queued tasks = 1075, completed tasks = 44022]]]]
解决分析集群健康状态
原因1:查看集群状态以及集群告警以及历史告警
get cluster/health 详细解释看运维篇
查看是否有未分配的分片,正在迁移的分区进行解决,先停止入库待恢复后再开启,实际中迁移数小于30对写入影响不大
未分配的分片和迁移分片会导致集群分配缓慢导致写入缓慢
原因2::查看写入量是否剧增,分片过大(大于50G)导致
调整分片数量
原因3:查看写入索引的分片分布是否均衡
GET _cat/shards/index 不均衡进行分片均衡,进行分片分配优化,设置索引的setting。
最主要参数:total_shards_per_node(单个节点上单个索引分配分片最多个数)
put index/settings{
"routing" : {
"allocation" : {
"total_shards_per_node" : "4"
}
},
}
原因4: 线程情况:GET _cat/thread_pool?v&s=rejected:desc
查看线程情况和集群中的状态ip是否高度一致,如果是则看是否分片或者id写入产生了数据倾斜,考虑进行均衡
reroute迁移配置后开启"routing": {"allocation.enable": "all"}
原因5:查看是否节点cpu/jvm内部压力过高
1.3:节点启动报:java.lang.IllegalStateException: failed to obtain node locks
Caused by: java.lang.IllegalStateException: failed to obtain node locks, tried [] with lock id
[0]; maybe these locations are not writable or multiple nodes were started without increasing
[node.max_local_storage_nodes] (was [1])?
集群节点还没有关闭就执行了启动过程,导致的节点注册异常
jps找到进程,kill -9 pid杀死重启
1.4:高内存/高cpu使用率解决
1:现象
节点的内存和cpu使用率过高,一般85%作为分界线;客户端的读写等请求会被拒绝
1cpu:GET _cat/nodes?v=true&s=cpu:desc
2内存:GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
使用率过高再查看热点线程是那些GET _nodes/my-node,my-other-node/hot_threads
2:解决方案
- 减少内存压力
1:对于text字段,fielddata 可以使用大量的 JVM 内存。为避免这种情况,Elasticsearchtext默认禁用字段上的 fielddata
2:清除fielddata缓存 POST _cache/clear?fielddata=true
3:减少分片数量,减少副本的梳理比如3->2
4:避免大数据量的查询,减少返回的数据量。size使用 索引设置
降低限制index.max_result_window。
使用search.max_buckets集群设置 减少允许的聚合桶的最大数量 。
使用 search.allow_expensive_queries集群设置禁用昂贵的查询。 - 减少cpu压力
对bulk批请求进行测试,避免一批请求过多
GET _nodes/my-node,my-other-node/hot_threads获取热点线程,取消长时间运行的请求
进行扩容,查看是否有超大分片索引进行解决
1.5:大分片处理
1、大分片的危害
- 过度占用服务器资源,降低集群服务能力
- 加剧JVM的GC,导致查询,写入变慢
- 在进行索引恢复,数据均衡时,更耗时
- 集群故障恢复变慢
- 集群稳定性变差
2、大分片处理方案
- 1:删除非必要索引DELETE index_name
- 2:删除大分片索引中的非必要数据,通过POST index/delete_by_query删除部分数据,可能存在问题数据量大删除慢
- 3:使用_split索引进行拆分或者reindex进行索引重建都可以。
- 4:解决方案1-reindex重建索引。重建索引可以对mapping进行重新设置,reindex必须提前配置mapping、分片计数、副本等。
1、post设置mapping
2、reindex方案参数确认
POST
{
"source": {
"index": "old_index",
"size":1000 //可选,每次批量提交1000个,可以提高效率,建议每次提交5-15M的数据
},
"dest": {
"index": "new_index"
}
- 5:解决方案2-split拆分分片。和reindex区别是更适合mapping没有改变时。split时分片数必须是原索引的整倍数
1、新建所以并设置为只读索引
PUT /my_source_index/_settings
{
"settings": {
"index.number_of_shards" : 1,
"index.blocks.write": true
}
}
2、split并设置别名。POST my_source_index/_split/my_target_index { "settings": { "index.number_of_shards": 5 }, "aliases": { //aliases 创建别名 "my_search_indices": {} } }
2:实战记录
2.1:es写入异常,写入缓慢
性能记录:单台服务器可以达到8000/s的写入量
但是在集群异常时会急剧下降,报es_rejected_execution_exception或者超时
问题1:某台服务器的es进程重启会导致分片relocatiing迁移,会写入异常
问题2:整个集群的分片数或者单个索引的分片数
控制集群的分片数控制5W左右,不要太多,我们12w左右时出现过写入异常,降低分片到6W左右写入恢复
控制索引的分片数:600以下
2.2:es的节点个数规划
<=3个时,建议master和data节点一起部署
建议>=3个节点