MST
星途 面试题库

面试题:ElasticSearch基本写模型之数据写入流程

请详细阐述ElasticSearch在执行一条简单文档写入操作时,从客户端发起请求到数据最终持久化存储的整个基本流程。
19.0万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试
  1. 客户端请求阶段
    • 客户端通过 RESTful API 向 Elasticsearch 集群中的某个节点(通常是负载均衡器分配的任意一个节点,这个节点被称为协调节点)发送写入文档的请求。请求中包含了要写入的文档数据、索引名称、文档类型(在 Elasticsearch 7.x 及之后版本,文档类型逐渐被弃用)等关键信息。
  2. 协调节点处理阶段
    • 协调节点接收到请求后,首先根据索引名称,通过集群状态信息(保存在主节点并同步到其他节点)计算出文档应该被路由到哪个分片(主分片或副本分片)上。它使用一种一致性哈希算法,基于索引名称和文档的 _id(如果请求中未指定 _id,Elasticsearch 会自动生成一个)来确定目标分片。
    • 一旦确定了目标分片,协调节点会将请求转发到负责该分片的主分片所在的节点(如果目标是副本分片,会先转发到主分片所在节点)。
  3. 主分片所在节点处理阶段
    • 主分片所在节点接收到协调节点转发过来的请求后,会执行以下操作:
      • 写入内存缓存:将文档写入到内存中的 Lucene 索引的 Segment 缓存(也叫 write buffer)中。这个缓存是易失性的,数据在缓存中的格式是一种临时的、便于快速索引的数据结构。同时,为了保证数据的顺序性和事务一致性,文档会被记录到一个 translog(事务日志)中,translog 是持久化存储在磁盘上的,以追加写的方式记录所有的写操作。
      • 数据刷新:当 write buffer 满(默认是 10% 的堆内存)或者达到一定时间间隔(默认 1 秒)时,内存中的数据会被刷新到一个新的 Segment 文件中,这个过程称为 refreshSegment 是 Lucene 底层的一个存储单元,每个 Segment 包含了一部分文档的索引数据,并且是不可变的。刷新后,write buffer 被清空,新的写入操作会再次填充 write buffer。同时,新生成的 Segment 会被打开供搜索使用,此时文档在索引中就可以被搜索到了,但还没有持久化到磁盘。
      • 数据持久化:随着写操作的不断进行,translog 会不断增大。为了防止 translog 过大,并且确保数据的持久化,Elasticsearch 会定期(默认 30 分钟)或者当 translog 达到一定大小(例如 512MB)时,触发一次 flush 操作。在 flush 操作中,所有未提交的 Segment 会被提交到磁盘,生成一个包含所有已提交 Segmentcommit point 文件,同时 translog 会被截断(保留未完成的事务日志部分)。这样,数据就从内存持久化到了磁盘。
  4. 副本分片同步阶段
    • 主分片成功写入并持久化后,会将写操作同步到该分片的所有副本分片所在的节点。副本分片所在节点接收到同步请求后,会按照与主分片类似的流程,将数据写入自己的内存缓存、translog,并在合适的时候进行 refreshflush 操作,从而完成副本数据的更新和持久化。
  5. 响应阶段
    • 当主分片和所有副本分片都成功写入数据后,主分片所在节点会向协调节点发送写入成功的响应。协调节点收到响应后,再将这个成功响应返回给客户端,表示文档写入操作成功完成。如果在任何阶段出现错误,例如某个副本分片同步失败,Elasticsearch 会根据配置决定是否继续进行操作或者返回错误给客户端。通常,默认情况下只要主分片写入成功,并且一定数量(可配置,默认是 quorum,即超过半数的副本分片)的副本分片同步成功,就会认为写入操作成功。