ElasticSearch填坑记1:_uid字段排序(fielddata特性),导致内存占用,不断GC,最后OOM

本文记录了一次由于ElasticSearch的_uid字段排序引发的系统故障,介绍了_fielddata特性如何导致内存占用过高,频繁GC直至OOM。问题源于尝试按创建时间对搜索结果排序,而_uid作为fielddata类型,会加载所有文档到内存,解决方案包括调整fielddata缓存大小、启用断路器以及避免使用此字段进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在某一天,我们的系统突然异常,大面积出现白屏,搜索页面点击后,响应非常慢,大量出现响应超过4秒的情况,异常高峰期平均查询时间达到10多秒,后台不断有ES服务宕机重启,GC告警频繁,经过一阵排查折腾,发现居然是简单的_uid字段排序导致的,下面就详细的讲一下。

    我们的ES搜索收到一个小小的需求,原来我们的搜索,新的结果会被放到后面去,产品经理希望能够对搜索结果进行排序,按照创建时间倒序排序。

    这里自然的相对用ES系统字段_uid进行倒序排序,因为这个字段是按照创建时间生成的,结果问题来了,这么一个简单的排序功能,居然产品了一次严重故障。

    首先,_uid是fielddata 类型,这是ES特有的特性,它能够将数据预加载在内存中,从而提高搜索速度。

    但是呢,我们的业务数据量极大,达到几十亿数据量级别,当_uid被加载到内容中的时候,就占用了es集群大量的内容,这部分内存并不会主动回收,导致服务器不断的GC停顿。数据被逐出导致查询很慢。

    Fielddata之所以占用很多内存的主要原因:

   假设你的查询要求只返回命中的 100 个结果,ES的fielddata 并不管你这个查询是怎么样,所以它并不会只加载 100 个文档。而是fielddata 会加载索引中 所有的 文档。官方文档是这样解释的:如果查询会访问文档 X、Y 和 Z,那很有可能会在下一个查询中访问其他文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值