Elasticsearch-00-总览

0. 摘要

项目目标

Elasticsearch 是一个分布式搜索和分析引擎,可扩展的数据存储和向量数据库,针对生产规模工作负载进行了速度和相关性优化。Elasticsearch 是 Elastic Stack 平台的基础。

核心能力

  • 近实时搜索: 对海量数据集进行近实时搜索
  • 向量搜索: 支持向量嵌入检索和语义搜索
  • 全文检索: 基于 Lucene 的强大全文检索能力
  • 分布式架构: 自动分片、副本和故障转移
  • 聚合分析: 复杂的数据聚合和分析能力
  • 可扩展性: 水平扩展,支持 PB 级数据

问题域

解决大规模数据的存储、索引、搜索和分析问题,支持:

  • 日志和指标分析
  • 应用性能监控(APM)
  • 安全日志分析
  • 检索增强生成(RAG)应用
  • 企业搜索

非目标

  • 不是 OLTP 数据库,不适合频繁更新的事务处理
  • 不是分布式文件存储系统
  • 不提供 ACID 事务保证(仅在单文档级别保证原子性)

运行环境

  • 语言: Java 21+
  • 运行时: JVM (OpenJDK/Oracle JDK)
  • 核心依赖: Apache Lucene 10.x
  • 构建系统: Gradle
  • 通信协议: HTTP/REST, TCP (节点间通信)

部署形态

  • 单节点模式: 用于开发和测试
  • 集群模式: 生产环境的分布式部署
  • 云服务: Elastic Cloud 托管服务
  • 插件扩展: 支持插件机制扩展功能

1. 整体架构图

flowchart TB
    subgraph Client["客户端层"]
        HTTP[HTTP/REST 客户端]
        TC[Transport Client]
        SDK[语言 SDK]
    end

    subgraph Gateway["网关层"]
        REST[REST API Handler]
        AUTH[认证/授权]
    end

    subgraph Coordination["协调层"]
        COORD[Coordinator<br/>集群协调器]
        MASTER[Master Service<br/>主节点服务]
        DISCO[Discovery<br/>节点发现]
    end

    subgraph Action["动作处理层"]
        AM[Action Module<br/>动作模块]
        TM[Task Manager<br/>任务管理器]
    end

    subgraph Core["核心业务层"]
        INDEX[Index Module<br/>索引模块]
        SEARCH[Search Module<br/>搜索模块]
        CLUSTER[Cluster Module<br/>集群管理模块]
        INGEST[Ingest Pipeline<br/>数据摄入管道]
    end

    subgraph Storage["存储引擎层"]
        ENGINE[Engine<br/>存储引擎]
        SHARD[Index Shard<br/>分片]
        LUCENE[Apache Lucene<br/>全文检索库]
        TRANSLOG[Translog<br/>事务日志]
    end

    subgraph Transport["传输层"]
        TS[Transport Service<br/>传输服务]
        TCP[TCP Transport]
        NETTY[Netty 网络框架]
    end

    subgraph Infra["基础设施层"]
        THREAD[Thread Pool<br/>线程池]
        BREAKER[Circuit Breaker<br/>熔断器]
        MONITOR[Monitor<br/>监控]
        GATEWAY[Gateway<br/>网关持久化]
    end

    HTTP --> REST
    TC --> TS
    SDK --> HTTP

    REST --> AUTH
    AUTH --> AM

    AM --> INDEX
    AM --> SEARCH
    AM --> CLUSTER
    AM --> INGEST

    COORD --> MASTER
    DISCO --> COORD
    CLUSTER --> COORD

    INDEX --> SHARD
    SEARCH --> SHARD
    SHARD --> ENGINE
    ENGINE --> LUCENE
    ENGINE --> TRANSLOG

    AM --> TM
    AM --> TS
    TS --> TCP
    TCP --> NETTY

    INDEX --> THREAD
    SEARCH --> THREAD
    ENGINE --> BREAKER
    COORD --> GATEWAY

    style Client fill:#e1f5ff
    style Gateway fill:#fff4e1
    style Coordination fill:#ffe1f5
    style Action fill:#f5e1ff
    style Core fill:#e1ffe1
    style Storage fill:#ffe1e1
    style Transport fill:#f5f5e1
    style Infra fill:#e1e1f5

架构图说明

组件职责

  1. 客户端层: 提供多种方式接入 Elasticsearch,包括 HTTP REST API、Transport 客户端和各语言 SDK
  2. 网关层: 处理 HTTP 请求,执行认证和授权,将请求路由到对应的处理器
  3. 协调层: 负责集群协调、主节点选举、节点发现和集群状态管理
  4. 动作处理层: 将客户端请求转换为内部动作,管理任务生命周期
  5. 核心业务层: 实现索引、搜索、集群管理、数据摄入等核心功能
  6. 存储引擎层: 基于 Lucene 的存储引擎,管理分片数据和事务日志
  7. 传输层: 节点间通信,使用 Netty 实现高性能 TCP 通信
  8. 基础设施层: 提供线程池、熔断器、监控等基础服务

数据流与控制流

  • 写入流程: Client → REST → Action → Index → Shard → Engine → Lucene + Translog
  • 搜索流程: Client → REST → Action → Search → Shard → Engine → Lucene
  • 集群管理流程: Coordinator → Master Service → Cluster State → Transport → All Nodes

耦合关系

  • 同步调用: REST API → Action Module → Core Modules
  • 异步事件: Cluster State Changes → Event Listeners
  • 发布订阅: Cluster State 通过 Transport 发布到所有节点

跨进程/跨线程路径

  • 跨节点通信: 通过 Transport Service 的 TCP 连接
  • 跨线程: 通过 ThreadPool 的不同线程池(search, index, generic, management等)
  • 线程隔离: 读写操作在不同线程池中执行,避免相互影响

高可用与扩展性

  • 无主架构: 任意节点都可以处理客户端请求
  • 主节点选举: 基于 Raft 协议的自动主节点选举
  • 数据分片: 索引自动分片,支持水平扩展
  • 副本机制: 每个分片可配置多个副本,保证高可用
  • 自动故障转移: 节点故障时自动重新分配分片

状态管理

  • 集群状态: 集中式的不可变集群元数据,由主节点管理
  • 本地状态: 每个节点维护本地分片状态
  • 持久化: 集群状态持久化到磁盘(Gateway)
  • 版本控制: 集群状态通过版本号确保一致性

2. 全局时序图

2.1 文档索引主流程

sequenceDiagram
    autonumber
    participant Client as 客户端
    participant REST as REST Handler
    participant Action as Action Module
    participant Primary as Primary Shard
    participant Replica as Replica Shard
    participant Engine as Storage Engine
    participant Lucene as Lucene Index
    participant Translog as Transaction Log

    Client->>REST: POST /index/_doc/id<br/>{document}
    REST->>REST: 解析请求,验证参数
    REST->>Action: IndexRequest

    Action->>Action: 路由计算<br/>hash(routing) % num_primary_shards
    Action->>Primary: 转发到主分片节点

    Primary->>Primary: 版本检查,序列号分配
    Primary->>Engine: index(doc, seqNo, version)

    Engine->>Engine: 获取 UID 锁
    Engine->>Engine: 版本冲突检测

    alt 新文档
        Engine->>Lucene: addDocument(doc)
    else 更新文档
        Engine->>Lucene: updateDocument(uid, doc)
    end

    Engine->>Translog: append(operation)
    Translog-->>Engine: fsync (可选)
    Engine-->>Primary: IndexResult

    par 并行复制到副本
        Primary->>Replica: ReplicationRequest<br/>(doc, seqNo, version)
        Replica->>Engine: index(doc, seqNo, version)
        Engine->>Lucene: addDocument/updateDocument
        Engine->>Translog: append(operation)
        Translog-->>Engine: fsync (可选)
        Engine-->>Replica: success
        Replica-->>Primary: ACK
    end

    Primary-->>Action: IndexResponse<br/>(result, version, seqNo)
    Action-->>REST: success
    REST-->>Client: 201 Created<br/>{_id, _version, result}

时序图说明

图意概述: 描述客户端索引一个文档到 Elasticsearch 的完整流程,从 HTTP 请求接收,到主分片写入,再到副本复制的全过程。

关键字段与载荷:

  • routing: 路由键,决定文档分配到哪个分片,默认为文档 ID
  • seqNo: 序列号,单调递增,用于副本同步和恢复
  • version: 文档版本号,用于乐观并发控制
  • primaryTerm: 主分片任期号,每次主分片变更递增

边界条件:

  1. 并发控制: 使用文档 UID 加锁,防止同一文档并发写入冲突
  2. 超时: 默认主分片操作超时 1 分钟,副本复制超时 1 分钟
  3. 幂等性: 通过 seqNo 保证副本应用操作的幂等性
  4. 顺序性: 相同文档的操作按 seqNo 顺序应用
  5. 一致性级别: 可配置需要多少副本确认才返回成功

异常路径与回退:

  • 版本冲突: 返回 409 Conflict,客户端需要重新获取最新版本
  • 主分片不可用: 等待主分片选举或失败返回 503
  • 副本失败: 主分片写入成功即可返回,副本异步重试或重新分配
  • 磁盘满: 返回 429 Too Many Requests,触发只读索引块
  • Translog 损坏: 分片进入失败状态,需要从副本恢复

性能与容量假设:

  • Translog Fsync: 默认每个请求 fsync,配置 async 可提升吞吐但降低可靠性
  • 批量索引: 使用 _bulk API 可以大幅提升吞吐(10x-100x)
  • 副本数量: 每增加一个副本,写入延迟增加约 30-50%
  • 刷新间隔: 默认 1s 刷新一次,文档可见有最多 1s 延迟
  • 吞吐量: 单节点约 5000-20000 docs/s,取决于硬件和文档复杂度

版本/兼容说明:

  • 序列号机制在 6.0 引入,替代旧的基于版本的复制
  • 8.0+ 移除 TransportClient,仅支持 REST API
  • Translog 格式向后兼容,支持滚动升级

2.2 搜索查询主流程

sequenceDiagram
    autonumber
    participant Client as 客户端
    participant REST as REST Handler
    participant Action as Action Module
    participant Coord as Coordinating Node
    participant Shard1 as Shard 1
    participant Shard2 as Shard 2
    participant Lucene as Lucene Searcher

    Client->>REST: POST /index/_search<br/>{query, size, from}
    REST->>Action: SearchRequest
    Action->>Coord: 协调节点处理

    Coord->>Coord: 计算需要查询的分片<br/>(主分片或副本)

    par Query Phase - 并行查询所有分片
        Coord->>Shard1: SearchShardRequest
        Shard1->>Lucene: search(query, size+from)
        Lucene-->>Shard1: TopDocs(docIds, scores)
        Shard1-->>Coord: QueryResult<br/>(docIds, scores, aggr)
    and
        Coord->>Shard2: SearchShardRequest
        Shard2->>Lucene: search(query, size+from)
        Lucene-->>Shard2: TopDocs(docIds, scores)
        Shard2-->>Coord: QueryResult<br/>(docIds, scores, aggr)
    end

    Coord->>Coord: 归并排序所有分片结果<br/>取 Top (size)
    Coord->>Coord: 确定需要获取的文档<br/>(shardId, docId)

    par Fetch Phase - 并行获取文档内容
        Coord->>Shard1: FetchRequest<br/>(docIds[])
        Shard1->>Lucene: document(docId)
        Lucene-->>Shard1: Document
        Shard1-->>Coord: FetchResult<br/>(documents[])
    and
        Coord->>Shard2: FetchRequest<br/>(docIds[])
        Shard2->>Lucene: document(docId)
        Lucene-->>Shard2: Document
        Shard2-->>Coord: FetchResult<br/>(documents[])
    end

    Coord->>Coord: 组装最终结果<br/>(hits, aggregations, took)
    Coord-->>Action: SearchResponse
    Action-->>REST: success
    REST-->>Client: 200 OK<br/>{hits[], total, took, aggs}

时序图说明

图意概述: 展示 Elasticsearch 搜索请求的两阶段执行过程:Query Phase(查询阶段)和 Fetch Phase(获取阶段),以及协调节点如何归并多分片结果。

关键字段与载荷:

  • query: 查询 DSL,支持 bool、match、term 等多种查询
  • size: 返回结果数量,默认 10
  • from: 分页起始位置,深度分页有性能问题
  • _source: 控制返回哪些字段
  • sort: 排序字段和顺序
  • aggs: 聚合定义

边界条件:

  1. 超时: 默认无超时,可通过 timeout 参数设置
  2. 最大结果窗口: 默认 from + size <= 10000,防止深度分页
  3. 并发控制: Query Phase 和 Fetch Phase 内部并发执行
  4. 分片选择: 使用自适应副本选择,选择最快的分片
  5. 请求缓存: Query 结果可缓存(仅 size=0 或聚合)

异常路径与回退:

  • 分片失败: 部分分片失败仍可返回结果,响应中包含失败信息
  • 超时: 返回已完成分片的结果,标记为部分结果
  • 熔断器触发: 内存不足时拒绝请求,返回 429
  • 查询过于复杂: Query Phase 超过内存限制,中断查询

性能与容量假设:

  • Query Phase: 轻量级,仅返回 docId 和 score,约占总耗时 30-40%
  • Fetch Phase: 需要读取文档内容,约占总耗时 60-70%
  • 深度分页: from=10000, size=10 需要每个分片返回 10010 个结果
  • 聚合: 内存占用高,基数聚合使用 HyperLogLog 近似算法
  • 并发度: 默认按分片数量并发,单节点可处理数百并发搜索

版本/兼容说明:

  • 7.0+ 默认使用自适应副本选择
  • 6.0+ 引入序列号,移除 _type
  • 5.0+ 引入 Query/Fetch 异步执行优化

2.3 集群状态变更主流程

sequenceDiagram
    autonumber
    participant Client as 管理客户端
    participant Master as Master Node
    participant Coord as Coordinator
    participant Cluster as Cluster Service
    participant Nodes as Data Nodes
    participant Gateway as Gateway

    Client->>Master: PUT /_cluster/settings<br/>{persistent: {...}}
    Master->>Cluster: ClusterStateUpdateTask

    Cluster->>Cluster: 加入队列<br/>(单线程执行)
    Cluster->>Cluster: execute(currentState)
    Cluster->>Cluster: 构建新的 ClusterState<br/>(version++)

    Cluster->>Gateway: persistMetaState(newState)
    Gateway->>Gateway: 写入磁盘<br/>(cluster metadata)
    Gateway-->>Cluster: success

    Cluster->>Coord: publish(newState)

    par 发布到所有节点
        Coord->>Nodes: PublishRequest<br/>(clusterState, version)
        Nodes->>Nodes: 验证版本号<br/>version > currentVersion
        Nodes->>Nodes: 应用新状态<br/>(原子替换)
        Nodes->>Nodes: 触发监听器<br/>(ClusterStateListener)
        Nodes-->>Coord: ACK
    end

    Coord->>Coord: 等待多数节点确认<br/>(quorum)

    opt 提交阶段
        Coord->>Nodes: Commit(version)
        Nodes->>Gateway: persistMetaState(newState)
        Nodes->>Nodes: 标记已提交
    end

    Coord-->>Cluster: PublishResponse
    Cluster-->>Master: ClusterStateUpdateResponse
    Master-->>Client: 200 OK<br/>{acknowledged: true}

时序图说明

图意概述: 展示 Elasticsearch 集群状态变更的完整流程,包括状态生成、持久化、发布和提交四个阶段,基于 Raft 协议保证一致性。

关键字段与载荷:

  • version: 集群状态版本号,单调递增
  • clusterUUID: 集群唯一标识
  • nodes: 集群节点列表
  • routingTable: 分片路由表
  • metadata: 索引元数据、设置、模板等
  • term: 主节点任期号

边界条件:

  1. 单线程执行: 集群状态更新在单线程中串行执行,保证顺序
  2. 超时: 发布超时默认 30s,提交超时默认 30s
  3. 多数确认: 需要多数主合格节点确认才算成功
  4. 版本检查: 拒绝旧版本状态,防止脑裂
  5. 幂等性: 相同版本的状态重复应用是幂等的

异常路径与回退:

  • 发布失败: 少数节点失败不影响,但会记录失败节点
  • 主节点故障: 新主节点选举后继续未完成的发布
  • 网络分区: 少数分区节点无法接收新状态,重新加入时同步
  • 版本冲突: 节点拒绝旧版本状态,主节点重新发布

性能与容量假设:

  • 状态大小: 通常 < 10MB,超大集群可能达到 100MB
  • 发布延迟: 小集群 < 100ms,大集群(100+节点)可达秒级
  • 更新频率: 建议 < 10次/s,过高会影响集群稳定性
  • 节点数量: 支持 1000+ 节点,但建议专用主节点
  • 分片数量: 单集群支持数十万分片

版本/兼容说明:

  • 7.0+ 使用 Raft-based 协调,移除旧的 Zen Discovery
  • 8.0+ 强制设置 cluster.initial_master_nodes
  • 滚动升级时兼容一个大版本差异

3. 模块边界与交互图

3.1 模块清单

Elasticsearch 核心代码模块按功能划分:

序号 模块名称 路径 职责 对外 API
01 Server 核心 server/ 核心服务器功能 Node, Bootstrap
02 客户端 client/ REST 和传输客户端 RestClient, TransportClient
03 索引模块 server/index/ 索引管理和文档操作 IndexService, IndexShard
04 搜索模块 server/search/ 搜索和聚合 SearchService, QueryPhase
05 集群模块 server/cluster/ 集群管理和协调 Coordinator, MasterService
06 传输层 server/transport/ 节点间通信 TransportService, TcpTransport
07 存储引擎 server/index/engine/ 数据存储引擎 InternalEngine, Translog
08 动作处理 server/action/ 请求动作处理 ActionModule, TransportAction
09 REST 层 server/rest/ HTTP REST API RestController, RestHandler
10 Gateway server/gateway/ 集群元数据持久化 Gateway, GatewayService
11 Ingest server/ingest/ 数据摄入管道 IngestService, Pipeline
12 脚本引擎 server/script/ 脚本执行 ScriptService, Painless
13 线程池 server/threadpool/ 线程池管理 ThreadPool, ExecutorBuilder
14 发现模块 server/discovery/ 节点发现 Discovery, PeerFinder
15 监控模块 server/monitor/ 系统监控 Monitor, JvmMonitor

3.2 模块交互矩阵

调用方 被调方 接口/方法 同步/异步 错误语义 一致性要求
REST Layer Action Module execute(request) 同步 返回异常
Action Module Transport Service sendRequest() 异步 回调 onFailure
Transport Service Index Module index/search/delete 异步 回调 onFailure 写入需确认
Index Module Storage Engine index(doc) 同步 抛出异常 强一致
Storage Engine Lucene addDocument() 同步 抛出异常 强一致
Storage Engine Translog add(operation) 同步 抛出异常 顺序写入
Search Module Storage Engine search(query) 同步 抛出异常 快照隔离
Coordinator Master Service submitStateUpdateTask() 异步 回调 onFailure 线性一致
Master Service Gateway persistMetaState() 同步 抛出异常 持久化
Master Service Transport Service publishClusterState() 异步 多数确认 多数一致
Cluster Module Index Module updateRouting() 事件 忽略异常 最终一致
Action Module Cluster Module clusterState() 同步读 读本地
Gateway Storage Engine 无直接调用 - - -

3.3 依赖关系图

flowchart TD
    REST[REST Layer] --> ACTION[Action Module]
    ACTION --> TRANSPORT[Transport Service]
    ACTION --> CLUSTER[Cluster Module]

    TRANSPORT --> TCP[TCP Transport]

    ACTION --> INDEX[Index Module]
    ACTION --> SEARCH[Search Module]

    INDEX --> SHARD[Index Shard]
    SEARCH --> SHARD

    SHARD --> ENGINE[Storage Engine]
    ENGINE --> LUCENE[Apache Lucene]
    ENGINE --> TRANSLOG[Translog]

    CLUSTER --> COORDINATOR[Coordinator]
    CLUSTER --> MASTER[Master Service]
    COORDINATOR --> TRANSPORT
    MASTER --> GATEWAY[Gateway]

    INDEX --> THREADPOOL[Thread Pool]
    SEARCH --> THREADPOOL
    TRANSPORT --> THREADPOOL

    ENGINE --> BREAKER[Circuit Breaker]
    SEARCH --> BREAKER

    style REST fill:#FFE4B5
    style ACTION fill:#98FB98
    style TRANSPORT fill:#87CEEB
    style INDEX fill:#DDA0DD
    style SEARCH fill:#F0E68C
    style CLUSTER fill:#FFA07A
    style ENGINE fill:#FF6347
    style LUCENE fill:#4682B4

4. 关键设计与权衡

4.1 数据一致性

分片内一致性(强一致)

  • 单文档操作: 通过版本号和 UID 锁保证单文档 ACID
  • Translog: 所有写操作先写 Translog,保证持久性
  • Flush: 定期将内存缓冲区刷新到磁盘,形成 Lucene segment

分片间一致性(主备模型)

  • 主分片写入: 写操作必须先在主分片成功
  • 副本复制: 主分片同步或异步复制到所有副本
  • 序列号机制: 全局单调递增的序列号,保证操作顺序
  • 全局检查点: 所有副本已确认的最大序列号

集群一致性(最终一致)

  • 集群状态: 基于 Raft 的主节点选举和状态复制
  • 发布-提交: 两阶段提交保证多数节点一致
  • 路由表: 路由表变更通过集群状态同步到所有节点

4.2 事务边界

  • 单文档: 单文档操作是原子的,通过 Lucene 的原子更新保证
  • 批量操作: _bulk API 中每个操作独立,部分失败不影响其他
  • 无跨文档事务: 不支持多文档 ACID 事务
  • 版本控制: 乐观并发控制,通过 versionif_seq_no + if_primary_term

4.3 锁与并发策略

乐观并发控制

  • 版本号: 每个文档有版本号,更新时检查版本
  • 序列号: 7.0+ 使用 seq_no + primary_term 替代版本号
  • CAS 操作: 条件更新,失败时返回冲突错误

分片级锁

  • UID 锁: 同一文档并发写入时获取 UID 锁
  • Refresh 锁: Refresh 操作获取读锁,不阻塞写入
  • Flush 锁: Flush 操作获取写锁,阻塞其他 Flush

集群级锁

  • 集群状态更新: 单线程串行执行,无锁竞争
  • 主节点选举: 通过 Raft 协议保证只有一个主节点

4.4 性能关键路径

写入路径

  1. 路由计算: O(1) hash 计算
  2. 版本检查: 内存查找(VersionMap),O(1)
  3. Lucene 写入: 解析文档,构建倒排索引,O(fields * terms)
  4. Translog: 顺序写入,O(1)
  5. 副本复制: 并行发送,延迟取决于最慢副本

优化手段:

  • 禁用 _source: 减少存储和网络传输
  • 增大 refresh_interval: 减少 Refresh 开销
  • 异步 Translog fsync: 提升吞吐,降低可靠性
  • 批量索引: 使用 _bulk API,减少网络往返

搜索路径

  1. 查询解析: 解析 Query DSL,O(query nodes)
  2. Query Phase: 每个分片独立执行查询,并行
  3. 归并排序: 协调节点归并所有分片结果,O(N log N)
  4. Fetch Phase: 并行获取文档,O(分片数)

优化手段:

  • 请求缓存: 缓存聚合结果和 size=0 的查询
  • 查询缓存: 缓存 Filter 查询结果
  • Fielddata 缓存: 缓存用于排序和聚合的字段值
  • Adaptive Replica Selection: 选择最快的副本

4.5 可观测性指标

集群级指标

  • Cluster Health: green/yellow/red
  • Active Shards: 活跃分片数
  • Relocating Shards: 正在迁移的分片数
  • Unassigned Shards: 未分配的分片数

节点级指标

  • JVM Heap: 堆内存使用率,建议 < 75%
  • GC Time: GC 时间,Young GC < 1s, Old GC 应避免
  • Thread Pool Queue: 线程池队列长度,队列满时拒绝请求
  • Circuit Breaker: 熔断器触发次数

索引级指标

  • Indexing Rate: 索引速率 (docs/s)
  • Search Rate: 搜索速率 (queries/s)
  • Search Latency: 搜索延迟 P50/P95/P99
  • Refresh Time: Refresh 耗时
  • Merge Time: Segment 合并耗时

分片级指标

  • Shard Size: 分片大小,建议 10-50GB
  • Segment Count: Segment 数量,过多影响搜索性能
  • Translog Size: Translog 大小,影响恢复时间

4.6 配置项

集群级配置

  • cluster.name: 集群名称,相同名称节点自动组成集群
  • cluster.initial_master_nodes: 初始主节点候选列表
  • discovery.seed_hosts: 种子节点列表

节点级配置

  • node.name: 节点名称
  • node.roles: 节点角色 [master, data, ingest, ml]
  • path.data: 数据目录
  • path.logs: 日志目录

索引级配置

  • number_of_shards: 主分片数,创建后不可修改
  • number_of_replicas: 副本数,可动态修改
  • refresh_interval: 刷新间隔,默认 1s
  • translog.durability: Translog 持久化策略,request/async

性能配置

  • indices.memory.index_buffer_size: 索引缓冲区,默认 10% heap
  • indices.queries.cache.size: 查询缓存,默认 10% heap
  • indices.fielddata.cache.size: Fielddata 缓存,默认不限制
  • thread_pool.write.queue_size: 写入线程池队列大小,默认 10000

5. 典型使用示例与最佳实践

5.1 最小可运行示例

单节点快速启动

# 下载并解压 Elasticsearch
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz
tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz
cd elasticsearch-8.11.0

# 配置单节点模式
cat > config/elasticsearch.yml <<EOF
cluster.name: my-cluster
node.name: node-1
network.host: 0.0.0.0
discovery.type: single-node
xpack.security.enabled: false
EOF

# 启动节点
./bin/elasticsearch

基础操作示例

# 创建索引
curl -X PUT "localhost:9200/products" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "price": { "type": "double" },
      "category": { "type": "keyword" },
      "created_at": { "type": "date" }
    }
  }
}'

# 索引文档
curl -X POST "localhost:9200/products/_doc" -H 'Content-Type: application/json' -d'
{
  "name": "Laptop",
  "price": 999.99,
  "category": "Electronics",
  "created_at": "2024-01-01T10:00:00Z"
}'

# 搜索文档
curl -X GET "localhost:9200/products/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match": {
      "name": "laptop"
    }
  }
}'

5.2 扩展点与插件接入

自定义分析器插件

Elasticsearch 支持通过插件扩展分析器、TokenFilter、CharFilter 等组件:

public class MyAnalysisPlugin extends Plugin implements AnalysisPlugin {

    @Override
    public Map<String, AnalysisProvider<TokenFilterFactory>> getTokenFilters() {
        return Collections.singletonMap("my_filter", MyTokenFilterFactory::new);
    }
}

public class MyTokenFilterFactory extends AbstractTokenFilterFactory {

    public MyTokenFilterFactory(IndexSettings indexSettings,
                                Environment environment,
                                String name,
                                Settings settings) {
        super(name, settings);
    }

    @Override
    public TokenStream create(TokenStream tokenStream) {
        return new MyTokenFilter(tokenStream);
    }
}

自定义聚合插件

public class MyAggregationPlugin extends Plugin implements SearchPlugin {

    @Override
    public List<AggregationSpec> getAggregations() {
        return Collections.singletonList(
            new AggregationSpec(
                "my_agg",
                MyAggregationBuilder::new,
                MyAggregationBuilder.PARSER
            ).addResultReader(InternalMyAggregation::new)
        );
    }
}

插件部署

# 安装插件
./bin/elasticsearch-plugin install file:///path/to/my-plugin.zip

# 验证插件
./bin/elasticsearch-plugin list

# 移除插件
./bin/elasticsearch-plugin remove my-plugin

5.3 生产环境配置清单

硬件配置建议

  • CPU: 16-32 核,搜索密集型需要更多核心
  • 内存: 64-128GB,JVM heap 设置为物理内存的 50%,不超过 32GB
  • 磁盘: SSD 必需,建议 NVMe,RAID 10 或 RAID 0
  • 网络: 10Gbps 网络,低延迟交换机

JVM 配置

# jvm.options
-Xms31g
-Xmx31g
-XX:+UseG1GC
-XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=30

操作系统配置

# 关闭 swap
sudo swapoff -a

# 增加文件描述符限制
ulimit -n 65535

# 增加虚拟内存区域
sysctl -w vm.max_map_count=262144

# 禁用 THP (Transparent Huge Pages)
echo never > /sys/kernel/mm/transparent_hugepage/enabled

集群配置

# elasticsearch.yml (生产环境三节点集群)
cluster.name: prod-cluster
node.name: ${HOSTNAME}
node.roles: [master, data, ingest]

# 网络配置
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300

# 发现配置
discovery.seed_hosts:
  - 10.0.0.1:9300
  - 10.0.0.2:9300
  - 10.0.0.3:9300
cluster.initial_master_nodes:
  - node-1
  - node-2
  - node-3

# 路径配置
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch

# 内存配置
indices.memory.index_buffer_size: 20%
indices.queries.cache.size: 15%

# 线程池配置
thread_pool.write.queue_size: 1000
thread_pool.search.queue_size: 2000

索引模板配置

{
  "index_patterns": ["logs-*"],
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "5s",
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
  },
  "mappings": {
    "properties": {
      "timestamp": {
        "type": "date"
      },
      "message": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      }
    }
  }
}

监控与告警

# 检查集群健康
curl -X GET "localhost:9200/_cluster/health?pretty"

# 检查节点统计
curl -X GET "localhost:9200/_nodes/stats?pretty"

# 检查索引统计
curl -X GET "localhost:9200/_stats?pretty"

# 检查慢查询日志
tail -f /var/log/elasticsearch/prod-cluster_index_search_slowlog.log

备份与恢复

# 配置快照仓库
curl -X PUT "localhost:9200/_snapshot/my_backup" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/mount/backups/elasticsearch"
  }
}'

# 创建快照
curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"

# 恢复快照
curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore"