ES索引的基础和进阶内容

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
云数据库 PolarDB MySQL 版,列存表分析加速 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
相关文章
|
Linux iOS开发 索引
【已解决】ModuleNotFoundError: No module named ‘matplotlib‘
【已解决】ModuleNotFoundError: No module named ‘matplotlib‘
|
1月前
|
人工智能 JSON Oracle
Oracle中各个c版本介绍
Oracle数据库“c”系列(Cloud)始于2013年12c,标志多租户架构革命。当前生产首选19c(长期稳定),学习与AI应用推荐23ai(原23c),支持向量搜索与JSON关系二元性;21c为短期创新版,12c/18c已停更。云原生演进清晰,稳中求新。(239字)
425 4
|
5月前
|
存储 弹性计算 网络协议
5 分钟构建企业级域控:AD DS 一键部署与实战指南
Active Directory 域服务(AD DS)不仅是企业级身份管理的基石,更是您实现**集中认证、策略统管、安全高效**IT架构的核心引擎。
|
5月前
|
Java 应用服务中间件 数据库
Tomcat底层原理与实战全解析
本文全面解析Tomcat的底层原理与实战应用。作为轻量级JavaEE容器,Tomcat由HTTP服务器和Servlet容器组成,采用分层架构(Server→Service→Engine→Host→Context)。文章详细讲解请求处理流程、安装配置优化、Web应用部署方式,并提供SpringBoot+Tomcat的完整实战案例。针对生产环境,重点介绍性能优化策略(JVM调优、Connector配置)、故障排查工具(jstack、jmap)以及高可用方案(Nginx负载均衡+Redis会话共享)。
709 2
|
运维 Oracle 关系型数据库
YashanDB演讲实录|王南:YAC集群,核心平替
本文分享了“2024国产数据库创新生态大会”上,深算院首席产品官兼崖山科技副总裁王南的演讲实录,主题为《YAC集群,核心平替》。文章深入探讨了数据库行业面临的规模化应用挑战,提出崖山数据库在核心技术、团队实力和商业化能力上的优势。崖山通过YashanDB V23版本,正式发布共享集群LTS版本、Oracle 99%兼容、MySQL生态支持、私有云管平台及数据库一体机等创新成果,提供高性价比的平替方案。同时,崖山全面开放V23版本下载,携手200多家生态伙伴加速商业落地,助力国产数据库迈向大规模应用新时代。
|
人工智能 编解码 虚拟化
See3D:智源研究院开源的无标注视频学习 3D 生成模型
See3D 是智源研究院推出的无标注视频学习 3D 生成模型,能够从大规模无标注的互联网视频中学习 3D 先验,实现从视频中生成 3D 内容。See3D 采用视觉条件技术,支持从文本、单视图和稀疏视图到 3D 的生成,并能进行 3D 编辑与高斯渲染。
731 13
See3D:智源研究院开源的无标注视频学习 3D 生成模型
|
12月前
|
存储 人工智能 关系型数据库
向量数据库和嵌入模型
本文介绍了向量数据库和嵌入模型的概念及应用,重点探讨了两者在AI技术栈中的协作关系。向量数据库是一种用于存储高维向量数据的解决方案,支持相似性搜索而非传统的关系型数据库精确匹配。文中通过实例展示了如何使用阿里百炼的文本嵌入模型(text-embedding-v3)将文本向量化,并结合Qdrant向量数据库进行存储与检索。代码示例部分详细说明了从文本嵌入到向量存储及查询的完整流程,为开发者提供了实践参考。
1961 15
向量数据库和嵌入模型
|
前端开发 数据安全/隐私保护
crypto-js中AES的加解密封装
文章介绍了如何在前端使用crypto-js库进行AES加密和解密,提供了加解密的函数封装示例,并演示了如何加密和解密字符串或对象。
1603 2
crypto-js中AES的加解密封装
|
消息中间件 供应链 测试技术
图解 DDD,这一篇总结太全面了!
DDD领取驱动是非常热的架构设计,微服务也有大量涉及,本文详细解析领域驱动设计(DDD),涵盖DDD原理、实践步骤及核心概念等,帮助更好地管理复杂业务逻辑。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
图解 DDD,这一篇总结太全面了!
|
存储 缓存 监控
优化 Elasticsearch
优化 Elasticsearch
318 1