elasticsearch更新数据存在延迟

1. 背景
向elasticsearch中新增一条文档数据后,立即请求查询文档列表,发现刚刚新增的文档查不出来,需要等一会后再次请求查询才能查询出来,随后测试了删除文档列表和更新文档列表中的文档这两个接口,出现了同样的问题,即elasticsearch数据更新有延迟 .总而言之,es在更新之后并不是立即可见(可查询)的,会有1s的延迟

2. 原因分析
官方说法:
https://www.elastic.co/guide/cn/elasticsearch/guide/current/near-real-time.html#img-pre-refresh

写数据----->ES内存 buffer(缓存区)-------定期refresh成segment------>os系统文件缓冲区(在这里的数据对搜索可见)---->磁盘

在写操作中,一般会先在内存中缓冲一段数据,再将这些数据写入硬盘,每次写入硬盘的这批数据称为一个分段,如同任何写操作一样。一般情况下,通过操作系统write接口写到磁盘的数据先到达系统缓存(内存),write函数返回成功时,数据未必被刷到磁盘。通过手工调用flush,或者操作系统通过一定策略将系统缓存刷到磁盘。这种策略大幅提升了写入效率。从write函数返回成功开始,无论数据有没有被刷到磁盘,该数据已经对读取可见。ES正是利用这种特性实现了近实时搜索。每秒产生一个新分段,新段先写入文件系统缓存,但稍后再执行flush刷盘操作,写操作很快会执行完,一旦写成功,就可以像其他文件一样被打开和读取了。由于系统先缓冲一段数据才写,且新段不会立即刷入磁盘,这两个过程中如果出现某些意外情况(如主机断电),则会存在丢失数据的风险。通用的做法是记录事务日志,每次对ES进行操作时均记录事务日志,当ES启动的时候,重放translog中所有在最后一次提交后发生的变更操作。比如HBase等都有自己的事务日志。

在ES中,每秒清空一次写缓冲,将这些数据写入文件,这个过程称为refresh,每次refresh会创建一个新的Lucene 段。但是分段数量太多会带来较大的麻烦,每个段都会消耗文件句柄、内存。每个搜索请求都需要轮流检查每个段,查询完再对结果进行合并;所以段越多,搜索也就越慢。因此需要通过一定的策略将这些较小的段合并为大的段,常用的方案是选择大小相似的分段进行合并。在合并过程中,标记为删除的数据不会写入新分段,当合并过程结束,旧的分段数据被删除,标记删除的数据才从磁盘删除。

默认情况下索引的refresh_interval为1秒,这意味着数据写1秒后就可以被搜索到,每次索引的refresh会产生一个新的Lucene段,这会导致频繁的segment merge行为,如果不需要这么高的搜索实时性,应该降低索引refresh周期

indexing buffer在为doc建立索引时使用,当缓冲满时会刷入磁盘,生成一个新的segment,这是除refresh_interval刷新索引外,另一个生成新segment的机会。每个shard有自己的indexingbuffer。

3. 解决思路
问题是elasticsearch中更新数据后有延迟

① 解决方案1 :
新增一条文档数据,返回响应数据之前,让线程睡眠1秒钟,然后再返回响应数据
在这里插入图片描述
② 解决方法2:indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);

Elasticsearch 刚索引的文档并不是立即对搜索可见,它们会先在内存 buffer(缓存区)中,待 buffer 数据满后或主动刷新操作才会写入到文件缓存区中,便可以搜索。总而言之,es在更新之后并不是立即可见(可查询)的,会有1s的延迟,可以通过设置refresh_interval参数来修改刷新的间隔。

手动让es中的数据每次更新后都从indexing buffer中刷新到磁盘中,,从而让更新的数据立即可见,但是从前面的分析可见,会影响性能。

POST /_refresh 
POST /blogs/_refresh
//刷新(Refresh)所有的索引。
//只刷新(Refresh) blogs 索引。
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ES集群中的主副本数据不一致时, 系统会出现数据同步的问题。通常情况下,每个索引都有一个主分片和多个副本分片,主分片负责处理索引的读写操作,副本分片则用于复制主分片数据,提供冗余和负载均衡。 主副本数据不一致可能由于以下原因导致: 1. 写入延迟:当写入操作发生时,主分片首先接收并处理该操作,然后将操作结果复制到副本分片。如果由于某种原因导致主分片写入操作成功,但是副本分片的复制过程延迟,那么主副本数据就会不一致。 2. 网络问题:主分片和副本分片之间的网络连接不稳定或中断可能导致数据同步延迟或失败,进而导致主副本数据不一致。 解决这个问题的方法可以有以下几种: 1. 检查集群健康状态:通过ES集群健康状态API检查集群的状态,查看是否存在不一致的副本。 2. 强制数据同步:使用ES提供的_force merge API可以强制主副本数据同步,保证数据一致性。 3. 调整配置:可以调整副本分片的数量或者增加副本分片的索引数,以提高数据复制和同步的效率。 4. 优化网络连接:保证主分片和副本分片之间的网络连接稳定,减少网络延迟和断连的可能性。 总结来说,当ES主副本数据不一致时,我们需要检查集群健康状态,强制数据同步,调整配置,以及优化网络连接,以确保数据的一致性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值