Elasticsearch写入的核心概念

分段

分段是Elasticsearch中的一个重要概念,其核心目的是更高效地执行搜索和更新操作。在Elasticsearch中,段是由一些倒排索引和一些元数据组成的。元数据包括与该段相关的信息,例如段的大小、创建日期和所包含的文档数量。分段是将索引分成多个小段的过程,每个分段包含一部分索引数据。查看索引中分段信息的方法如下。

GET products/_segments

索引、分片、分段的关系如图:

在这里插入图片描述

事务日志文件

为了防止Elasticsearch集群宕机造成数据丢失,为了保证可靠存储,一个文档被索引之后,Elasticsearch就会将其添加到内存缓冲区,并且同时写入事务日志文件(translog)中。

translog的作用是保证数据的可靠性和一致性。当Elasticsearch节点出现故障或崩溃时,translog可以用来恢复数据。在节点重新启动后,Elasticsearch会重新读取translog中的所有操作并将其应用到Lucene索引中,从而使数据保持一致。

倒排索引是不可变的

已写入磁盘的倒排索引永远不会改变。使用倒排索引的好处是无须锁定,不用担心多进程操作更改数据导致数据不一致问题。使用倒排索引的坏处是更新了词典词库后,老的索引不能生效,如果要使其可搜索,则必须重建整个索引或者借助reindex操作迁移索引。这也是经常被问到的一点。

在这里插入图片描述

段是不可变的

单个文档写入操作对应Index请求,批量写入操作对应Bulk请求。Index和Bulk这两类请求是相同的处理逻辑,会将请求统一封装到BulkRequest中。写入原理图如图所示。

在这里插入图片描述
写入过程拆解如下。

1)客户端向主节点1发送写数据请求。此时主节点1充当协调节点的角色。

2)主节点1使用文档的ID确定文档属于分片0。请求会被转发到节点3,因为分片0的主分片目前被分配在节点3上。使用路由算法来通过文档的ID确定文档所属分片。路由算法计算公式如下。

shard=hash(routing)%number_of_primary_shards

其中,routing表示文档ID,number_of_primary_shards表示主分片个数,shard表示文档ID所属分片号。

3)节点3在主分片上面执行写入操作。如果写入成功了,它将请求并行转发到主节点1和节点2的副本分片上。一旦所有的副本分片都报告成功,节点3将向协调节点报告写入成功,则协调节点会向客户端报告写入成功。

写入过程的注意点如下。

❑写操作必须在主分片执行成功后,才能复制相关的副本分片。

❑主分片写入失败,则整个请求会被认为是写失败的。

❑如果有部分副本写失败(前提是主分片写入成功),则整个请求会被认为是写成功的。

❑如果设置了副本,则数据会先写入主分片,主分片再同步到副本分片,同步操作会加重磁盘IO负担,间接影响写入性能。

在Elasticsearch中,可以通过在执行写入操作时设置write_consistency参数来配置写入一致性级别。

默认情况下,write_consistency参数的取值为"quorum",表示要求主副本和大多数副本(至少一半加1)成功写入才返回成功的响应。如果设置为"all",则表示要求主副本和所有副本都成功写入才返回成功的响应。如果设置为"one",则表示仅要求主副本成功写入即可返回成功的响应。

在执行写入操作时,可以将write_consistency参数作为一个选项传递给相关的API。例如,在使用Index API创建文档时,可以使用以下方式指定write_consistency参数:

POST /my_index/_doc?write_consistency=all
{
  "field1": "value1",
  "field2": "value2"
}

可以通过修改索引的设置,在索引级别上配置全局的write_consistency参数。例如,使用Update Index Settings API来更新索引的设置:

PUT /my_index/_settings
{
  "index": {
    "write": {
      "consistency": "all"
    }
  }
}

Elasticsearch refresh和flush操作

refresh操作

将文档插入Elasticsearch时,文档会被写入内存缓冲区中,然后通过refresh(刷新)操作定期从该缓冲区刷新到内存段中。刷新频率由refresh_interval参数控制,默认1s刷新一次,所以说Elasticsearch是近实时的搜索引擎,而不是准实时。也就是说,新插入的文档在刷新到段(内存中)之前是不能被搜索到的,如图所示。

在这里插入图片描述

flush操作

新创建的文档会先进入内存缓冲区,与此同时会将操作记录在事务日志之中。当发生刷新时事务日志中的操作记录并不会被清除,而是在数据从文件系统缓存写入磁盘之后才会清空。从文件系统缓存写入磁盘的过程就是flush(该操作也翻译为“刷新”,为了避免和refresh混淆,这里保留了flush操作的写法,可理解为“持久化并清空事务日志”)。

flush操作的实现如下。

POST /my-index-000001/_flush

总结一下,当新的文档写入后,写入索引缓冲区(index buffer)的同时会写入事务日志。refresh操作使得写入文档搜索可见;flush操作将文件系统缓存(filesystem cache)写入磁盘,以达到持久化的目的。

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值