如何避免ElasticSearch创建每日索引时出现性能下降?
预创建索引并预热
别等到午夜流量高峰才创建次日索引,提前在低峰期(比如凌晨1点前、或白天空闲时段)批量建好所有客户的次日索引。创建后执行简单的预热操作,比如跑一次GET /customer_xxx_*/_search?q=*或者写入一条测试数据,让Elasticsearch完成分片初始化、加载缓存,避免实际写入时突然抢占资源。
用命令提前创建的示例:curl -X PUT http://your-es-node:9200/customer_abc_20240618,记得用索引模板确保所有客户索引的配置(分片数、映射、设置)一致。错开索引创建时间
不要所有客户的索引都卡在午夜0点创建,把客户分成几组,分散在23:45、00:00、00:15这几个时间点分批创建,把瞬间的资源压力拆解开。可以用Cron或者调度工具按分组设置不同的创建任务,避免集群同时处理上百个分片初始化请求。优化索引创建的资源参数
调整Elasticsearch的分片并发参数,降低初始化时的资源争抢:- 把
cluster.routing.allocation.node_initial_primaries_recoveries(主分片初始化并发数)设为2-3,默认值可能过高; - 把
cluster.routing.allocation.node_concurrent_recoveries(分片恢复并发数)也适当调低。
另外,给小客户的每日索引只分配1个主分片就行,分片数越多,初始化时的元数据处理开销越大,完全没必要浪费资源。
- 把
改用ILM自动管理索引生命周期
放弃手动创建/删除索引的方式,给每个客户配置专属的索引生命周期管理(ILM)策略:- 定义热阶段的滚动规则,比如索引存活1天或者达到50GB时自动rollover创建新索引;
- 设置删除阶段,比如数据保留30天后自动删除;
- 把rollover的触发时间调到午夜后的低峰期(比如凌晨2点),避开业务流量高峰。
示例ILM策略配置:
{ "policy": { "phases": { "hot": { "actions": { "rollover": { "max_age": "1d", "max_size": "50gb" } } }, "delete": { "min_age": "30d", "actions": { "delete": {} } } } } }配合索引模板把ILM策略绑定到客户索引前缀,让Elasticsearch自动处理索引的创建、滚动和删除,彻底避免手动批量创建的压力。
调整集群资源调度
午夜时段暂时降低非核心查询任务的优先级,或者把部分查询流量转移到副本节点,为主节点和数据节点的索引操作预留CPU、IO资源。如果集群跨可用区,开启分片分配感知,避免单节点集中处理过多分片初始化请求。
内容的提问来源于stack exchange,提问作者Elisha Sterngold

