Elasticsearch 索引(Index)详解

Elasticsearch 索引(Index) 是数据组织与管理的核心单元,类似于关系型数据库中的“数据库”或“表”。理解索引的结构、配置、生命周期和最佳实践,是掌握 Elasticsearch 的关键。

本文将全面详解 Elasticsearch 索引的概念、组成、配置项、操作方式及高级用法。


一、什么是索引(Index)?

在 Elasticsearch 中,索引(Index) 是一个逻辑命名空间,用于存储具有相似特征的文档集合。它是数据写入、搜索、聚合和管理的基本单位。

类比关系型数据库:

Elasticsearch关系型数据库(如 MySQL)
IndexTable / Database
DocumentRow
FieldColumn
MappingSchema

📌 注意:Elasticsearch 的“索引”更接近于“表”的概念,但功能更强大。


二、索引的核心组成

一个完整的索引由以下几个部分构成:

组成部分说明
Settings配置分片数、副本数、分析器等
Mappings定义字段类型、是否分词、是否索引等
Documents实际存储的数据(JSON 文档)
Shards & Replicas物理存储结构,支持水平扩展和高可用

三、索引的基本操作(CRUD)

1. 创建索引(Create)

最简创建:
PUT /my-index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title": { "type": "text" },
      "status": { "type": "keyword" },
      "created_at": { "type": "date" }
    }
  }
}

⚠️ 索引名必须小写,不能包含特殊字符(_- 可用)。


2. 查看索引信息

GET /my-index

返回:

{
  "my-index": {
    "aliases": {},
    "mappings": { ... },
    "settings": { ... }
  }
}

查看所有索引:

GET /_cat/indices?v

3. 删除索引

DELETE /my-index

⚠️ 删除不可恢复,请谨慎操作。


4. 打开/关闭索引

关闭索引可节省资源(内存),但仍保留数据:

POST /my-index/_close
POST /my-index/_open

四、索引 Settings 详解

settings 控制索引的物理行为和性能。

常见配置项:

参数说明默认值
number_of_shards主分片数量(创建后不可改)1
number_of_replicas每个主分片的副本数1
refresh_interval刷新频率(控制近实时搜索)1s
index.codec存储压缩方式default(可设为 best_compression
analysis.analyzer自定义分析器见下文
示例:高写入场景优化
"settings": {
  "number_of_shards": 5,
  "number_of_replicas": 1,
  "refresh_interval": "30s",
  "translog.durability": "async",
  "translog.sync_interval": "30s"
}

提示:写入密集型应用可降低刷新频率以提升吞吐。


五、索引 Mappings 详解

mappings 定义字段的结构和行为,决定如何索引和搜索。

1. 核心字段类型

类型用途是否分词
text全文搜索(会分词)
keyword精确匹配、聚合、排序
date日期类型-
long, integer, short, byte整数
double, float浮点数
boolean布尔值
object嵌套 JSON 对象
nested独立索引的嵌套对象
ipIP 地址
geo_point地理位置坐标

2. 动态映射 vs 静态映射

  • 动态映射(Dynamic Mapping)
    自动推断字段类型(如字符串 → text + keyword)。

  • 静态映射(Explicit Mapping)
    手动定义字段类型,避免类型冲突。

"mappings": {
  "dynamic": false,  // 禁用动态映射
  "properties": {
    "email": { "type": "keyword" },
    "content": { "type": "text", "analyzer": "ik_smart" }
  }
}

建议生产环境关闭 dynamic 或设为 strict(拒绝未知字段)。


3. 自定义分析器(Analyzer)

用于控制 text 字段的分词方式。

示例:使用 IK 中文分词
PUT /news
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ik_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "my_ik_analyzer"
      }
    }
  }
}

常用中文分词插件:ikjiebaanalysis-smartcn


六、分片(Shards)与副本(Replicas)

1. 主分片(Primary Shard)

  • 数据被分割成多个主分片,分布在不同节点上。
  • number_of_shards 在创建时设定,不可更改
  • 建议:根据数据量预估(如每 shard 30GB 左右)。

2. 副本分片(Replica Shard)

  • 每个主分片可有多个副本,用于:
    • 高可用(主分片故障时切换)
    • 提升查询吞吐(负载均衡)
"settings": {
  "number_of_shards": 3,
  "number_of_replicas": 2  // 每个主分片有 2 个副本
}

总分片数 = 主分片 × (1 + 副本数) = 3 × 3 = 9


3. 分片设计建议

  • 单个分片建议 10GB ~ 50GB
  • 集群节点数 ≥ 主分片数,以便均匀分布。
  • 避免“过小分片”(影响性能)或“过大分片”(恢复慢)。

七、索引别名(Aliases)

别名 是指向一个或多个索引的逻辑名称,用于:

  • 无缝切换索引(如滚动更新)
  • 实现读写分离
  • 联合多个索引查询

示例:读写别名

# 创建索引
PUT /logs-2024-04-01

# 添加别名
POST /_aliases
{
  "actions": [
    { "add": { "index": "logs-2024-04-01", "alias": "logs-write" } },
    { "add": { "index": "logs-2024-04-01", "alias": "logs-read" } }
  ]
}

# 写入
POST /logs-write/_doc { ... }

# 查询
GET /logs-read/_search { ... }

滚动更新(Rollover)场景

PUT /logs-000001
{
  "aliases": {
    "logs-write": {
      "is_write_index": true
    },
    "logs-read": {}
  }
}

# 当满足条件时滚动到新索引
POST /logs-write/_rollover
{
  "conditions": {
    "max_age": "1d",
    "max_docs": 1000000
  }
}

八、索引模板(Index Templates)

用于自动应用 settings 和 mappings 到匹配名称的索引。

1. Legacy Template(旧版)

PUT /_template/template_logs
{
  "index_patterns": ["logs-*"],
  "settings": {
    "number_of_shards": 3
  },
  "mappings": {
    "properties": {
      "host": { "type": "keyword" }
    }
  }
}

2. Composable Template(7.8+ 推荐)

支持多模板组合:

# 组件模板:定义 mappings
PUT /_component_template/logs-mapping
{
  "template": {
    "mappings": {
      "properties": {
        "message": { "type": "text" }
      }
    }
  }
}

# 组合模板
PUT /_index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3
    },
    "composed_of": ["logs-mapping"]
  }
}

九、索引生命周期管理(ILM)

ILM(Index Lifecycle Management) 自动管理索引从创建到删除的全过程。

四个阶段:

  1. Hot:活跃写入,高资源。
  2. Warm:不再写入,只读,降低副本、禁用刷新。
  3. Cold:极少访问,迁移到低性能节点。
  4. Delete:过期删除。

示例策略:

PUT /_ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_size": "50gb", "max_age": "30d" }
        }
      },
      "warm": {
        "min_age": "30d",
        "actions": {
          "forcemerge": { "max_num_segments": 1 },
          "shrink": { "number_of_shards": 1 }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": { "delete": {} }
      }
    }
  }
}

应用到模板:

"template": {
  "settings": {
    "index.lifecycle.name": "logs-policy"
  }
}

十、高级特性与最佳实践

1. 数据分区策略

  • 时间序列索引logs-2024-04-01,便于按时间管理。
  • 按业务分索引usersordersproducts
  • 避免单一超大索引

2. 性能优化建议

  • 合理设置 refresh_interval
  • 使用 keyword 替代 text 做聚合。
  • 控制字段数量(避免“宽表”)。
  • 启用 doc_values(默认开启,用于排序聚合)。

3. 安全与权限

  • 使用 Index Patterns + Roles 控制用户访问。
  • 敏感字段加密(需应用层或使用 Field Masking)。

十一、常见问题

Q1:如何修改已创建索引的分片数?

不能直接修改
✅ 解决方案:使用 reindex 创建新索引并迁移数据。

POST /_reindex
{
  "source": { "index": "old-index" },
  "dest": { "index": "new-index" }
}

Q2:索引可以跨集群吗?

不能直接跨集群,但可通过 Cross-Cluster Search 查询远程集群的索引。

Q3:如何监控索引状态?

GET /my-index/_stats          # 统计信息
GET /my-index/_recovery       # 恢复状态
GET /_cat/shards/my-index?v   # 分片分布

十二、总结

特性说明
Index数据逻辑容器
Settings控制分片、副本、刷新等
Mappings定义字段结构与行为
Shards水平扩展的基础
Aliases实现灵活路由
Templates自动化索引配置
ILM自动化生命周期管理

十三、最佳实践清单 ✅

  • 使用时间序列命名(如 logs-%Y-%m-%d
  • 配置 ILM 实现自动 rollover 和删除
  • 使用别名实现读写分离
  • 关闭 dynamic 或设为 strict
  • 合理设置分片数(每分片 10~50GB)
  • 中文字段使用 ik 分词器
  • 高频聚合字段使用 keyword

📌 扩展学习建议

  • 索引模板 + ILM + Rollover 联合使用(日志系统标准架构)
  • Hot-Warm-Cold 架构设计
  • 使用 Kibana Stack Management 管理索引
  • 监控索引的 segment 数量、merge 压力
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值