ES写入数据的工作原理

2020/1/1

点击勘误issues (opens new window),哪吒感谢大家的阅读

# ES写入数据的工作原理

Elasticsearch (ES) 写入数据的工作原理非常重要,因为它决定了数据的存储方式、查询效率和系统的可靠性。

写入数据的大致流程

  1. 接收请求:用户通过 RESTful API 提交写入请求。
  2. 路由分片:ES 根据数据的 _id 或其他字段,计算出数据应该存储到哪个分片上。
  3. 主分片写入:写入请求先被发送到负责该分片的主节点。
  4. 副本同步:主分片将数据同步到对应的副本分片。
  5. 确认成功:主分片和副本分片都写入成功后,返回写入成功的响应。

详细步骤及类比

  1. 接收请求(用户提交快递信息)

    流程:用户通过 HTTP 请求提交数据(比如一条文档)。 类比:你去快递公司寄快递,告诉工作人员(ES 节点)收件人的信息和包裹内容。

  2. 路由分片(分配包裹)

    流程:ES 使用哈希算法计算出这条数据应该存储在哪个分片(Primary Shard)上。 类比:快递公司根据收件人的地址,分配包裹到某个区域的快递仓库(分片)。

实际例子:假设索引 my_index 有 5 个分片,数据的 _id 被分配到分片 3。

  1. 主分片写入(主仓库接收包裹)

    流程:数据被发送到分片 3 所在的主分片节点。主分片会先写入数据并记录到内存缓冲区和事务日志(Translog)。 类比:包裹到达对应的主仓库,仓库工作人员(主分片)先记录包裹信息到登记簿(事务日志),并把包裹暂时存放在一个临时区(内存缓冲区)。

作用: 事务日志:用于数据恢复,防止意外断电或节点故障导致数据丢失。 内存缓冲区:用于暂存写入的数据,定期刷新到磁盘。 实际例子: 主分片所在节点将文档存储到内存,同时记录到事务日志文件。

  1. 副本同步(备份包裹)

    流程:主分片将数据同步到其对应的副本分片。 如果一个分片有 2 个副本,那么数据会同步到另外两个节点上的副本分片。 类比:主仓库的工作人员将包裹的详细信息备份到其他仓库(副本分片),以防主仓库损坏或丢失包裹。 作用: 副本分片提高数据的高可用性,即使主分片故障,也能从副本中恢复数据。 实际例子: 主分片 3 将数据同步到副本分片 3 的两个副本节点。

  2. 确认写入成功(签收)

    流程:主分片和所有副本分片都写入成功后,主分片向客户端返回写入成功的确认。 类比:主仓库和其他仓库都完成包裹的登记后,快递公司给你一张签收单,表示包裹寄出成功。 实际例子: 客户端收到一个 HTTP 响应,状态码为 201 Created,表示文档已成功写入。

# 重要细节

  1. 数据刷新到磁盘(快递上架)

    内存缓冲区中的数据不会立即写入磁盘,而是定期(默认 1 秒)通过 Refresh 机制刷新到磁盘生成新的段(Lucene 索引文件)。 类比:快递临时存放在仓库的装车区,等到一定时间后才正式上架或发车。 手动触发刷新

  2. 事务日志和故障恢复

    即使数据还未写入磁盘,只要事务日志中记录了这条数据,ES 在故障恢复时也能重新加载数据。 类比:如果包裹信息已经登记,即使仓库的货架出了问题,也可以根据登记簿找回包裹。

  3. 写入时的冲突

    如果多个客户端同时写入同一条数据(同一个 _id),会触发版本冲突。 ES 提供 乐观锁机制 解决此类问题,通过 _version 字段确保数据一致性。

# 总结写入流程

以下是写入数据的核心流程:

  • 接收写入请求 → 数据到达集群,由主节点分配给目标分片。
  • 分片路由 → 通过哈希算法计算分片位置。
  • 主分片写入 → 数据写入主分片的内存缓冲区和事务日志。
  • 副本分片同步 → 主分片将数据同步到副本分片。
  • 确认成功 → 主分片和副本分片写入成功后,返回写入成功的响应。

es 无非就是写入数据,搜索数据。

# es 写数据过程

  • 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node (协调节点)。
  • coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。
  • 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node 。
  • coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。