Elasticsearch原理知识点及整体结构

323 阅读3分钟

Elasticsearch整体结构

整体结构说明:

  • 在ES Index集群模式下,有多个Node(节点)组成。每个节点都是ES的实例
  • 每个节点有多个shard(分片),P0,P1,P2是主分片,R0,R1,R2为副本分片
  • 每个分片上对应着就是一个Lucene Index(底层索引文件)
  • Lucene Index 是一个统称
    • 由多个Segment(段文件,即倒排索引)组成。每个段文件存储的就是Doc文档
    • Commit Point 记录了所有segments的信息
    • Memory Buffer,数据缓冲区
    • TransLog,事务日志

Lucene索引结构

更多文件类型(可参考这里)如下:

文件的关系如下:

Lucene处理流程

创建索引的过程:

  • 准备待索引的原文档,数据来源可能是文件、数据库或网络
  • 对文档的内容进行分词组件处理,形成一系列的Term
  • 索引组件对文档和Term处理,形成字典和倒排表

搜索索引的过程:

  • 对查询语句进行分词处理,形成一系列Term
  • 根据倒排索引表查找出包含Term的文档,并进行合并形成符合结果的文档集
  • 比对查询语句与各个文档相关性得分,并按照得分高低返回

文档的写入与删除

文档写入

  1. Document 写入到 Memory Buffer(内存缓冲区)
  2. 当满足一定条件后内存缓冲区中的 Documents 刷新到高速缓存(Cache),数据从 BufferCache 的过程是定期每秒刷新一次
  3. 生成新的 Segment,这个 Segment 还在 Cache 中;这时候还没有 commit,但是已经可以被读取了

Translog 事务日志

  1. Document 写入到 Memory Buffer时,同时会追加TransLog(类似MySQL中的binlog

  2. Buffer 中的数据每秒 RefreshCache 中时,Translog 并没有进入到刷新到磁盘,是持续追加的

  3. Translog 每隔 5s 会 fsync 到磁盘

  4. Translog 会继续累加变得越来越大,当 Translog 大到一定程度或者每隔一段时间,会执行 flush

flush 操作会分为以下几步执行:

  • Buffer 被清空
  • 记录 commit point
  • Cache 内的 Segmentfsync 刷新到磁盘
  • Translog 被删除

值得注意的是:

  • Translog 每 5s 刷新一次磁盘,所以故障重启,可能会丢失 5s 的数据
  • Translog 执行 flush 操作,默认 30 分钟一次,或者 Translog 太大也会执行

删除和更新

Segment 不可改变,所以 Docment 并不能从之前的 Segment 中移除或更新。

所以每次 commit, 生成 commit point 时,会有一个 .del 文件,里面会列出被删除的 Document(逻辑删除)。

而查询时,获取到的结果在返回前会经过 .del 过滤。更新时,也会标记旧的 Docment 被删除,写入到 .del 文件,同时会写入一个新的文件。

此时查询会查询到两个版本的数据,但在返回前会被移除掉一个。

Segment 合并

每 1s 执行一次 Refresh 都会将内存中的数据创建一个 Segment

Segment 数目太多会带来较大的麻烦。每一个 Segment 都会消耗文件句柄、内存和 cpu 运行周期。

更重要的是,每个搜索请求都必须轮流检查每个 Segment,所以 Segment 越多,搜索也就越慢。

在 ES 后台会有一个线程进行 Segment 合并:

  • Refresh 操作会创建新的 Segment 并打开以供搜索使用。
  • 合并进程选择一小部分大小相似的 Segment,并且在后台将它们合并到更大的 Segment 中。这并不会中断索引和搜索。
  • 当合并结束,老的 Segment 被删。

说明合并完成时的活动:

  • 新的 Segment 被刷新(flush)到了磁盘。 写入一个包含新 Segment 且排除旧的和较小的 Segment的新 commit point
  • 新的 Segment 被打开用来搜索。
  • 老的 Segment 被删除(物理删除)