笔记三十三: 分片及其生命周期
分片的内部原理
- 什么是ES的分片
- ES中最小的工作单元 / 是一个Lucence的Index
- 一些问题:
- 为什么ES的搜索时近实时的(1秒后被搜到)
- ES如何保证在断电时数据也不会丢失
- 为甚删除文档,并不会立刻释放空间
倒排索引的不可变性
- 倒排索引采用
Immutable Design
,一旦生成,不可更改 - 不可变性,带来了的好处如下:
- 不许考虑并发写文件的问题,避免了锁机制带来的性能问题
- 一旦读入内核的文件系统缓存,便留在那里,只要文件系统存有足够的空间,大部分请求就会直接请求内存,不会命中磁盘,提高了很大的性能
- 缓存容易生成和维护 / 数据可以被压缩
- 不可变更性,带来了的挑战:如果需要让一个新的文档可以被搜索,需要重建整个索引
Lucence Index
- 在Lucene中,单个倒排索引文件被称为
Segment
。Segment
是自包含的,不可变更的。多个Segment
汇总在一起,称为Lucene的Index,其对应的就是ES中的Shard - 当有新文档写入时,会生成新的
Segment
,查询时会同时查询所有的Segment
,并且对结果汇总。Luncene中有个文件,用来记录所有的Segment
的信息,叫做Commit Point
- 删除的文档信息,保存在”.del”文件中
Refresh
- 将Index buffer 写入
Segment
的过程叫做Refresh
。Refresh
不执行fsync
操作 Refresh
频率:默认1秒发生一次,可通过index.refresj_interval
配置。Refresh
后,数据就可以被搜索到了。这也就是为什么ES被称为近实时搜索- 如果系统有大量的数据写入,那就会产生很多的
Segment
- Index Buffer 被占满时,会触发
Refresh
,默认值是JVM的10%
Transaction Log
-Segment
写入磁盘的过程相对耗时,借助文件系统缓存,Refresh时,先将Segment
写入缓存以开放查询
- 蔚来保证数据不会丢失。所有在Index文档时,同时写
Transaction Log
,高版本开始,ra默认落盘。每个分片都有一个Transaction Log
- 当
ES Refresh
时,Index Buffer
被清空,Transaction Log
不会清空
Flush
- ES Flush & Lucene Commit
- 调用
Refresh
,Index Buffer
清空并且Refresh
- 调用fsync,将缓存中的
Segments
写入磁盘 - 清空(删除)
Transaction Log
- 默认30分钟调用一次
Transaction Log
满(默认512M)
- 调用
Merge
Segment
很多,需要定期被合并- 减少
Segment
/ 删除已经删除的文档
- 减少
- ES 和Lucene 会自动进行Merge操作
- POST my_index/_forcemerge
本作品采用《CC 协议》,转载必须注明作者和本文链接