Elasticsearch:Elasticsearch中的refresh和flush操作指南

在今天的文章里,我们来主要介绍一下Elasticsearch的refresh及flush两种操作的区别。如果我们从字面的意思上讲,好像都是刷新的意思。但是在Elasticsearch中,这两种操作是有非常大的区别的。本指南将有效解决两者之间的差异。 我们还将介绍Lucene功能的基础知识,例如重新打开(reopen)和提交(commit),这有助于理解refresh和flush操作。

Refresh及Flush

乍一看,Refresh和Flush操作的通用目的似乎是相同的。 两者都用于使文档在索引操作后立即可供搜索。 在Elasticsearch中添加新文档时,我们可以对索引调用_refresh或_flush操作,以使新文档可用于搜索。 要了解这些操作的工作方式,您必须熟悉Lucene中的Segments,Reopen和Commits。Apache Lucene是Elasticsearch中的基础查询引擎。

Lucene中的Segments

在Elasticsearch中,最基本的数据存储单位是shard。 但是,通过Lucene镜头看,情况会有所不同。 在这里,每个Elasticsearch分片都是一个Lucene索引(index),每个Lucene索引都包含几个Lucene segments。 一个Segment包含映射到文档里的所有术语(terms)一个反向索引(inverted index)。

下图显示了段的概念及其如何应用于Elasticsearch索引及其分片:
?

这种分Segment的概念是,每当创建新文档时,它们就会被写入新的Segment中。 每当创建新文档时,它们都属于一个新的Segment,并且无需修改前一个Segment。 如果必须删除文档,则在其原始Segment中将其标记为已删除。 这意味着它永远不会从Segement中物理删除。

与更新相同:文档的先前版本在上一个Segment中被标记为已删除,更新后的版本保留在当前Segment中的同一文档ID下。

Lucene中的Reopen

当调用Lucene Reopen时,将使累积的数据可用于搜索。 尽管可以搜索最新数据,但这不能保证数据的持久性或未将其写入磁盘。 我们可以调用n次重新打开功能,并使最新数据可搜索,但不能确定磁盘上是否存在数据。

Lucene中的Commits

Lucene提交使数据安全。 对于每次提交,来自不同段的数据将合并并推送到磁盘,从而使数据持久化。 尽管提交是持久保存数据的理想方法,但问题是每个提交操作都占用大量资源。 每个提交操作都有其自己的内部 I/O 操作以及与其相关的读/写周期。 这就是为什么我们希望在基于Lucene的系统中一次又一次地重新使用重新打开功能以使新数据可搜索的确切原因。

Elasticsearch中的Translog

Elasticsearch采用另一种方法来解决持久性问题。 它在每个分片中引入一个事务日志(transaction log)。 已建立索引的新文档将传递到此事务日志和内存缓冲区中。 下图显示了此过程:

Elasticsearch中的refresh

当我们把一条数据写入到Elasticsearch中后,它并不能马上被用于搜索。新增的索引必须写入到Segment后才能被搜索到,因此我们把数据写入到内存缓冲区之后并不能被搜索到。新增了一条记录时,Elasticsearch会把数据写到translog和in-memory buffer(内存缓存区)中,如下图所示:

如果希望该文档能立刻被搜索,需要手动调用refresh操作。在Elasticsearch中,默认情况下_refresh操作设置为每秒执行一次。 在此操作期间,内存中缓冲区的内容将复制到内存中新创建的Segment中,如下图所示。 结果,新数据可用于搜索。

这个refresh的时间间隔可以由index设置中index.refresh_interval来定义。执行完refresh后的结果如下:

我们可以看出来,在In-meomory buffer中,现在所有的东西都是空的,但是Translog里还是有东西的。

refresh的开销比较大,我在自己环境上测试10W条记录的场景下refresh一次大概要14ms,因此在批量构建索引时可以把refresh间隔设置成-1来临时关闭refresh,等到索引都提交完成之后再打开refresh,可以通过如下接口修改这个参数:

curl -XPUT 'localhost:9200/test/_settings' -d '{
    "index" : {
        "refresh_interval" : "-1"
    }
}'

另外当你在做批量索引时,可以考虑把副本数设置成0,因为document从主分片(primary shard)复制到从分片(replica shard)时,从分片也要执行相同的分析、索引和合并过程,这样的开销比较大,你可以在构建索引之后再开启副本,这样只需要把数据从主分片拷贝到从分片:

curl -XPUT 'localhost:9200/my_index/_settings' -d ' {
    "index" : {
        "number_of_replicas" : 0
    }
}'

执行完批量索引之后,把刷新间隔改回来:

curl -XPUT 'localhost:9200/my_index/_settings' -d '{
    "index" : {
        "refresh_interval" : "1s"
    }
}'

你还可以强制执行一次refresh以及索引分段的合并:

curl -XPOST 'localhost:9200/my_index/_refresh'
curl -XPOST 'localhost:9200/my_index/_forcemerge?max_num_segments=5'

Translog及持久化存储

但是,translog如何解决持久性问题? 每个Shard中都存在一个translog,这意味着它与物理磁盘内存有关。 它是同步且安全的,因此即使对于尚未提交的文档,您也可以获得持久性和持久性。 如果发生问题,可以还原事务日志。 同样,在每个设置的时间间隔内,或在成功完成请求(索引,批量,删除或更新)后,将事务日志提交到磁盘。

Elasticsearch中的Flush

Flush实质上意味着将内存缓冲区中的所有文档都写入新的Lucene Segment,如下面的图所示。 这些连同所有现有的内存段一起被提交到磁盘,该磁盘清除事务日志(参见图4)。 此提交本质上是Lucene提交(commit)。

Flush会定期触发,也可以在Translog达到特定大小时触发。 这些设置可以防止Lucene提交带来的不必要的费用。

结论
在本指南中,我们探索了两个紧密相关的Elasticsearch操作,_flush和_refresh显示了它们之间的共性和差异。 我们还介绍了Lucene的基础架构组件-重新打开(reopen)并提交(commits)-这有助于掌握Elasticsearch中_refresh和_flush操作的要点。
简而言之,_refresh用于使新文档可见以进行搜索。 而_flush用于将内存中的段保留在硬盘上。 _flush不会影响Elasticsearch中文档的可见性,因为搜索是在内存段中进行的,而不是_refresh会影响其可见性。

参考:
【1】https://qbox.io/blog/refresh-flush-operations-elasticsearch-guide
【2】https://www.ezlippi.com/blog/2018/04/elasticsearch-translog.html

原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/12092561.html

时间: 2024-10-28 11:21:41

Elasticsearch:Elasticsearch中的refresh和flush操作指南的相关文章

[Elasticsearch] 聚合中的重要概念 - Buckets(桶)及Metrics(指标)

[Elasticsearch] 聚合中的重要概念 - Buckets(桶)及Metrics(指标) 2015-01-04 来源: http://blog.csdn.net/dm_vincent/article/details/42387161 本章翻译自Elasticsearch官方指南的Aggregations-High-level Concepts一章. 高层概念(High-Level Concepts) 和查询DSL一样,聚合(Aggregations)也拥有一种可组合(Composabl

elasticsearch 安装中可能遇到的问题

1.can not run elasticsearch as root 切换到非root用户 groupadd elasticsearch useradd -g elasticsearch elasticsearch passwd elasticsearch 2.main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrust

alert日志中出现Private Strand Flush Not Complete的处理方法

还是南京那个客户的库,alert.log日志还报了如下的错误: Fri Oct 17 19:59:51 2014 Thread 1 cannot allocate new log, sequence 4722 Private strand flush not complete Current log# 1 seq# 4721 mem# 0: /oradata/sgomp5/redo01.log Thread 1 advanced to log sequence 4722 (LGWR switch

Elasticsearch的Refresh与Flush操作

初次接触到这两个概念,估计都会觉得他们没什么差别,都是为了在操作索引之后让索引可以被实时性的搜索,不过它们还是有点不同的.Elasticsearch底层依赖Lucene,这里我们介绍下Lucene的segment, Reopen,commit.Segment在ES中,基本的存储单元是shard(分片),但是在更底层的Lucene上稍微有点不同,ES的每一个shard是Lucene的一个index(索引),Lucene的索引由多个segment组成,每个segment就是ES文档的倒序索引,里面包

[Elasticsearch] 聚合中的重要概念 - Buckets(桶)及Metrics(zh)

本章翻译自Elasticsearch官方指南的Aggregations-High-level Concepts一章. 高层概念(High-Level Concepts) 和查询DSL一样,聚合(Aggregations)也拥有一种可组合(Composable)的语法:独立的功能单元可以被混合在一起来满足你的需求.这意味着需要学习的基本概念虽然不多,但是它们的组合方式是几近无穷的. 为了掌握聚合,你只需要了解两个主要概念: Buckets(桶): 满足某个条件的文档集合. Metrics(指标):

ElasticSearch 生产中的问题与解决方案

1.由 gc 引起节点异常 问题: 因为 gc 时会使 jvm 停止工作,如果某个节点 gc 时间过长,master ping 3次(zen discovery默认 ping 失败重试 3 次)不通后就会把该节点剔除出集群,从而导致索引进行重新分配. 解决方法: 1. 优化gc,减少gc时间. 2. 调大zen discovery 的重试次数(es参数:ping_retries)和超时时间(es参数:ping_timeout) 后来发现根本原因是有个节点的系统所在硬盘满了.导致系统性能下降. 2

elasticsearch配置文件中http.cors.x字段有哪些用途和用法

http.cors.enabled 是否支持跨域,默认为false http.cors.allow-origin 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式.比如只允许本地地址. /https?:\/\/localhost(:[0-9]+)?/ http.cors.max-age 浏览器发送一个"预检"OPTIONS请求,以确定CORS设置.最大年龄定义多久的结果应该缓存.默认为1728000(20天) http.cors.all

[Elasticsearch] Elasticsearch权威指南翻译目录

为了方便大家能够更加快速地找到自己需要参考的那部分,对已经翻译完成的部分根据权威指南的目录做了相应目录,希望能够有所帮助. 起步(Getting Started) 1. 你懂的,为了搜索 英文原文链接:You Know, for Search 2. 集群中的生活 译文链接: [Elasticsearch] 集群的工作原理 - 第一部分 [Elasticsearch] 集群的工作原理 - 第二部分 英文原文链接:Life inside a Cluster 3. 数据进,数据出 英文原文链接:Dat

ELK 学习笔记之 elasticsearch elasticsearch.yml配置概述

elasticsearch.yml配置概述: 设置集群名字 cluster.name 定义节点名称 node.name 节点作为master,但是不负责存储数据,只是协调. node.master: true node.data: false 子节点,存储数据 node.master: false node.data: true 该节点是一个负载均衡器,什么都不做 node.master: false node.data: false 分片数 index.number_of_shards 副本数