Tavio's blog Tavio's blog
首页
  • JVM底层原理
  • 邪恶多线程
  • MyBatis底层原理
  • Spring底层原理
  • MySQL的优化之路
  • ClickHouse的高性能
  • Redis的快速查询
  • RabbitMQ的生产
  • Kafka的高吞吐量
  • ES的入门到入坑
  • MySQL自增ID主键空洞
  • 前端实现长整型排序
  • MySQL无感换表
  • Redis延时双删
  • 高并发秒杀优惠卷
  • AOP无侵入式告警
  • 长短链接跳转
  • 订单超时取消
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Tavio Zhang

努力学习的小码喽
首页
  • JVM底层原理
  • 邪恶多线程
  • MyBatis底层原理
  • Spring底层原理
  • MySQL的优化之路
  • ClickHouse的高性能
  • Redis的快速查询
  • RabbitMQ的生产
  • Kafka的高吞吐量
  • ES的入门到入坑
  • MySQL自增ID主键空洞
  • 前端实现长整型排序
  • MySQL无感换表
  • Redis延时双删
  • 高并发秒杀优惠卷
  • AOP无侵入式告警
  • 长短链接跳转
  • 订单超时取消
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • ES CRUD
  • ES分布式架构
  • ES ISR机制
  • ES深度分页查询优化
  • ES数据写入到查询
    • 一、数据写入:多阶段协同的可靠性保障
      • 1. 文档校验:数据入口的第一道关卡
      • 2. 分片路由:确定数据的"归宿"
      • 3. 写入缓冲区与Translog:临时存储与可靠性保障
      • 4. Refresh:让数据"可查询"
      • 5. Flush:数据永久化到磁盘
      • 6. 副本同步:数据冗余与高可用
    • 二、数据查询:快速定位目标文档的流程
      • 1. 请求分发:协调节点的"调度中心"角色
      • 2. 分片内匹配:倒排索引的高效检索
      • 3. 结果聚合:协调节点的"整合工作"
    • 三、总结:近实时与高可用的设计本质
  • ELK的底层逻辑
  • ES ILM
  • 《Elasticsearch》笔记
Tavio
2025-06-22
目录

ES数据写入到查询

在分布式搜索引擎领域,Elasticsearch(简称ES)以其近实时性、高吞吐量和分布式特性脱颖而出。

# 一、数据写入:多阶段协同的可靠性保障

ES的写入并非简单的"存盘"操作,而是一套包含校验、路由、缓冲、索引及持久化的复杂流程。其核心目标是:在保证高写入性能的同时,确保数据不丢失且最终可查询。

# 1. 文档校验:数据入口的第一道关卡

客户端发送的数据需先封装为JSON文档,并指定目标索引。ES接收请求后,首先执行文档校验,确保数据符合索引的映射规则(Mapping)。

  • 映射规则校验:索引的Mapping定义了字段类型(如price为double)、分词器(如name使用ik_max_word)等规则。若文档字段与Mapping冲突(例如price传入字符串"2aasfsa"),ES会直接返回错误。
  // 错误示例:price字段类型不匹配
  POST /goods/_doc/3
  {
    "name": "iphone13",
    "price": "2aasfsa"  // 错误:Mapping中price为double,此处为字符串
  }
  // 响应:400 Bad Request,提示类型不匹配
1
2
3
4
5
6
7
  • 动态映射(Dynamic Mapping):若文档包含Mapping中未定义的字段(如新增type: "phone"),ES会自动推断字段类型并添加到Mapping中(可通过dynamic参数控制此行为,如strict模式禁止动态添加)。
  // 动态映射示例:自动添加type字段
  POST /goods/_doc/2
  {
    "name": "iphone13",
    "price": 22,
    "type": "phone"  // Mapping中未定义,自动推断为text类型
  }
1
2
3
4
5
6
7

# 2. 分片路由:确定数据的"归宿"

ES是分布式架构,一个索引由多个主分片(Primary Shard)和副本分片(Replica Shard)组成。文档必须明确写入哪个主分片,这一过程通过路由算法实现:

shard = hash(routing) % number_of_primary_shards
1
  • 路由键(routing):默认使用文档ID(_id),也可手动指定(如按用户ID路由,确保同一用户数据落在同一分片,优化关联查询)。
  • 主分片数量(number_of_primary_shards):索引创建时指定,后续不可修改(需重建索引调整)。

示例:若goods索引有3个主分片,文档ID=1的hash(_id)=3,则3%3=0,文档将写入0号主分片。

# 3. 写入缓冲区与Translog:临时存储与可靠性保障

文档路由到目标主分片后,不会直接写入磁盘,而是先进入内存缓冲区(In-Memory Buffer),同时一条操作记录会被写入Translog(事务日志)。

  • 内存缓冲区:临时存储待索引文档,减少磁盘IO频率,提升写入速度。此时文档处于"不可查询"状态。
  • Translog:记录所有未持久化到磁盘的操作,是数据可靠性的核心保障。Translog默认实时刷写到磁盘(通过index.translog.durability控制,request模式确保请求返回前刷盘),即使节点宕机,重启后可通过Translog恢复缓冲区数据,避免丢失。

# 4. Refresh:让数据"可查询"

ES通过Refresh操作将内存缓冲区的数据转换为可查询状态,默认每1秒自动执行一次(可通过index.refresh_interval配置,如-1禁用自动刷新,适合批量写入场景)。

  • 过程:内存缓冲区的数据被写入Lucene分段(Segment) 并生成倒排索引(关键词到文档ID的映射,如iphone -> [2, 3, 12]),随后内存缓冲区清空。
  • 特性:分段生成后文档即可被查询(近实时性的核心),但此时分段仍存储在内存中,未持久化到磁盘。

# 5. Flush:数据永久化到磁盘

当Translog达到一定大小(默认512MB,可通过index.translog.flush_threshold_size调整)或间隔30分钟(可配置),ES会执行Flush操作,将内存中的分段永久写入磁盘:

  • 内存中的分段被刷写到磁盘(通过fsync确保物理写入)。
  • 清空Translog(已持久化的数据无需再记录)。

Flush操作可手动触发(POST /索引名/_flush),但频繁触发会影响性能,建议依赖自动机制。

# 6. 副本同步:数据冗余与高可用

主分片完成写入后,会将文档同步到其对应的副本分片(Replica Shard)。只有当主分片和所有副本分片都确认写入完成后,ES才会向客户端返回"成功"响应(可通过wait_for_active_shards控制等待的副本数量)。

  • 副本分片的作用:提供数据冗余(主分片故障时可升级为新主分片)、分担查询压力(查询请求可路由到副本)。

# 二、数据查询:快速定位目标文档的流程

ES的查询核心是从海量文档中快速匹配目标,流程可分为请求分发、分片内匹配、结果聚合三个阶段。

# 1. 请求分发:协调节点的"调度中心"角色

客户端的查询请求首先由协调节点(Coordinating Node) 接收,其核心任务是协调查询流程:

  • 解析查询语句(如name: iphone),确定目标索引。
  • 根据索引的分片分布(主分片+副本分片),选择参与查询的分片(默认采用轮询机制在主/副本间负载均衡)。
  • 将查询请求分发到选定的分片。

# 2. 分片内匹配:倒排索引的高效检索

被选中的分片接收到请求后,执行分片内查询:

  • 将ES查询语句转换为Lucene可执行的查询(如TermQuery)。
  • 遍历分片内的所有Lucene分段,利用倒排索引快速匹配包含目标关键词的文档ID。
  • 对匹配的文档进行相关性评分(基于TF/IDF、字段权重等算法),按评分排序后,返回前N条文档的ID和评分(不返回完整文档,减少数据传输量)。

# 3. 结果聚合:协调节点的"整合工作"

协调节点收集所有分片返回的(文档ID+评分)后,执行最终处理:

  • 对所有文档ID按评分重新排序,筛选出全局前N条(如分页查询中的from和size参数)。
  • 向对应的分片请求这些文档的完整数据(通过文档ID精准获取)。
  • 将完整文档整理为JSON格式,返回给客户端。

# 三、总结:近实时与高可用的设计本质

ES的写入与查询流程深刻体现了其设计哲学:

  • 近实时性:通过Refresh机制(1秒间隔)平衡写入性能与查询延迟,数据并非实时可见,但延迟可控。
  • 可靠性:Translog确保数据不丢失,副本分片提供冗余,Flush保障数据永久化。
  • 分布式效率:分片路由实现数据均匀分布,查询时分片并行处理+协调节点聚合,支撑海量数据的高效检索。
编辑 (opens new window)
#ES数据写入到查询
上次更新: 2026/01/21, 19:29:14
ES深度分页查询优化
ELK的底层逻辑

← ES深度分页查询优化 ELK的底层逻辑→

最近更新
01
订单超时取消
01-21
02
双 Token 登录
01-21
03
长短链接跳转
01-21
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式