前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES系列终章-索引的存储

ES系列终章-索引的存储

作者头像
热心的大肚皮
发布2023-02-28 13:49:39
2840
发布2023-02-28 13:49:39
举报

哈喽大家好,不知不觉半年过去了,es也迎来了最终章。话不多说,开始整。

今天的话,咱们一起聊聊索引的存储吧。对了,大家知道es是怎么分配文档写入哪个分片的吗?其实遵循的原理于之前聊过的map比较像的。

代码语言:javascript
复制
shard = hash(routing) % number_of_primary_shards

routing字段默认为id。

那索引的物理结构是什么样的呢?

Lucene有2种文件格式,是根据CompoundFile 来判断的。

CompoundFile == false

CompoundFile == true

组合文件只是将原来放在多个文件中的数据整合到少数的几个文件中,减少了打开的文件描述符的数量,其它并没有大的区别,所以我们重点来看非组合文件。

不变性

写到磁盘的倒序索引是不变的:自从写到磁盘就再也不变。这会有很多好处:

不需要添加锁。不存在写操作,因此不存在多线程更改数据。

提高读性能。一旦索引被内核的文件系统做了Cache,绝大多数的读操作会直接从内存而不需要经过磁盘。减少磁盘I/O和计算消耗。lucene的缓存可分为两类:filter cache和field cache。filter cache的实现类为CachingWrapperFilter,用来缓存其他Filter的查询结果。field cache的实现类是FieldCache,缓存用于排序的field的值。

当然,索引的不变性也有缺点。如果你想让新修改过的文档可以被搜索到,你必须重新构建整个索引。这在一个index可以容纳的数据量和一个索引可以更新的频率上都是一个限制。

索引数据的写入
translog

当一个文档写入Lucence后是存储在内存中的,即使执行了refresh操作仍然是在文件系统缓存中,如果此时服务器宕机,那么这部分数据将会丢失。为此ES增加了translog, 当进行文档写操作时会先将文档写入Lucene,然后写入一份到translog,写入translog是落盘的(如果对可靠性要求不是很高,也可以设置异步落盘,可以提高性能,由配置index.translog.durability和index.translog.sync_interval控制),这样就可以防止服务器宕机后数据的丢失。由于translog是追加写入,因此性能比较好。与传统的分布式系统不同,这里是先写入Lucene再写入translog,原因是写入Lucene可能会失败,为了减少写入失败回滚的复杂度,因此先写入Lucene。

segment

上面提到,每次refresh的时候,都会在文件系统缓冲区中生成一个segment,后续flush触发的时候持久化到磁盘。所以,随着数据的写入,尤其是refresh的时间设置的很短的时候,磁盘中会生成越来越多的segment,

通过每隔一秒的自动刷新机制会创建一个新的segment,用不了多久就会有很多的segment。segment会消耗系统的文件句柄,内存,CPU时钟。最重要的是,每一次请求都会依次检查所有的segment。segment越多,检索就会越慢。

segment数目太多会带来较大的麻烦。每一个segment都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个segment,所以segment越多,搜索也就越慢。

merge 的默认条件:每30分钟或当translog达到一定大小(由index.translog.flush_threshold_size控制,默认512mb)

merge的过程大致描述如下:

磁盘上两个小segment:A和B,内存中又生成了一个小segment:C

A,B被读取到内存中,与内存中的C进行merge,生成了新的更大的segment:D

触发commit操作,D被fsync到磁盘

创建新的提交点,删除A和B,新增D

删除磁盘中的A和B

索引数据的删除

磁盘上的每个segment都有一个删除文件与它相关联。当发送删除请求时,该文档未被真正删除,而是在删除文件中标记为已删除。此文档可能仍然能被搜索到,但会从结果中过滤掉。当segment合并时,在删除文件中标记为已删除的文档不会被包括在新的segment中,也就是说merge的时候会真正删除被删除的文档。

索引数据的更新

创建新文档时,Elasticsearch将为该文档分配一个版本号。对文档的每次更改都会产生一个新的版本号。当执行更新时,旧版本在删除文件中被标记为已删除,并且新版本在新的segment中写入索引。旧版本可能仍然与搜索查询匹配,但是从结果中将其过滤掉。

接下来呢,会和大家一起聊聊jvm,作为程序猿怎么能不了解jvm呢。

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-27,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 程序猿日常笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 不变性
  • 索引数据的写入
  • translog
  • segment
  • 索引数据的删除
  • 索引数据的更新
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com