ES索引的基础和进阶内容

本文涉及的产品
RDSClaw,2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 本文详解Elasticsearch索引创建与优化:涵盖默认、自定义配置及模板三种创建方式;深入分片/副本数选型策略(建议分片10–50GB);详述reindex全流程(含切片加速、限速、监控与安全删除);解析object/nested/wildcard等核心字段类型差异;并介绍动态/显式映射、索引模板与别名等进阶实践。(239字)

创建索引的方式

三种创建索引的方式

方式 说明 适用场景
默认创建 kibana里面直接运行 PUT /my_index,ES 会使用默认配置,并启用动态映射自动识别字段类型。 测试、快速原型开发。
自定义配置创建 创建索引时,在请求体中明确指定 settings(分片、副本等)和 mappings(字段类型、分析器等)。 生产环境,需要对性能和数据类型精细控制。
使用模板创建 预先定义好 index_patterns(如 logs-*),当创建匹配模式的索引时,模板配置会自动应用。 数据量很大(如日志、事件数据),需要自动管理大量索引。

例如,在kibana 的dev tools运行命令

PUT /product_info
{
   
  "settings": {
   
    "number_of_shards": 3,    // 设置主分片数,设置后不能修改,除非reindex,需提前规划
    "number_of_replicas": 2   // 设置副本数,用于提高数据可用性和查询吞吐量,可动态调整
  },
  "mappings": {
   
    "properties": {
   
      "product_id": {
   
        "type": "keyword"     // 关键词类型,用于精确匹配
      },
      "name": {
   
        "type": "text",       // 文本类型,用于全文搜索
        "fields": {
   
          "keyword": {
           // 为 name 字段增加一个子字段
            "type": "keyword",
            "ignore_above": 256  // 如果字符串的长度 超过当前设定的值,那么该字符串不会被索引,也不会被存储到倒排索引中
          }
        }
      },
      "price": {
   
        "type": "double"      // 双精度浮点数
      },
      "in_stock": {
   
        "type": "boolean"     // 布尔类型
      },
      "created_date": {
   
        "type": "date",       // 日期类型
        "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
      }
    }
  }
}

索引参数优化

主分片数 number_of_shards 值的选择。
首先,分片的大小建议为 10GB ~ 50GB。分片太多(如每个分片只有几百 MB)会产生管理开销;分片太大(如 >100GB)会导致故障恢复慢。
分片数应 ≥ 节点数,才能充分利用所有节点的计算资源。例如有 3 个数据节点,分片数可以设为 3 或 6 等。
shard_count = max(节点数, ceil(预估总数据量 / 30GB))

副本数 number_of_replicas 值的选择。
副本是主分片的完整拷贝,用于高可用扩展查询吞吐。但是每个副本都会消耗和主分片一样多的磁盘。副本数越多,存储成本线性增加。
动态调整 PUT /index/_settings
至少 1 个副本(即副本数 ≥ 1)才能容忍一个节点宕机而不丢数据。
如果读请求远多于写请求,增加副本数可以让查询分散到更多分片上,减轻主分片压力。
测试环境为0或1,生产环境至少为1,通常1或2即可。

索引参数优化示例

计算示例
假如,数据量为500 GB,集群有五个数据节点,每个节点磁盘2TB。

500GB / 30GB ≈ 17个分片。选择节点数的倍数,15或者20都可以。
副本数1。
总分片数 = 15(主分片) (1 + 1(副本数)) = 15 2 = 30
最终每个节点承担6个分片,包括5主1副本。

reindex操作

reindex 是将一个索引(或跨多个索引)中的数据复制到另一个索引(或数据流)的操作。常用于:

  • 修改映射(如字段类型错误需要重建)。
  • 更改分片数(number_of_shards 不可直接修改,必须 reindex 到新索引)。
  • 升级索引版本(如从 6.x 到 7.x 需要重新索引)。
  • 合并或过滤数据。

例如下面的命令是将老索引的数据复制到新索引

POST _reindex
{
   
  "source": {
   
    "index": "old_index"
  },
  "dest": {
   
    "index": "new_index"
  }
}
reindex参数调优

一些可以调优的参数

  • slcies:任务拆分成多个并行子任务,每个子任务处理一部分数据,大幅加速迁移
    • auto:自动确定切片数,小数据量
    • 手动指定正整数N,大数据量,N = 主分片数(1~2倍)
    • 不设置,单线程执行,相当于1
      POST _reindex
      {
             
      "source": {
              "index": "big_logs" },
      "dest": {
              "index": "big_logs_new" },
      "slices": 6   // 分成6个并行子任务
      }
      
  • requests_per_second:限制 reindex 每秒处理的文档操作数(包括索引、更新、删除),避免过度消耗集群资源。
      • 正整数:每秒不超过该数目。
    • -1 或省略:不限速。
    • 0:暂停任务(恢复时设为正数)。
      一开始的时候指定值
      POST _reindex
      {
             
      "source": {
              "index": "old" },
      "dest": {
              "index": "new" },
      "requests_per_second": 1000   // 每秒最多 1000 个文档
      }
      
      后续打算修改值(动态调整),task_id 可以从 GET _tasks 获得。
      POST _reindex/<task_id>/_rethrottle
      {
             
      "requests_per_second": 500
      }
      
监控所有reindex任务

查询所有正在运行(或最近完成)的 reindex 任务,可以监控进度、限速状态、错误等。

GET _tasks?detailed=true&actions=*reindex

一些需要关注的字段及其含义。

字段 含义
action 任务类型,如 indices:data/write/reindex
status.total 需要处理的总文档数(如果源索引能提前获取)。
status.created 已经成功创建的文档数(目标索引新增)。
status.updated 已经更新的文档数(覆盖写入)。
status.version_conflicts 版本冲突数(例如目标索引已存在同 _id 文档且未覆盖)。
status.retries.bulk 批次写入失败重试次数。
status.throttled_millis 该任务因限速而主动等待的总毫秒数。
requests_per_second 当前设定的限速值。
running_time_in_nanos 任务已经运行的纳秒数。
  • GET _tasks/<task_id> – 查看特定任务。
  • POST _tasks/<task_id>/_cancel – 取消一个正在运行的 reindex。
reindex之后删除老索引

reindex不会删除老索引,要想删除老索引,使用下面的语句,最好确认后删除

DELETE /old_index
如何判断reindex成功

先比较文档数,看是否一样,这一步之后还是需要检查id的,数量一样并不能完全确认成功

GET /old_index/_count
GET /new_index/_count

查看 _id,scroll只返回 _id,不返回 _source

GET /old_index/_search?scroll=1m&filter_path=hits.hits._id
{
   
  "size": 1000,
  "_source": false
}
reindex的影响(重要)
影响维度 说明
集群资源消耗 reindex 会占用大量 CPU内存磁盘 I/O,尤其在数据量大时。
写入压力 目标索引的写入速度可能影响其他正常写入操作。建议在低峰期执行。
源索引性能 reindex 使用滚动搜索(scroll)读取源索引,可能增加源索引的堆内存压力。
外部查询 源索引和目标索引在 reindex 期间均可正常查询(但目标索引数据不完整时可能返回部分结果)。
操作可中断/恢复 reindex 支持 _rethrottle 调整速率,也支持 task API 取消任务。如果中途失败,已写入的数据不会回滚,建议使用 op_type: create 避免重复。

索引数据结构(type)

除了以上type,还有其他的type,
例如:ip(用于存储和管理 IPv4 或 IPv6 地址)、geo_point (专门存储经纬度,用于地理位置相关的搜索和分析)、object (JSON 对象的默认映射方式。索引时会被“扁平化”处理。如果你的对象是一个数组且内部元素需要保持独立性,建议使用 nested 类型)、wildcard类型(7.9版本引入,专门用于高效通配符/正则表达式匹配

object与nested

object扁平化处理示例

这是原先的

{
   
  "users": [
    {
   "name": "Alice", "age": 25},
    {
   "name": "Bob",   "age": 30}
  ]
}

默认object数组会变成

users.name = ["Alice", "Bob"]
users.age  = [25, 30]

对应的数据失去了关联
例如查询 users.name=Alice AND users.age=30 会错误地匹配到该文档(因为两个条件分别从不同对象中取值)。

nested类型:将数组中的每个对象独立索引为一个 隐藏的嵌套文档,保持对象内部的关联性。

"users": {
   
  "type": "nested",
  "properties": {
   
    "name": {
    "type": "text" },
    "age":  {
    "type": "integer" }
  }
}

注意,查询时必须使用 nested 查询

{
   
  "nested": {
   
    "path": "users",
    "query": {
   
      "bool": {
   
        "must": [
          {
    "match": {
    "users.name": "Alice" } },
          {
    "term":  {
    "users.age":  25 } }
        ]
      }
    }
  }
}

这个存储类型,也不是万能的。适合用于每个对象独立、需要同时关联多个字段条件的情况(如商品规格列表、订单明细等场景)。

  • ✅ 保留了对象内字段的逻辑独立性,避免“跨对象匹配”。
  • ❌ 存储和查询开销更大(每个嵌套对象单独存储,join 成本高)。
  • ❌ 写入性能有一定损耗。
wildcard

定义方式

{
   
  "mappings": {
   
    "properties": {
   
      "path": {
   
        "type": "wildcard"
      }
    }
  }
}
  • 需要频繁使用 * 前缀、后缀或中间通配符的字段,如 URL 路径、文件路径、用户输入的模糊搜索词。

注意:wildcard 不适合完全精确匹配(用 keyword 更高效),也不适合全文搜索(用 text)。

查询示例

{
   
  "query": {
   
    "wildcard": {
   
      "path": {
   
        "value": "*/user/*/profile*"
      }
    }
  }
}

比 keyword 占用更多空间,因为需要存储自动机结构。

索引映射方式

es索引的映射方式有两种,分为动态和显式两种方式。

  • 动态映射 (Dynamic Mapping):当索引一个包含新字段的文档时,ES 会自动推测并添加字段映射。适合快速迭代,但在生产环境中过度依赖可能导致类型错误,建议仅在开发测试环境使用或谨慎开启。
  • 显式映射 (Explicit Mapping):即上面代码的内容,在创建索引时手动定义清楚所有字段属性。虽然工作量稍大,但能带来数据类型精确、搜索性能可控、避免意外字段的好处,是生产环境的推荐做法。

索引进阶用法

索引模板

这里的是 7.8+ 版本的 可组合索引模板
API 端点为 _index_template,例如 PUT _index_template/my_template

当你想要按天、按月动态生成的索引(如日志数据),手动逐个创建显然太麻烦,这时候可以用索引模板(Index Templates) 来批量自动管理。

PUT _index_template/order_logs_template   // 模板名称,自定义
{
   
  "index_patterns": ["order-logs-*"],     // 索引模式,匹配的索引会自动应用此模板
  "priority": 200,                         // 模板优先级,数字越大优先级越高
  "template": {
                               // 具体配置,和普通索引一样
    "settings": {
   
      "number_of_shards": 1,
      "number_of_replicas": 1
    },
    "mappings": {
   
      "properties": {
   
        "timestamp": {
    "type": "date" },
        "message": {
    "type": "text" }
      }
    }
  }
}

配置好之后,如果你创建了 order-logs-2024-01-01 这个索引,它会自动应用上述配置,非常方便。

索引别名

索引别名(Index Alias) 像一个指向真实索引的指针,可以实现应用程序与底层索引的解耦。例如在数据迁移时,可以通过原子操作切换别名,实现服务的无缝过渡。

POST /_aliases
{
   
  "actions": [
    {
    "remove": {
    "index": "logs_v1", "alias": "app_logs" } },
    {
    "add": {
       "index": "logs_v2", "alias": "app_logs" } }
  ]
}

和索引相关的常用命令

  • *查询索引配置 :GET /product_info
  • *查询索引字段映射:GET /product_info/_mapping
  • *查询索引状态:GET /_cat/indices/product_info?v
相关文章
|
5天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
2374 16
|
23天前
|
人工智能 数据可视化 安全
王炸组合!阿里云 OpenClaw X 飞书 CLI,开启 Agent 基建狂潮!(附带免费使用6个月服务器)
本文详解如何用阿里云Lighthouse一键部署OpenClaw,结合飞书CLI等工具,让AI真正“动手”——自动群发、生成科研日报、整理知识库。核心理念:未来软件应为AI而生,CLI即AI的“手脚”,实现高效、安全、可控的智能自动化。
34940 57
王炸组合!阿里云 OpenClaw X 飞书 CLI,开启 Agent 基建狂潮!(附带免费使用6个月服务器)
|
17天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
15766 46
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
|
13天前
|
人工智能 JavaScript Ubuntu
低成本搭建AIP自动化写作系统:Hermes保姆级使用教程,长文和逐步实操贴图
我带着怀疑的态度,深度使用了几天,聚焦微信公众号AIP自动化写作场景,写出来的几篇文章,几乎没有什么修改,至少合乎我本人的意愿,而且排版风格,也越来越完善,同样是起码过得了我自己这一关。 这个其实OpenClaw早可以实现了,但是目前我觉得最大的区别是,Hermes会自主总结提炼,并更新你的写作技能。 相信就冲这一点,就值得一试。 这篇帖子主要就Hermes部署使用,作一个非常详细的介绍,几乎一步一贴图。 关于Hermes,无论你赞成哪种声音,我希望都是你自己动手行动过,发自内心的选择!
3031 29
|
2天前
|
云安全 人工智能 安全
|
2天前
|
人工智能 测试技术 API
阿里Qwen3.6-27B正式开源:网友直呼“太牛了”!
阿里云千问3.6系列重磅开源Qwen3.6-27B稠密大模型!官网:https://t.aliyun.com/U/JbblVp 仅270亿参数,编程能力媲美千亿模型,在SWE-bench等权威基准中表现卓越。支持多模态理解、本地部署及OpenClaw等智能体集成,已开放Hugging Face与ModelScope下载。
|
1天前
|
机器学习/深度学习 缓存 测试技术
DeepSeek-V4开源:百万上下文,Agent能力比肩顶级闭源模型
DeepSeek-V4正式开源!含V4-Pro(1.6T参数)与V4-Flash(284B参数)双版本,均支持百万token上下文。首创混合注意力架构,Agent能力、世界知识与推理性能全面领先开源模型,数学/代码评测比肩顶级闭源模型。
1242 6