Elasticsearch原理(三):写入流程

本文深入探讨了Elasticsearch的写入流程,从Lucene的基础写入开始,逐步解析Elasticsearch如何通过shard、TransLog和副本分片实现分布式写入的实时性和可靠性。在Elasticsearch中,写入数据首先经过Ingest Pipeline处理,然后通过主分片和副本分片的交互确保数据一致性。虽然Elasticsearch不是实时的,但通过TransLog可以在1秒内使数据可搜索。此外,更新操作实际上是先删除旧文档再添加新文档。文章还介绍了如何通过调整副本数量和TransLog刷新频率来平衡性能和安全性。
摘要由CSDN通过智能技术生成

这篇文章我们探索Elasticsearch的写入流程,Elasticsearch的写入跟数据库的写入是完全不同的。

数据库中的写入只是单纯的写入行,Elasticsearch中的写入则是建立索引文件,可以理解成数据即索引。下面对比分析Elasticsearch与NoSQL数据库区别。

Elasticsearch并不支持事务。

实时性

Elasticsearch的主要应用场景就是实时,但Elasticsearch本身并非实时而是near-real-time(近实时)。Elasticsearch默认写入的数据会在1秒后,才可以被检索到。

NoSQL数据库则可以做到real-time(实时),一般情况下写入成功后是马上可以被查询到的。Elasticsearch中的Get请求也能保证是实时的,因为Get请求会直接读内存中尚未Flush到磁盘的TransLog。但是Get请求只支持通过doc_id进行查询,所以对于条件查询依然无法实现实时。

关于Get和Search请求:ElasticSearch原理(四):查询流程

可靠性

一种情况是我们从一个原始数据源,比如数据库,导入数据到Elasticsearch。这种情况对Elasticsearch的可靠性要求可能就没那么高,主要的功能还是搜索。因为原始数据存储是一个数据保障,即使Elasticsearch发生数据丢失,重新导入就行了。但有一种场景就是数据直接写Elasticsearch的,并且不允许丢失,这个时候对Elasticsearch的可靠性要求就很高。

关于Elasticsearch可靠性:ElasticSearch干货(五):Elasticsearch如何保证数据不丢失?

NoSQL数据库本身作为一款数据库,数据库对于数据可靠性一般都非常的高,但这也是数据库性能瓶颈的所在。如何使用Elasticsearch来中和两者,既保证数据可靠有保证性能就尤为重要。


众所周知,Elasticsearch是基于Lucene实现的,并且在Lucene的基础上做了功能上的修改和优化。下面我们开始探讨Lucene的写入和Elasticsearch的写入有什么区别。

Lucene的写入

Lucene的写入主要是index、update、和delete。因为segment是不支持修改的,所以update和delete其实都是写入。
Lucene中写操作主要是通过IndexWriter类实现,IndexWriter提供三个接口:

 public long addDocument();
 public long updateDocuments();
 public long deleteDocuments();

只要Doc通过IndesWriter写入后,后面就可以通过IndexSearcher搜索了。但也存在几点缺陷:

  • Lucene并不是分布式
  • Lucene只有在数据生成索引文件(segment)之后,才会被查询到,做不到实时
  • 如何保证segment的可靠性
  • segment不支持更新,一旦创建不能修改,所以不支持针对分档进行部分更新

Elasticsearch的写入

首先针对上述提到的Lucene的缺陷一一介绍Elasticsearch是怎么弥补优化的。

Elasticsearch为了实现分布式,引入了shard,将segment分布在不同的机器上。并且根据_routing来决定如何分配到指定的shard。

Elasticsearch中每个index由多个shard组成,默认是5个,每个shard分布在不同的机器上。shard分为主分片和副本分片,在文档写入时,会根据_routing来计算(OperationRouting类)得出文档要写入哪个分片。这里的写入请求只会写主分片,当主分片写入成功后,会同时把写入请求发送给所有的副本分片,当副本分片写入成功后,会传回返回信息给主分片,主分片得到所有副本分片的返回信息后,再返回给客户端。
在写入时,我们可以在Request自己指定_routing,也可以在Mapping指定文档中的Field值作为_routing。如果没有指定_routing,则会把_id作为_routing进行计算。由于写入时,具有相同_routing的文档一定会分配在同一个分片上,所以如果是自定义的_routing,在查询时,一定要指定_routing进行查询,否则是查询不到文档的。这并不是局限性,恰恰相反,指定_routing的查询,性能上会好很多,因为指定_routing意味着直接去存储数据的shard上搜索,而不会搜索所有shard。

从上述可以看出,Elasticsearch文档写入主要是写主分片和写副本分片。所以副本分片的个数就直接决定了写入的性能。合理

  • 11
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值