ES索引的基础和进阶内容

简介: 本文详解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
相关文章
|
3月前
|
数据采集 JSON 自然语言处理
LLM 幻觉的架构级修复:推理参数、RAG、受约束解码与生成后验证
大型语言模型虽能力强,却易“自信撒谎”——即幻觉问题。本文系统拆解五层防御架构:1)推理参数调优(如低temperature+top_p);2)RAG、CoT、结构化输出等架构策略;3)生成后事实/引用/实体四重验证;4)领域微调与置信度校准;5)持续评估监控。强调幻觉不可根除,唯靠多层协同防御。
400 3
LLM 幻觉的架构级修复:推理参数、RAG、受约束解码与生成后验证
|
7月前
|
Java 应用服务中间件 数据库
Tomcat底层原理与实战全解析
本文全面解析Tomcat的底层原理与实战应用。作为轻量级JavaEE容器,Tomcat由HTTP服务器和Servlet容器组成,采用分层架构(Server→Service→Engine→Host→Context)。文章详细讲解请求处理流程、安装配置优化、Web应用部署方式,并提供SpringBoot+Tomcat的完整实战案例。针对生产环境,重点介绍性能优化策略(JVM调优、Connector配置)、故障排查工具(jstack、jmap)以及高可用方案(Nginx负载均衡+Redis会话共享)。
804 2
|
Linux iOS开发 索引
【已解决】ModuleNotFoundError: No module named ‘matplotlib‘
【已解决】ModuleNotFoundError: No module named ‘matplotlib‘
|
4月前
|
缓存 项目管理 开发工具
UV实战教程,我啥要从Anaconda切换到uv来管理包?
本文对比Anaconda“手动挡”与uv“全自动挡”环境管理:uv以“项目即环境”为核心,支持`uv init`一键初始化、自动下载Python、智能依赖管理(`uv add/sync/run`)及PyCharm无缝对接,大幅提升Python开发效率与协作体验。(239字)
1384 11
UV实战教程,我啥要从Anaconda切换到uv来管理包?
|
3月前
|
消息中间件 存储 Cloud Native
【消息队列MQ】主流消息队列MQ全方位对比:Kafka、RocketMQ、RabbitMQ、Pulsar
本文系统梳理Kafka、RocketMQ、RabbitMQ、Pulsar四大主流MQ的核心定位、架构差异、性能特性、运维生态及精准选型逻辑,覆盖从金融级可靠、高吞吐流处理到云原生多租户等全场景,助你构建结构化MQ知识体系,实现科学决策。
|
5月前
|
SQL 关系型数据库 MySQL
深入浅出:图解淘宝分布式数据库TDDL(及开源替代方案)
TDDL(淘宝分布式数据层)是阿里自研的数据库中间件,支持分库分表、读写分离与分布式事务,历经多年演进并开源。其核心通过SQL解析、智能路由、重写与结果聚合,透明化处理海量数据与高并发,兼容MySQL协议,助力系统线性扩展与高可用。(239字)
|
3月前
|
供应链 安全 iOS开发
OpenAI 发布重要安全公告:macOS 用户请注意!
OpenAI确认第三方库Axios遭行业性供应链攻击,但用户数据、系统及软件均未被入侵。为防范假冒应用,macOS用户需立即更新官方App至最新版,网页版、iOS、Windows不受影响。(239字)
196 7
|
3月前
|
人工智能 JSON Oracle
Oracle中各个c版本介绍
Oracle数据库“c”系列(Cloud)始于2013年12c,标志多租户架构革命。当前生产首选19c(长期稳定),学习与AI应用推荐23ai(原23c),支持向量搜索与JSON关系二元性;21c为短期创新版,12c/18c已停更。云原生演进清晰,稳中求新。(239字)
867 4
|
2月前
|
监控 关系型数据库 MySQL
【MySQL CPU飙升困扰】排查无从下手?掌握这套系统化性能调优方案,快速定位并解决性能瓶颈
日常运维中,MySQL CPU骤升至90%+令人焦头烂额?本文提供一套经生产验证的系统化排查方法论:从慢查询、锁竞争、参数配置到架构优化,精准定位根因,杜绝“重启救火”。240字
|
4月前
|
存储 监控 Java
炸穿 JVM 瓶颈!全网最硬核 JVM 核心参数・线上配置规范与调优 SOP
本文聚焦JDK17实战调优,直击90%线上JVM问题根源——参数配置不合理、内存规划错误、GC选型失当。详解堆内存、元空间、ZGC/G1、线程栈等核心参数,提供微服务/大数据/网关三类标准化配置SOP及可直接复用的监控代码与诊断方案。
574 1