目录
- 背景
- 第一部分 静态分区
- 第二部分 动态分区
- 第三部分 两者的比较
- 第四部分 动态分区使用的问题
- 参考文献及资料
背景
故障现象:
集群出现大量的put-mapping的任务堆积 (1200个左右),该任务属于HIGH级别,比创建索引等任务级别高。所以出现集群4月27号的索引未创建成功。
pending task 反应了master节点尚未执行的集群级别的更改任务(例如:创建索引,更新映射,分配分片)的列表。pending task的任务是分级别的(优先级排序:IMMEDIATE>URGENT>HIGH>NORMAL>LOW>LANGUID),只有当上一级别的任务执行完毕后才会执行下一级别的任务,这也说明了:当出现HIGH级别以上的pending task任务时,备份和创建索引等一些低级别任务虽然任务对资源占用不多,也将不会执行
put-mapping的原因分析:
pendingtask只能由主节点来进行处理,这些任务包括创建索引并将shards分配给节点。任务分优先次序。如果任务的产生比处理速度更快,将会产生堆积。如果存在任务堆积,集群存在较大隐患,需要排查集群的任务,确认原因。
这一条优化建议在上面也提到了,因为创建索引及新加字段都是更新元数据操作,需要 master 节点将新版本的元数据同步到所有节点。
因此在集群规模比较大,写入qps较高的场景下,特别容易出现master更新元数据超时的问题,这可导致 master 节点中有大量的 pending_tasks 任务堆积,从而造成集群不可用,甚至出现集群无主的情况。
动态mapping非常容易引起性能问题,特别是集群比较大的情况下,容易因为大量的mapping更新任务会导致master过载。 并且动态mapping也容易因为脏数据的写入产生错误的字段类型。 我们的做法是完全禁用动态mapping,在索引的mapping设置中增加”dynamic”: “false” 这个选项即可。 集群的索引字段类型都需要预先设计好,数据必须严格按照设计的类型写入,否则会被reject。
优化建议:
1、静态mapping;
2、index创建提前,并且设定好mapping;
其中 priority 字段则表示该 task 的优先级,翻看 ES 的源码可以看到一共有六种优先级:
1 | IMMEDIATE((byte) 0), |
查看分片未分配的原因
其中 index和shard 列出了具体哪个索引的哪个分片未分配成功。reason 字段则列出了哪种原因导致的分片未分配。这里也将所有可能的原因列出来:
1 | INDEX_CREATED:由于创建索引的API导致未分配。 |
detail 字段则列出了更为详细的未分配的原因。下面我会总结下在日常运维工作中常见的几种原因。
如果未分配的分片比较多的话,我们也可以通过下面的API来列出所有未分配的索引和主分片:
新版本:
https://github.com/elastic/elasticsearch/pull/48867
参考文献及资料
1、记Elasticsearch 因不合理创建type导致集群故障 https://blog.csdn.net/sunjiangangok/article/details/80423852