elasticsearch
Elasticsearch 是一个开源的分布式 RESTful 搜索和分析引擎。
安装次数
点赞
应用评论
催更次数
桌面端


应用描述
Elasticsearch 是一个开源的分布式 RESTful 搜索和分析引擎。
相关攻略

使用 Elasticsearch Dump 工具进行生产环境到测试环境的数据迁移与备份
`es-dump` 是 Elasticsearch 的一个实用工具,专门用于从 Elasticsearch 集群中导出或导入数据,支持数据、映射、别名、模板等多种类型的数据操作。它在数据迁移、备份、恢复等场景中非常实用。本文将展示如何使用 `es-dump` 工具执行生产到测试环境的索引复制,以及备份数据到本地文件或云存储服务中。 https://appstore.lazycat.cloud/#/shop/detail/xu.deploy.elasticsearch ### 1. 复制索引从生产到测试环境 在某些情况下,我们需要将生产环境中的 Elasticsearch 索引迁移到测试环境。可以通过以下步骤将生产环境中的分析器、映射和数据导出并导入到测试环境中。 #### 导出并导入分析器: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=http://staging.es.com:9200/my_index \ --type=analyzer ``` #### 导出并导入映射: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=http://staging.es.com:9200/my_index \ --type=mapping ``` #### 导出并导入数据: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=http://staging.es.com:9200/my_index \ --type=data ``` 通过上述命令,你可以完整地将生产环境的 `my_index` 复制到测试环境的 `my_index` 中,包含索引的分析器、映射和数据。 ### 2. 备份索引到文件 在进行索引备份时,可以将索引的映射和数据导出到本地文件中,以便稍后进行恢复。 #### 备份索引映射到 JSON 文件: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=/data/my_index_mapping.json \ --type=mapping ``` #### 备份索引数据到 JSON 文件: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=/data/my_index.json \ --type=data ``` ### 3. 使用 `gzip` 压缩备份 如果索引数据量较大,建议通过压缩方式来备份数据。以下命令将数据备份到 `gzip` 压缩文件中: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=$ \ | gzip > /data/my_index.json.gz ``` ### 4. 查询数据备份 在某些情况下,你可能只需要备份符合特定查询条件的数据。可以使用 `searchBody` 参数来指定查询条件: #### 备份查询结果到文件: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=query.json \ --searchBody='{"query":{"term":{"username": "admin"}}}' ``` ### 5. 拆分备份文件 对于大规模索引,可以将数据拆分成多个部分进行备份。使用 `fileSize` 参数来限制每个文件的大小: ```bash elasticdump \ --input=http://production.es.com:9200/my_index \ --output=/data/my_index.json \ --fileSize=10mb ``` ### 6. 云存储上的导入导出 有时你可能需要将数据导入或导出到云存储(如 S3 或 Minio)中。`elasticdump` 也支持这种操作。 #### 从 S3 导入数据到 Elasticsearch: ```bash elasticdump \ --s3AccessKeyId "${access_key_id}" \ --s3SecretAccessKey "${access_key_secret}" \ --input "s3://${bucket_name}/${file_name}.json" \ --output=http://production.es.com:9200/my_index ``` #### 将数据从 Elasticsearch 导出到 S3: ```bash elasticdump \ --s3AccessKeyId "${access_key_id}" \ --s3SecretAccessKey "${access_key_secret}" \ --input=http://production.es.com:9200/my_index \ --output "s3://${bucket_name}/${file_name}.json" ``` ### 7. 使用 CSV 数据导入 Elasticsearch 你也可以将 CSV 文件中的数据导入到 Elasticsearch 中。以下命令展示了如何处理 CSV 文件的导入: ```bash elasticdump \ --input "csv:///data/cars.csv" \ --output=http://production.es.com:9200/my_index \ --csvSkipRows 1 \ --csvDelimiter ";" ``` 这里的 `--csvSkipRows` 参数用于跳过 CSV 文件中的指定行,`--csvDelimiter` 用于定义 CSV 文件的列分隔符。 `elasticdump` 提供了强大的导入导出功能,帮助用户轻松地进行数据备份、恢复、索引迁移等操作。无论是将索引从生产环境迁移到测试环境,还是将数据备份到本地文件或云存储中,`elasticdump` 都能为你提供灵活的解决方案。 通过合理使用这些功能,你可以显著提高 Elasticsearch 集群的维护和管理效率,确保数据的安全性与可用性。 

Elasticsearch 快速上手:让搜索变得简单有趣
## Elasticsearch 到底是啥? 简单来说,Elasticsearch(简称 ES)就是一个**超级强大的搜索引擎**。想象一下,你有几百万条数据,如果用传统数据库一条条找,可能要找到天荒地老。但用 ES,几毫秒就能搞定! 它就像是给你的数据装了个 Google 搜索引擎,不管是商品、日志、文章,还是用户信息,都能秒速查找。 ### 谁在用它? - **维基百科**:全球最大的百科全书,搜索功能全靠它 - **GitHub**:代码搜索就是用的 ES - **Stack Overflow**:程序员的救命稻草,问题搜索也是它 - **京东、淘宝**:商品搜索背后的技术支撑 - **滴滴、美团**:位置搜索、商家搜索都有它的身影 https://appstore.lazycat.cloud/#/shop/detail/xu.deploy.elasticsearch ## 如何使用? 截止到目前(2025 年 9 月 11 日 08:51:18),商店中的版本是一个单节点的服务,还没有集成看板功能,所以应用打开后,是这个页面:  上面是 Elasticsearch 服务启动后的欢迎页面,显示了当前节点和集群的状态、版本号(如 9.0.0)、集群名称(如 docker-cluster)等。这说明你的 Elasticsearch 实例已经运行,可以通过 API 进行数据操作和检索。 通过懒猫应用查看器,发现目前的验证是关闭的,不需要密码就能访问服务  ### 查询集群健康状态 打开终端,输入命令 `curl -X GET "https://elasticsearch.你的懒猫.heiyu.space/_cat/health?v"` 如果成功,你将看到类似如下的返回结果,显示集群的状态、节点数量等信息:  ### 查看所有索引 查看当前集群中所有的索引: `curl -X GET "https://elasticsearch.lanmao168.heiyu.space/_cat/indices?v" `  这将列出所有的索引,包括它们的名称、状态等信息。我目前还没有数据,所以都是空的。 用命令行看起来有点费劲,下面我用 postman 演示功能。注意lanmao168 是我的微服,需要你改成自己的。 ## 1. 创建索引 ### 请求方法: * **PUT** ### 请求 URL: ``` https://elasticsearch.lanmao168.heiyu.space/products ``` ### 请求体(Body): ```json {} ``` ### 说明: * 这里我们使用 `PUT` 请求创建一个名为 `products` 的索引。 * 请求体为空 `{}` 即可创建索引。 ### 操作步骤: 1. 打开 Postman,选择 `PUT` 方法。 2. 在 URL 栏中输入 `https://elasticsearch.lanmao168.heiyu.space/products`。 3. 选择 `Body`,并选择 `raw` 格式。 4. 在 `raw` 中选择 `JSON` 格式,内容写 `{}`。 5. 点击 `Send` 按钮发送请求。  如果索引创建成功,你会看到返回类似以下内容: ```json { "acknowledged": true, "shards_acknowledged": true, "index": "products" } ``` --- ## 2. 添加文档 ### 请求方法: * **POST** ### 请求 URL: ``` https://elasticsearch.lanmao168.heiyu.space/products/_doc/1 ``` ### 请求体(Body): ```json { "name": "Smartphone", "brand": "BrandX", "price": 699.99, "category": "Electronics" } ``` ### 说明: * 这里我们使用 `POST` 请求向 `products` 索引中添加一条文档。 * 文档 ID 是 `1`,内容是关于一款名为 `Smartphone` 的产品。 ### 操作步骤: 1. 在 Postman 中,选择 `POST` 方法。 2. 在 URL 栏中输入 `https://elasticsearch.lanmao168.heiyu.space/products/_doc/1`。 3. 选择 `Body`,并选择 `raw` 格式。 4. 在 `raw` 中选择 `JSON` 格式,填入上面的文档内容。 5. 点击 `Send` 按钮发送请求。  如果文档添加成功,你会看到类似以下的返回: ```json { "_index": "products", "_id": "1\n", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 0, "_primary_term": 1 } ``` --- ## 3. 查询文档 ### 请求方法: * **GET** ### 请求 URL: ``` https://elasticsearch.lanmao168.heiyu.space/products/_search ``` ### 请求参数(Params): ```text q=name:Smartphone ``` ### 说明: * 这里我们使用 `GET` 请求来查询 `products` 索引中所有 `name` 字段为 `Smartphone` 的文档。 ### 操作步骤: 1. 在 Postman 中,选择 `GET` 方法。 2. 在 URL 栏中输入 `https://elasticsearch.lanmao168.heiyu.space/products/_search`。 3. 在 `Params` 标签下添加一个参数: * **Key**: `q` * **Value**: `name:Smartphone` 4. 点击 `Send` 按钮发送请求。  返回的结果类似如下: ```json { "took": 283, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.2876821, "hits": [ { "_index": "products", "_id": "1\n", "_score": 0.2876821, "_source": { "name": "Smartphone", "brand": "BrandX", "price": 699.99, "category": "Electronics" } } ] } } ``` --- ## 4. 更新文档 ### 请求方法: * **PUT** ### 请求 URL: ``` https://elasticsearch.lanmao168.heiyu.space/products/_doc/1 ``` ### 请求体(Body): ```json { "doc": { "price": 799.99 } } ``` ### 说明: * 这里我们使用 `PUT` 请求来更新文档 ID 为 `1` 的 `price` 字段。 ### 操作步骤: 1. 在 Postman 中,选择 `PUT` 方法。 2. 在 URL 栏中输入 `https://elasticsearch.lanmao168.heiyu.space/products/_doc/1/_update`。 3. 选择 `Body`,并选择 `raw` 格式。 4. 在 `raw` 中选择 `JSON` 格式,填入需要更新的数据。 5. 点击 `Send` 按钮发送请求。  如果更新成功,你会看到返回的 JSON: ```json { "_index": "products", "_id": "1", "_version": 1, "result": "created", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 1, "_primary_term": 1 } ``` --- ## 5. 删除文档 ### 请求方法: * **DELETE** ### 请求 URL: ``` https://elasticsearch.lanmao168.heiyu.space/products/_doc/1 ``` ### 说明: * 使用 `DELETE` 方法删除 `products` 索引中 ID 为 `1` 的文档。 ### 操作步骤: 1. 在 Postman 中,选择 `DELETE` 方法。 2. 在 URL 栏中输入 `https://elasticsearch.lanmao168.heiyu.space/products/_doc/1`。 3. 点击 `Send` 按钮发送请求。  删除成功后,返回的响应如下: ```json { "_index": "products", "_id": "1", "_version": 3, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 } ``` --- ## 总结 Elasticsearch 不是银弹,但在搜索和日志分析场景下,它确实是个利器。不管你是要做商品搜索、日志分析,还是实时监控,ES 都能帮你轻松搞定。 先用单机版本熟悉功能,有需要再扩展集群,掌握了 ES 的核心概念和使用技巧,你就能在数据的海洋中游刃有余。 ## 相关资源 📚 - [Elasticsearch 官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html) - [GitHub 仓库](https://github.com/elastic/elasticsearch) - [中文社区](https://elasticsearch.cn/) - [Kibana 在线演示](https://demo.elastic.co/)

Elasticsearch第3章:架构原理
# https://appstore.lazycat.cloud/#/shop/detail/xu.deploy.elasticsearch > 本章导读:本章将深入介绍 Elasticsearch 的架构设计,包括集群架构、节点类型、数据存储原理等,帮助读者理解 ES 的内部工作机制。 ## 目录 - [前置知识](#前置知识) - [集群架构概览](#集群架构概览) - [节点类型详解](#节点类型详解) - [数据存储原理](#数据存储原理) - [分布式架构](#分布式架构) - [本章小结](#本章小结) - [参考资料](#参考资料) ## 集群架构概览 ### 整体架构图 ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ 客户端请求 │ │ (REST API / Transport Protocol) │ └─────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Elasticsearch 集群 │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ 协调层 (Coordinating) │ │ │ │ 接收请求 → 路由到分片 → 聚合结果 → 返回响应 │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌──────────────────────────┼──────────────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Master │ │ Data │ │ Ingest │ │ │ │ Node │ │ Node │ │ Node │ │ │ │ │ │ │ │ │ │ │ │ • 集群状态 │ │ • 数据存储 │ │ • 数据预处理│ │ │ │ • 索引管理 │ │ • 搜索执行 │ │ • Pipeline │ │ │ │ • 分片分配 │ │ • 聚合计算 │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ 存储层 (Lucene) │ │ │ │ 倒排索引 / Doc Values / 段文件 │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 架构组件说明 | 组件 | 职责 | |------|------| | 协调层 | 接收客户端请求,路由到正确的分片,聚合各分片结果 | | Master 节点 | 管理集群元数据,处理索引创建/删除,分片分配决策 | | Data 节点 | 存储数据,执行数据相关操作(CRUD、搜索、聚合) | | Ingest 节点 | 执行 Ingest Pipeline,在索引前预处理文档 | | 存储层 | 基于 Lucene 的底层存储,管理倒排索引和段文件 | ## 节点类型详解 ### Master 节点 Master 节点负责集群级别的管理操作: **职责**: - 维护集群状态(Cluster State) - 创建和删除索引 - 分片分配和重平衡决策 - 节点加入和离开处理 **配置**: ```yaml # elasticsearch.yml node.roles: [master] ``` **最佳实践**: - 生产环境至少 3 个 Master-eligible 节点 - 专用 Master 节点不存储数据,资源需求较低 - 配置 `cluster.initial_master_nodes` 防止脑裂 ```yaml # 专用 Master 节点配置 node.roles: [master] cluster.initial_master_nodes: ["master-1", "master-2", "master-3"] ``` ### Data 节点 Data 节点负责数据存储和处理: **职责**: - 存储分片数据 - 执行 CRUD 操作 - 执行搜索和聚合 **配置**: ```yaml # elasticsearch.yml node.roles: [data] ``` **数据节点分层**(8.x 新特性): | 角色 | 说明 | 适用数据 | |------|------|----------| | `data_hot` | 热数据节点 | 最新、频繁访问的数据 | | `data_warm` | 温数据节点 | 较少访问的历史数据 | | `data_cold` | 冷数据节点 | 很少访问的归档数据 | | `data_frozen` | 冻结数据节点 | 极少访问,可搜索快照 | | `data_content` | 内容数据节点 | 非时序数据 | ```yaml # 热数据节点配置 node.roles: [data_hot] # 温数据节点配置 node.roles: [data_warm] ``` ### Coordinating 节点 协调节点(也称为客户端节点)专门处理请求路由: **职责**: - 接收客户端请求 - 将请求路由到相关分片 - 聚合各分片返回的结果 - 返回最终结果给客户端 **配置**: ```yaml # 专用协调节点(不设置任何角色) node.roles: [] ``` **工作流程**: ``` 客户端请求 │ ▼ ┌─────────────────┐ │ Coordinating │ │ Node │ └────────┬────────┘ │ 路由请求 ┌────┴────┬────────┐ ▼ ▼ ▼ ┌───────┐ ┌───────┐ ┌───────┐ │Shard 0│ │Shard 1│ │Shard 2│ └───┬───┘ └───┬───┘ └───┬───┘ │ │ │ └────┬────┴────────┘ │ 聚合结果 ▼ ┌─────────────────┐ │ Coordinating │ │ Node │ └────────┬────────┘ │ ▼ 客户端响应 ``` ### Ingest 节点 Ingest 节点在文档索引前执行预处理: **职责**: - 执行 Ingest Pipeline - 数据转换和丰富 - 字段提取和格式化 **配置**: ```yaml # elasticsearch.yml node.roles: [ingest] ``` **Pipeline 示例**: ```json PUT _ingest/pipeline/my-pipeline { "description": "处理日志数据", "processors": [ { "grok": { "field": "message", "patterns": ["%{IP:client_ip} - %{DATA:user} \\[%{HTTPDATE:timestamp}\\]"] } }, { "date": { "field": "timestamp", "formats": ["dd/MMM/yyyy:HH:mm:ss Z"] } }, { "geoip": { "field": "client_ip" } } ] } ``` ### ML 节点 机器学习节点执行 ML 任务: **职责**: - 异常检测作业 - 预测分析 - 数据帧分析 **配置**: ```yaml # elasticsearch.yml node.roles: [ml] xpack.ml.enabled: true ``` ### 节点角色组合建议 **小型集群(开发/测试)**: ```yaml # 所有节点都是全角色 node.roles: [master, data, ingest] ``` **中型集群**: ``` ┌─────────────────────────────────────────────────────────┐ │ 3 x Master/Data 节点 │ │ node.roles: [master, data, ingest] │ └─────────────────────────────────────────────────────────┘ ``` **大型集群**: ``` ┌─────────────────────────────────────────────────────────┐ │ 3 x 专用 Master 节点 │ │ node.roles: [master] │ ├─────────────────────────────────────────────────────────┤ │ N x 专用 Data 节点 │ │ node.roles: [data_hot] / [data_warm] / [data_cold] │ ├─────────────────────────────────────────────────────────┤ │ 2+ x 协调节点 │ │ node.roles: [] │ ├─────────────────────────────────────────────────────────┤ │ 2+ x Ingest 节点 │ │ node.roles: [ingest] │ └─────────────────────────────────────────────────────────┘ ``` ## 数据存储原理 ### Lucene 基础 Elasticsearch 底层使用 Apache Lucene 作为搜索引擎库。每个分片本质上是一个 Lucene 索引。 ``` ┌─────────────────────────────────────────────────────────┐ │ Elasticsearch 分片 │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Lucene Index │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │Segment 0│ │Segment 1│ │Segment 2│ ... │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ### 倒排索引(Inverted Index) 倒排索引是全文搜索的核心数据结构: **正向索引 vs 倒排索引**: ``` 正向索引(文档 → 词项): ┌─────────┬────────────────────────────┐ │ Doc ID │ Content │ ├─────────┼────────────────────────────┤ │ 1 │ "Elasticsearch is fast" │ │ 2 │ "Elasticsearch is scalable"│ │ 3 │ "Lucene is fast" │ └─────────┴────────────────────────────┘ 倒排索引(词项 → 文档): ┌───────────────┬─────────────────────────┐ │ Term │ Posting List │ ├───────────────┼─────────────────────────┤ │ elasticsearch │ [1, 2] │ │ fast │ [1, 3] │ │ is │ [1, 2, 3] │ │ lucene │ [3] │ │ scalable │ [2] │ └───────────────┴─────────────────────────┘ ``` **倒排索引结构**: ``` ┌─────────────────────────────────────────────────────────┐ │ 倒排索引 │ ├─────────────────────────────────────────────────────────┤ │ Term Dictionary (词项字典) │ │ ┌─────────────────────────────────────────────────┐ │ │ │ elasticsearch → offset: 0 │ │ │ │ fast → offset: 100 │ │ │ │ scalable → offset: 200 │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ Posting List (倒排列表) │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Doc IDs: [1, 2] │ │ │ │ Term Frequency: [1, 1] │ │ │ │ Positions: [[0], [0]] │ │ │ │ Offsets: [[0-13], [0-13]] │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ### Doc Values Doc Values 是列式存储,用于排序、聚合和脚本访问: ``` 倒排索引(搜索用): Doc Values(聚合/排序用): Term → Doc IDs Doc ID → Field Value "apple" → [1, 3] 1 → "apple" "banana" → [2] 2 → "banana" "cherry" → [4] 3 → "apple" 4 → "cherry" ``` **Doc Values vs Fielddata**: | 特性 | Doc Values | Fielddata | |------|------------|-----------| | 存储位置 | 磁盘 | 内存 | | 构建时机 | 索引时 | 查询时 | | 适用类型 | keyword, numeric, date, ip, geo | text | | 内存占用 | 低 | 高 | | 默认状态 | 启用 | 禁用 | ```json // 禁用 Doc Values(节省磁盘,但无法排序/聚合) PUT /my-index { "mappings": { "properties": { "description": { "type": "keyword", "doc_values": false } } } } ``` ### 段(Segment) 段是 Lucene 索引的基本单位,是不可变的: **段的生命周期**: ``` 1. 文档写入内存缓冲区 ┌─────────────────┐ │ Memory Buffer │ ← 新文档 └─────────────────┘ 2. Refresh:内存缓冲区 → 新段(可搜索) ┌─────────────────┐ │ Segment 0 │ ← 可搜索 └─────────────────┘ 3. 更多文档写入,创建更多段 ┌─────────┐ ┌─────────┐ ┌─────────┐ │Segment 0│ │Segment 1│ │Segment 2│ └─────────┘ └─────────┘ └─────────┘ 4. Merge:多个小段合并为大段 ┌─────────────────────────────────┐ │ Merged Segment │ └─────────────────────────────────┘ ``` **段合并(Merge)**: ```json // 强制合并(谨慎使用,资源消耗大) POST /my-index/_forcemerge?max_num_segments=1 ``` ### _source 字段 `_source` 存储文档的原始 JSON: ```json // 禁用 _source(节省存储,但无法更新/reindex) PUT /my-index { "mappings": { "_source": { "enabled": false } } } // 部分存储 PUT /my-index { "mappings": { "_source": { "includes": ["title", "date"], "excludes": ["content"] } } } ``` ### 存储结构总结 ``` ┌─────────────────────────────────────────────────────────────────┐ │ Lucene Segment │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Inverted Index │ │ Doc Values │ │ _source │ │ │ │ │ │ │ │ │ │ │ │ • Term Dict │ │ • 列式存储 │ │ • 原始 JSON │ │ │ │ • Posting List │ │ • 排序/聚合用 │ │ • 更新/高亮用 │ │ │ │ • 全文搜索用 │ │ │ │ │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Stored Fields │ │ Term Vectors │ │ Norms │ │ │ │ │ │ │ │ │ │ │ │ • 存储的字段值 │ │ • 词项位置信息 │ │ • 字段长度归一化│ │ │ │ │ │ • 高亮/MLT 用 │ │ • 评分用 │ │ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ## 分布式架构 ### 文档路由 文档通过路由算法分配到特定分片: ``` shard_num = hash(routing) % number_of_primary_shards ``` 默认 `routing` 值为文档 `_id`。 ```json // 自定义路由 PUT /products/_doc/1?routing=user123 { "name": "Product A", "user_id": "user123" } // 查询时指定路由(提高效率) GET /products/_search?routing=user123 { "query": { "match": { "user_id": "user123" } } } ``` ### 写入流程 ``` 1. 客户端发送写入请求到协调节点 2. 协调节点根据路由计算目标主分片 3. 请求转发到主分片所在节点 4. 主分片执行写入 5. 主分片并行复制到所有副本分片 6. 所有副本确认后,返回成功响应 ┌────────┐ ┌─────────────┐ ┌─────────────┐ │ Client │────>│ Coordinating│────>│ Primary │ └────────┘ │ Node │ │ Shard │ └─────────────┘ └──────┬──────┘ │ ┌───────────┼───────────┐ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ │Replica │ │Replica │ │Replica │ │ 1 │ │ 2 │ │ 3 │ └────────┘ └────────┘ └────────┘ ``` ### 搜索流程 搜索分为两个阶段:Query Phase 和 Fetch Phase。 **Query Phase**: ``` 1. 协调节点将请求发送到所有相关分片 2. 每个分片执行本地搜索,返回匹配文档的 ID 和排序值 3. 协调节点合并结果,确定最终的 Top N 文档 ┌────────┐ ┌─────────────┐ │ Client │────>│ Coordinating│ └────────┘ │ Node │ └──────┬──────┘ │ Query ┌────────────┼────────────┐ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Shard 0 │ │ Shard 1 │ │ Shard 2 │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └────────────┼────────────┘ │ Doc IDs + Scores ▼ ┌─────────────┐ │ Coordinating│ │ Node │ └─────────────┘ ``` **Fetch Phase**: ``` 1. 协调节点向包含目标文档的分片发送 Fetch 请求 2. 分片返回完整文档内容 3. 协调节点组装最终结果返回客户端 ┌─────────────┐ │ Coordinating│ │ Node │ └──────┬──────┘ │ Fetch (Doc IDs) ┌────────────┼────────────┐ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Shard 0 │ │ Shard 1 │ │ Shard 2 │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └────────────┼────────────┘ │ Full Documents ▼ ┌─────────────┐ │ Coordinating│──────> Client │ Node │ └─────────────┘ ``` ### 集群状态管理 集群状态(Cluster State)包含: - 节点信息 - 索引元数据 - 分片分配信息 - 映射定义 - 集群设置 ```json // 查看集群状态 GET /_cluster/state // 查看集群状态大小 GET /_cluster/state?filter_path=metadata.indices.*.state ``` ### 主节点选举 Elasticsearch 使用基于 Raft 的选举算法(7.0+): ``` ┌─────────────────────────────────────────────────────────┐ │ 主节点选举流程 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 1. 节点启动,进入候选状态 │ │ 2. 候选节点向其他节点请求投票 │ │ 3. 获得多数票的节点成为主节点 │ │ 4. 主节点定期发送心跳 │ │ 5. 主节点失联,重新选举 │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ │ │(Master) │◄───│ │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ ▲ ▲ │ │ │ 心跳 │ │ │ │ └──────────────┴──────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ ``` **防止脑裂**: ```yaml # 配置初始主节点(仅首次启动时需要) cluster.initial_master_nodes: ["node-1", "node-2", "node-3"] ``` ## 本章小结 本章深入介绍了 Elasticsearch 的架构原理: 1. **集群架构**:由协调层、Master 节点、Data 节点、Ingest 节点等组成 2. **节点类型**: - Master:管理集群状态和元数据 - Data:存储数据,执行搜索和聚合 - Coordinating:路由请求,聚合结果 - Ingest:数据预处理 - ML:机器学习任务 3. **数据存储**: - 倒排索引:全文搜索的核心 - Doc Values:排序和聚合的列式存储 - 段:不可变的 Lucene 索引单元 4. **分布式机制**: - 文档路由:hash(routing) % shards - 写入流程:主分片写入 → 副本复制 - 搜索流程:Query Phase → Fetch Phase 理解这些架构原理有助于更好地设计和优化 Elasticsearch 应用。 ## 参考资料 - [Elasticsearch 集群架构](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html) - [节点角色](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html) - [Lucene 倒排索引](https://lucene.apache.org/core/) - [分布式搜索执行](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-shard-routing.html) 
懒猫评分/评论
0.0
0 条评论
新功能
版本历史记录ES 单节点,后续上 kibana 和多节点
此 App 尚未收到足够的评分或评论,无法显示评论列表。