二、基础知识
11. 分片内部原理
- 分片, 并将它 描述成最小的 工作单元
11.1. 使文本可被搜索
- 倒排索引
-
需要注意的是,倒排索引并非如此简单,会包含更多其它信息
-
它会保存每一个词项出现过的文档总数, 在对应的文档中一个具体词项出现的总次数,词项在文档中的顺序,每个文档的长度,所有文档的平均长度,用于后续的排序
-
早期的全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。 一旦新的索引就绪,旧的就会被其替换,这样最近的变化便可以被检索到。
11.1.1. 不变性
-
倒排索引被写入磁盘后是 不可改变 的:它永远不会修改。 不变性有重要的价值:
-
不用锁
-
一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求内存,而不会命中磁盘。这提供了很大的性能提升。
-
写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量
-
11.2. 动态更新索引
-
怎样在保留不变性的前提下实现倒排索引的更新?答案是: 用更多的索引
-
通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到—----从最早的开始—---查询完后再对结果进行合并。
11.3 写入原理
-
数据写入内存的 buffer 中
-
当 buffer 写满后,会将其写入新的 index segment中
-
es的底层是 lucene 存在多个 segment(内存中)
-
segment 中的内容 刷入 os cache 中(内存中,用于和磁盘交互的部分)
- 只要segment写入os cache,那就直接打开供 search 使用,不立即执行commit,这个阶段 refresh。 默认是每隔1秒refresh一次,也就是说,每隔一秒就会将buffer中的数据写入一个新的index segment file,先写入os cache中。所以,es是
近实时
的,数据写入到可以被搜索,默认是1秒。
- 只要segment写入os cache,那就直接打开供 search 使用,不立即执行commit,这个阶段 refresh。 默认是每隔1秒refresh一次,也就是说,每隔一秒就会将buffer中的数据写入一个新的index segment file,先写入os cache中。所以,es是
-
-
到这里,已经可以实现 秒 级别的检索操作(写入一秒后,可查询),但是缺少可靠性
-
数据同时写入 buffer缓冲和translog日志文件 实现高可用
-
新的segment不断添加,buffer不断被清空,而translog中的数据不断累加
-
当translog长度达到一定程度的时候,commit操作发生
- buffer中的所有数据写入一个新的segment,并写入os cache,打开供使用
- buffer被清空
- 一个commit ponit被写入磁盘,标明了所有的index segment
- filesystem cache中的所有index segment file缓存数据,被fsync强行刷到磁盘上
- 现有的translog被清空,创建一个新的translog
-
优化 (段合并)
-
默认会在后台对 segment 实现 merge 的操作,小的变大
-
有点类似 LSM 的操作
-
-
小结:磁盘上记录的是。commit 的位置,如果需要数据恢复,就是 commit 到 log 最开始的位置