ElasticSearch 的分片,在Lucene 中又被称为 Index
在学习分片前,先介绍几个概念,有助于更清晰的认识分片。
带着这三个问题,看下面的文档。
- 为什么ES的搜索是近实时的?
- ES 如何保证断电时数据不丢失?
- 为什么删除文档,不会立刻释放空间?
倒排索引的不可变性
ElasticSearch中的倒排索引一旦生成,就不可更改。
不可变性的优点:
- 无需考虑写文件的问题,避免了锁机制带来的性能问题
- 一旦读入文件系统缓存,便留在那里,不会更改,极大的减小了系统开销
- 缓存更容易生成和维护
不可变带来的问题
- 如果新增了文档,需要重新生成索引,新文档才能被查询到
Lucene Index
在Lucene中单个倒排索引文件称为 Segment,Segment是不可变更的。多个Segment汇集在一起,称为Index,对应这个ES中的shard。
ES中专门有 Commit Point 用来记录所有的Segment 信息,当有新文档写入时会生成新的Segment,查询时会同时查询所有Segment,最后对结果进行汇总。
删除的文档信息,保存在 “.del” 文件中(此时并不会真正删除),最后的搜索结果中会对删除的文档过滤。
文档写入 之 Refresh
ES中写入文档时,会先把文档写到一个内存空间 Index Buffer 中,到达一定时间,es将 index buffer 中的内容写到 Segment(先使用文件系统缓存这时候就可以查询了,然后刷新到磁盘)中并将index buffer 清空,这个写入的过程称为 Refresh。
Refresh 不执行 fsync 操作。
- Refresh 的频率默认1s一次,可通过index.refresh_interval配置,Refresh 过后文档就可以搜索到了,这也是为什么ElasticSearch 被称为“近实时搜索”
- 如果有大量的的数据写入,就会产生很多的 Segment
- Index Buffer 被占满时,也会触发Refresh, 默认值是jvm的10%
文档写入之Transaction log
在文档写入index buffer 的同时,会写入Transaction log,每个分片都有一个Transaction log,Transaction log 默认是落盘的。
然后,Refresh 时将Index buffer 写入Segment,同时开放Segment 查询。index buffer 被清空,但Transaction log 会被保留
当系统断电重启时,ElasticSearch 会先从Transaction log 恢复数据。
文档写入之Flush
- 执行Flush 时,会先调用Refresh,清空Index Buffer
- 调用fsync 将缓存中的Segment 写入磁盘,并清空 Transaction log
- Flush 默认30分钟执行一次
- Transaction log 满时也会触发 Flush, 默认大小是512MB
文档写入之 Merge
- 在执行完Flush后,磁盘上会产生大量的Segment 文件,这时候就需要对Segment文件进行定期处理,以减少Segment 数量
- Merge 可以把多个Segment文件合并为一个
- Merge 同时会把“.del”文件中记录的文档进行真正的删除
- ES 和 Lucene 会自动进行Merge 操作
- POST index/_forcemerge 手动Merge
https://www.hugbg.com/archives/2083.html
2020-04-09 11:33 上午 1F
生老病死,八苦之四,众生必经,江澄亦是。 —魔道祖师
2020-04-20 12:25 下午 2F
花自飘零水自流。一种相思,两处闲愁。 —一剪梅·红藕香残玉簟秋