ElasticSearch深入解析(八):索引设置、索引别名、索引模板

一、索引的动态设置、静态设置

  • 索引设置包含两部分核心内容:
    • 静态设置(static index settings),只允许在创建索引时或者针对已关闭的索引进行设置。
    • 指动态设置(dynamic index settings),可以借助更新设置(update settings)的方式进行动态更新,更新后立即生效。

1. 静态设置

静态设置实战场景举例如下:
设置主分片大小的参数是index.number_of_shards,只在创建索引时生效,不支持动态修改。

默认主分片大小为1,且每个索引的分片数量上限默认为1024。此限制是一个安全限制,可防止索引分片数过多导致集群不稳定。

如果在业务层面扩充节点后确实需要扩展主分片数,该怎么办?
答案:在非业务核心时间通过reindex操作迁移实现。​

2. 动态设置

动态设置的实战场景举例如下:

  • 设置副本数参数为index.number_of_replicas,可以动态修改:
PUT news_index/_settings
{"number_of_replicas":3
}
  • 设置刷新频率参数为index.refresh_interval,可以动态修改:
PUT news_index/_settings
{"refresh_interval":"1s"
}

默认刷新频率参数值为1s,即每秒刷新一次。这1s决定了Elasticsearch是近实时的搜索引擎,而非准实时搜索引擎。如果业务层面对实时性的要求不高,可以考虑将该值调大。因为如果采用1s,则每秒都会生成一个新的分段(关于分段的概念可以参考最后一章),会影响写入性能。

  • max_result_window是Elasticsearch中的一个设置参数,用于控制搜索结果的最大窗口的大小:

默认情况下,max_result_window的值为10000,这意味着在分页搜索时最多可以返回10000条数据。如果每页可显示10条数据,那么最多可以翻到1000页。在某些情况下,可能需要处理比默认值更大的数据集。

在这种情况下,可以通过更新索引设置来动态修改max_result_window的值:

PUT news_index/_settings
{"max_result_window":50000
}

上述命令将max_result_window的值设置为50000。此时如果每页显示10条数据,则可以最多翻到5000页。

增大max_result_window的值可能会对Elasticsearch集群的性能产生影响,尤其是在处理大量数据时。因此,在根据实际需求调整此参数时,要权衡性能和查询范围之间的关系。如果需要遍历大量数据,则建议使用scroll API或search_after参数,以更高效地进行处理。

在 Elasticsearch 中,max_result_window参数(默认值为 10000)主要限制的是基于from + size的深度分页查询(即通过from指定偏移量,size指定每页大小)。这种查询方式在偏移量(from)较大时,会导致 Elasticsearch 在每个分片上生成大量中间结果并合并,消耗大量内存和 CPU,甚至引发 OOM(内存溢出)。
而 scroll API 和 search_after 这两种分页方式,设计上避免了max_result_window的直接限制。

二、索引别名

  • 索引别名常见的使用场景:
    • 当需要定期创建新索引(如日志按天 / 月分割),同时保持应用端无需感知索引名称变化时,通过别名指向 “当前有效索引”,实现无缝切换。
    • 索引重建或结构升级:旧索引 users_v1 需升级到 users_v2(如新增字段、调整映射),先通过别名 users 指向 users_v1,应用正常访问,重建完成后,通过原子操作切换别名指向 users_v2,实现无感知迁移。

索引别名只是物理索引的软链接的名称而已,一个索引可以创建多个别名,一个别名也可以指向多个索引。

实战中,很多工程师在开发中后期才发现索引别名的妙处。正如前文所说,别名能进行高效的索引管理,能进行索引数据修改或更新操作并确保用户无感知。

  • 示例场景
    线上索引 users_v1 需要新增一个分词器为 ik_max_word 的字段 address,但直接修改映射会导致集群分片重建,且旧数据无法应用新分词器(需重建索引)。

  • 传统方案(无别名)的痛点

  1. 重建新索引 users_v2 并迁移数据,需修改所有客户端代码/配置中的索引名,易遗漏导致线上故障;
  2. 切换期间需停机或双写,用户体验差。
  • 别名实现无感知升级(步骤)
  1. 创建新索引并绑定临时别名

    PUT /users_v2
    {"mappings": {"properties": {"address": { "type": "text", "analyzer": "ik_max_word" }}}
    }
    POST /_aliases
    {"actions": [{ "add": { "index": "users_v2", "alias": "users_tmp" } }]
    }
    
    • 开发/测试环境通过 users_tmp 验证新索引逻辑,不影响线上 users_v1
  2. 生产环境双写验证

    • 应用端同时写入 users_v1users_v2(通过别名解耦,代码无需硬编码索引名),
    • 读取时通过别名 users 暂指向 users_v1,确保线上流量无影响。
  3. 原子切换别名指向

    POST /_aliases
    {"actions": [{ "remove": { "index": "users_v1", "alias": "users" } },{ "add": { "index": "users_v2", "alias": "users" } }// 可同时删除旧索引(需确保数据迁移完成)]
    }
    
    • 切换瞬间完成,客户端无感知,无需重启服务或修改配置。
  • 核心价值
  • 风险隔离:通过临时别名 users_tmp 验证新索引,避免直接操作线上索引;
  • 零停机迁移:利用别名的原子操作,实现“热切换”,用户请求始终路由到有效索引。
  1. 从别名检索:

在 Elasticsearch 中,检索时使用索引别名与使用真实索引名的操作完全一致,别名会被透明解析为实际指向的索引(单个或多个)。

# 简单查询
GET /my_alias/_search
{"query": { "match_all": {} }
}# 带过滤的查询
GET /my_alias/_search
{"query": { "term": { "status": "active" } }
}

若别名指向多个索引(如 logs_2025_q1 指向 logs-2025-01、logs-2025-02、logs-2025-03),检索时会同时查询所有关联索引:

GET /logs_2025_q1/_search
{"query": { "range": { "timestamp": { "gte": "2025-01-01" } } }
}

等价于 GET /logs-2025-01,logs-2025-02,logs-2025-03/_search,但别名简化了索引列表的维护。

别名支持通配符模式(如 logs-*),检索时自动匹配所有符合模式的索引:

# 创建别名匹配2025年4月的所有日志索引
POST /_aliases
{"actions": [{ "add": { "index": "logs-2025-04*", "alias": "april_logs" } }]
}
# 检索时使用别名
GET /april_logs/_search
{ "query": { "term": { "service": "user-center" } } }

避免在 DSL 中硬编码索引模式(如 logs-2025-04*),通过别名统一管理匹配规则。

三、索引模板

  • 两个常见的业务场景问题:
    • 问题1:数据量非常大,需要进行索引生命周期管理,具体要按日期划分索引,且要求多个索引的Mapping一致,而每次手动创建或者脚本创建都很麻烦,怎么办?
    • 问题2:实际业务中应用了多个索引,想让这些索引中相同名字的字段类型完全一致,以便实现跨索引检索,怎么办?

我们会发现传统方式不能解决多索引的快速定义和高效管理等问题。因此,索引模板应运而生。

1. 索引模板的定义

Elasticsearch 7.8及之后版本支持两种定义模板的方式,可简记为普通模板定义方式组件模板新增/创建方式

  • 普通模板定义方式如下所示:
PUT _index_template/<template_name>  # 模板名称(唯一)
{"index_patterns": ["logs-*", "metrics-*"],  # 匹配的索引名模式(支持通配符)"priority": 100,                            # 模板优先级(高优先级覆盖低优先级)"template": {                               # 新索引的配置内容"settings": {                             # 索引设置(分片、副本、刷新间隔等)"number_of_shards": 3,"number_of_replicas": 1,"refresh_interval": "30s"},"mappings": {                             # 字段映射(类型、分词器、动态模板等)"dynamic": "strict",                     # 严格模式(禁止自动添加未定义字段)"properties": {"@timestamp": { "type": "date" },      # 时间字段(必选,用于时序数据)"message": { "type": "text", "analyzer": "ik_max_word",            # 中文分词器(需提前安装)"fields": { "keyword": { "type": "keyword" } }  # 同时存储keyword子字段}}},"aliases": {                              # 为新索引自动绑定别名"current_logs": {}                       # 别名指向新索引(无额外配置)}},"composed_of": ["ilm_policy_template"]      # 组合其他组件模板(可选,8.x+ 支持)
}

而组件模板的核心在于将原有普通模板定义的mappings、settings等以组件的方式分隔,以便最小化更新模板。

  • 组件模板定义方式如下所示:

在这里插入图片描述
在这里插入图片描述

由上可知,模板名称为mydata_template,包含两个核心组件——component_mapping_template、component_settings_template。component_mapping_template组件模板实现了映射的定义,component_settings_template实现了设置和别名的定义。

当业务层面需要更新映射时,只需要更新component_mapping_template组件模板即可,改动范围更小、操作更精细化。

2. 索引模板应用的常见问题

模板和索引在应用上的区别是什么?

索引针对的是单一索引,类似MySQL中的一个表。而模板针对一个或多个索引,或者说是针对具有相同表结构的一类索引。

如果想更新映射,那么可以通过更新模板来实现吗?

首先需要建立这样一个认知前提:一旦创建了映射,除几个特定的类型以外,其他类型都不支持更新,除非进行reindex操作。

所以,一旦创建了索引,对索引模板的更新将不会影响该索引。

更新模板仅适用于新创建的索引。更新为动态模板仅会影响索引中的新字段。

分段

在Elasticsearch(基于Lucene实现)中,“分段”(Segment)是底层存储和处理数据的基本单元,本质上是一个不可变的倒排索引文件。以下是具体解释:

分段的本质与作用

  • 倒排索引载体:每个分段存储一组文档的倒排索引(关键词到文档的映射),是Lucene实现快速搜索的核心数据结构。
  • 独立搜索单元:分段一旦生成就不可修改,可独立被搜索,多个分段的搜索结果会在查询时合并。
  • 写入过程的中间产物:文档写入时不会直接写入磁盘上的主索引,而是先存入内存缓冲区,通过定期刷新(refresh)生成新分段。

分段与“近实时”机制的关系

  • 默认1秒刷新(refresh_interval
    Elasticsearch默认每1秒将内存缓冲区中的文档写入一个新分段(并开放搜索),这使得数据在写入后1秒内可见,实现“近实时”(Near Real-Time)。

    • 若调大该值(如30s),则每30秒生成一个分段,数据可见延迟增加,但减少分段生成频率。
  • “准实时”与“近实时”的区别

    • 准实时:数据可见延迟较长(如分钟级),分段生成频率低。
    • 近实时:通过高频刷新(1秒)缩短延迟,但代价是分段数量增加。

分段对写入性能的影响

  • 频繁生成分段的代价
    每次refresh会:

    1. 将内存数据写入分段文件(磁盘I/O);
    2. 生成新的分段元数据(如文件句柄、索引结构);
    3. 可能触发后续的分段合并(merge)操作(长期分段过多时,Elasticsearch会自动合并小分段为大分段,减少搜索时的开销)。
      这些操作在高写入负载下会消耗CPU、磁盘I/O和内存资源,降低写入吞吐量。
  • 调大刷新间隔的优势
    减少分段生成频率,降低I/O和元数据管理开销,提升写入性能,适合对实时性要求不高的场景(如日志分析、离线报表)。

分段的生命周期

  • 生成:通过refresh操作将内存数据写入新分段(默认1秒一次)。
  • 存在:分段不可变,可被搜索,直到被合并或删除。
  • 合并:Elasticsearch后台定期合并小分段为大分段,减少分段数量,提升搜索效率(合并过程会释放旧分段资源)。
  • 删除:当文档被删除时,分段不会立即修改,而是记录“删除标记”,合并时才真正移除被删除的文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Prometheus实战教程:k8s平台手动部署Grafana

以下是一个可用于生产环境的 Kubernetes 部署 Grafana 的 YAML 文件。该配置包括 Deployment、Service、ConfigMap 和 PersistentVolumeClaim&#xff0c;确保 Grafana 的高可用性和数据持久化。 Grafana 生产部署 YAML 文件 ☆实操示例 cat grafana-deployment.yaml 登录后复制…

VSTO外接程序与VBA的联动尝试

文章目录 前言一、第一坑&#xff1a;安装offic2007后excel加载项找不到了二、示例1 通过Ribbon XML自定义Excel主菜单并添加新项二、示例1 总结三、示例2 创建VSTO外接程序三、示例2 总结四、示例 3 C# VSTO外接程序示例四、示例 3 总结五、实现C# 的VSTO调用VBA函数(xlam)六、…

DeepSeek驱动的金市情绪量化:NLP解析贸易政策文本的情绪传导路径

【AI观察】政策信号与市场情绪的量化关联 基于自然语言处理技术对全球财经文本的情绪分析显示&#xff0c;4月30日亚盘时段现货黄金价格波动率较前日下降12.3%&#xff0c;与技术面修正指标呈现强相关性。特政府最新关税政策调整引发市场风险偏好指数&#xff08;RPI&#xff…

期末代码Python

以下是 学生信息管理系统 的简化版代码示例&#xff08;控制台版本&#xff0c;使用文件存储数据&#xff09;&#xff0c;包含核心功能&#xff1a; 1. 定义学生类 class Student: def __init__(self, sid, name, score): self.sid sid # 学号 self.name name # 姓名 self.s…

zotero pdf中英翻译插件使用

最近发现一个pdf中英翻译的神器zotero-pdf2zh&#xff0c;按照官方安装教程走一遍的时候&#xff0c;发现一些流程不清楚的问题&#xff0c; 此文就是整理一些安装需要的文件以及遇到的问题&#xff1a; 相关文件下载地址 Zotero 是一款免费的、开源的文献管理工具&#xff0…

本地MySQL连接hive

1、首先需要修改MySQL的配置&#xff0c;允许远程连接&#xff1a; # 在本地MySQL服务器上执行 sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf找到 bind-address 行&#xff0c;将其修改为&#xff1a; bind-address 0.0.0.02、在本地MySQL中创建用户并授权&#xff08;注意…

Nginx核心功能2

一&#xff1a;正向代理 正向代理&#xff08;Forward Proxy)是一种位于客户端和原始服务器之间的代理服务器&#xff0c;其主要作用是将客户端的请求转发给目标服务器&#xff0c;并将响应返回给客户端Nginx的正向代理充当客户端的“中间人”&#xff0c;代表用户访问外部资源…

高定电视,一场关于生活方式的觉醒

需要有自己的工作室&#xff0c;雇用3个以上专职模特&#xff0c;至少15名全职员工和20名技术工匠‌&#xff1b; 每年都要参加巴黎高级时装周&#xff0c;展示至少50款原创设计&#xff1b; 使用的面料必须高质量、昂贵且不同寻常&#xff0c;设计上注重细节和个性&#x…

用PyTorch搭建卷积神经网络实现MNIST手写数字识别

用PyTorch搭建卷积神经网络实现MNIST手写数字识别 在深度学习领域&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;简称CNN&#xff09;是处理图像数据的强大工具。它通过卷积层、池化层和全连接层等组件&#xff0c;自动提取图像特征&#xff…

Tensorrt 基础入门

什么是tensorrt? 其他厂商: Qualcomm, Hailo, google TPU tensorrt的优劣势 使用tensorrt的pipeline tensorrt使用中存在的问题以及解决方案 tensorrt的应用场景 自动驾驶模型部署需要关注的问题&#xff1a; 边端硬件资源有限 散热&#xff08;不能水冷&#xff09; 实时性&…

Qt 显示QRegExp 和 QtXml 不存在问题

QRegExp 和 QtXml 问题 在Qt6 中 已被弃用&#xff1b; 1&#xff09;QRegExp 已被弃用&#xff0c;改用 QRegularExpression Qt5 → Qt6 重大变更&#xff1a;QRegExp 被移到了 Qt5Compat 模块&#xff0c;默认不在 Qt6 核心模块中。 错误类型解决方法QRegExp 找不到改用 Q…

玩玩OCR

一、Tesseract: 1.下载windows版&#xff1a; tesseract 2. 安装并记下路径&#xff0c;等会要填 3.保存.py文件 import pytesseract from PIL import Image def ocr_local_image(image_path):try:pytesseract.pytesseract.tesseract_cmd rD:\Programs\Tesseract-OCR\tesse…

Dify 完全指南(一):从零搭建开源大模型应用平台(Ollama/VLLM本地模型接入实战)》

文章目录 1. 相关资源2. 核心特性3. 安装与使用&#xff08;Docker Compose 部署&#xff09;3.1 部署Dify3.2 更新Dify3.3 重启Dify3.4 访问Dify 4. 接入本地模型4.1 接入 Ollama 本地模型4.1.1 步骤4.1.2 常见问题 4.2 接入 Vllm 本地模型 5. 进阶应用场景6. 总结 1. 相关资源…

C++ Windows 打包exe运行方案(cmake)

文章目录 背景动态库梳理打包方案一、使用 Vcpkg 安装静态库&#xff08;关键基础配置&#xff09;1. 初始化 Vcpkg2. 安装静态库&#xff08;注意 x64-windows-static 后缀&#xff09; 二、CMakeLists.txt 关键配置三、编译四、验证 不同平台代码兼容\_\_attribute\_\_((pack…

Java学习手册:Hibernate/JPA 使用指南

一、Hibernate 和 JPA 的核心概念 实体&#xff08;Entity&#xff09; &#xff1a;实体是 JPA 中用于表示数据库表的 Java 对象。通过在实体类上添加 Entity 注解&#xff0c;JPA 可以将实体类映射到数据库表。例如&#xff0c;定义一个 User 实体类&#xff1a; import ja…

字符串匹配 之 拓展 KMP算法(Z算法)

文章目录 习题2223.构造字符串的总得分和3031.将单词恢复初始状态所需的最短时间 II 灵神代码模版 区别与KMP算法 KMP算法可用于求解在线性时间复杂度0(n)内求解模式串p在主串s中匹配的未知当然&#xff0c;由于在KMP算法中&#xff0c;预处理求解出了next数组&#xff0c;也就…

安全为上,在系统威胁建模中使用量化分析

*注&#xff1a;Open FAIR™ 知识体系是一种开放和独立的信息风险分析方法。它为理解、分析和度量信息风险提供了分类和方法。Open FAIR作为领先的风险分析方法论&#xff0c;已得到越来越多的大型组织认可。 在数字化风险与日俱增的今天&#xff0c;企业安全决策正面临双重挑战…

游戏引擎学习第259天:OpenGL和软件渲染器清理

回顾并为今天的内容做好铺垫 今天&#xff0c;我们将对游戏的分析器进行升级。在之前的修复中&#xff0c;我们解决了分析器的一些敏感问题&#xff0c;例如它无法跨代码重新加载进行分析&#xff0c;以及一些复杂的小问题。现在&#xff0c;我们的分析器看起来已经很稳定了。…

讯睿CMS模版常用标签参数汇总

一、模板调用标签 1、首页 网站名称&#xff1a;{SITE_NAME} 标题&#xff1a;{$meta_title}&#xff08;列表页通用&#xff09; Keywords&#xff1a;{$meta_keywords} Description&#xff1a;{$meta_description}2、列表页 迅睿cms调用本栏目基础信息标签代码 当前栏目…

【C#】Buffer.BlockCopy的使用

Buffer.BlockCopy 是 C# 中的一个方法&#xff0c;用于在数组之间高效地复制字节块。它主要用于操作字节数组&#xff08;byte[]&#xff09;&#xff0c;但也可以用于其他类型的数组&#xff0c;因为它直接基于内存操作。 以下是关于 Buffer.BlockCopy 的详细说明和使用示例&…