首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Elasticsearch的分段存储思想

在早期的全文检索中为整个文档集合建立了一个很大的倒排索引,并将其写入磁盘中,如果索引有更新,就需要重新全量创建一个索引来替换原来的索引。这种方式在数据量很大时效率很低,并且由于创建一次索引的成本很高,所以对数据的更新不能过于频繁,也益不能保证时效性。

现在,在搜索中引入了段的概念(将一个索引文件拆分为多个子文件,则每个子文件叫作段),每个段都是一个独立的可被搜索的数据集,并且段具有不变性,一旦索引的数据被写入硬盘,就不可再修改。

分段的思想下的数据操作

新增:当有新的数据需要创建索引时,由于段的不变性,所以选择新建一个段来存储新增的数据。

删除:当需要删除数据时,由于数据所在的段只可读,不可写,所以 Lucene 在索引文件下新增了一个.del 的文件,用来专门存储被删除的数据 id。当查询时,被删除的数据还是可以被查到的,只是在进行文档链表合并时,才把已经删除的数据过滤掉。被删除的数据在进行段合并时才会真正被移除。

更新:更新的操作其实就是删除和新增的组合,先在.del 文件中记录旧数据,再在新段中添加一条更新后的数据。

段不变性的优点

不需要锁,因为数据不会更新,所以不用考虑多线程下的读写不一致情况。

可以常驻内存。段在被加载到内存后,由于具有不变性,所以只要内存的空间足够大,就可以长时间驻存,大部分查询请求会直接访问内存,而不需要访问磁盘,使得查的性能有很大的提升。

缓存友好。在段的声明周期内始终有效,不需要在每次数据更新时被重建。

增量创建。分段可以做到增量创建索引,可以轻量级地对数据进行更新,由于每次创建的成本很低,所以可以频繁地更新数据,使系统接近实时更新。

段不变性的缺点

当对数据进行删除时,旧数据不会被马上删除,而是在.del 文件中被标记为删除。而旧数据只能等到段更新时才能真正被移除,这样会有大量的空间浪费。

更新。更新数据由删除和新增这两个动作组成。若有一条数据频繁更新,则会有大量的空间浪费。

由于索引具有不变性,所以每次新增数据时,都需要新增一个段来存储数据。当段的数量太多时,对服务器的资源( 如文件句柄 )的消耗会非常大,查询的性能也会受到影响。

在查询后需要对已经删除的旧数据进行过滤,这增加了查询的负担。

为了提升写的性能,Lucene 并没有每新增一条数据就增加一个段,而是采用延迟写的策略每当有新增的数据时,就将其先写入内存中,然后批量写入磁盘中。若有一个段被写到硬盘,就会生成一个提交点,提交点就是--个用来记录所有提交后的段信息的文件。

一个段一旦拥了提交点,就说明这个段只有读的权限,失去了写的权限:相反,当段在内存中时,就只有写数据的权限,而不具备读数据的权限,所以也就不能被检索了。从严格意义上来说,Lucene或者 Elasticscarch 并不能被称为实时的搜索引擎,只能被称为准实时的搜索引擎。

写索引的流程

新数据被写入时,并没有被直接写到磁盘中,而是被暂时写到内存中。Lucene 默认是一秒钟,或者当内存中的数据量达到一定阶段时,再批量提交到磁盘中,当然,默认的时间和数据量的大小是可以通过参数控制的。通过延时写的策略,可以减少数据往磁盘上写的次数,从而提升整体的写入性能。

在达到触发条件以后,会将内存中缓存的数据一次性写入磁盘中,并生成提交点。

由于数据先被暂存放在内存中,并没有真正持久化到磁盘,所以如果这时出现断电等不可控的情况,就会丢失数据,为此,elasticsearch添加了事务日志,来保证数据的安全。

ps:事务日志下一篇介绍。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230607A0ATWO00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券