我们团队基于Elasticsearch开发了一款将数据从数据库实时同步至Elasticsearch的工具——搜索平台,其实现方式主要是通过flink将数据库中已有的存量数据导入Elasticsearch,并订阅数据表的binlog,将实时改动也同步至Elasticsearch。
问题发现
AIoT团队在搜索平台上维护了一个较大的索引,其写入平均有2k到3k的tps,查询也有数百QPS。由于该索引较重要且占用资源较多,因此使用Elasticsearch的template功能将之单独部署在专用的机器上。
从5月底开始,写入此索引的flink实时任务就会偶现失败重启的情况,经排查,发现是写入Elasticsearch的请求超时导致的,结合当时机器的cpu占用等指标判定是写入tps过高导致Elasticsearch无法承受,因此,将该索引所占的机器从2台升级到3台,并使用业务数据进行了一轮写入压测,发现能支撑业务方的写入速率,扩完后较长一段时间内,该索引也一直没有出现问题,因此认为问题已经被解决了。
问题排查
然而,在6月22日凌晨,上述问题再次出现,通过查看指标,发现当时的写入速率并无显著提升。
1.索引写入速率
既然不是由写入速率提升造成的,那就接着排查其他可能占用CPU资源的行为。
2.索引查询速率
3.jvm gc次数
4.节点merge速率
5.节点写入队列长度
由上述指标可以看出,写入耗时过久是因为索引的其中一个节点写入队列过长,无法及时处理写入导致的。然而在写入队列变长的过程中,节点的gc,merge等操作并无明显变化,索引的查询速率也没有明显提升,因此猜测是某些具有特殊特征的文档导致es写入过慢导致的。
在上述猜测下,我们的思路就变成了找出导致索引过慢的罪魁祸首文档。因此就从埋点数据中收集了很多慢索引文档,尝试手动索引,但均能很快索引完成。
但是线上问题依旧存在,为了使业务不出问题,我们从以下手段尝试修复线上问题:
1.加速Elasticsearch的索引效率
- 调大索引的refresh_interval参数
- 修改index.translog.durability为async等
- 关闭部分字段的索引配置