《Elasticsearch 使用避坑记》

Elasticsearch(简称ES)是一款强大的开源搜索和分析引擎,广泛应用于日志分析、全文搜索和实时数据分析等领域。然而,由于其复杂性和灵活性,在使用过程中难免会遇到各种问题。使用ES也有好几年了,最近抽空总结了下 "踩坑" 经验,希望可以给到一些参考。

索引设计问题

1. 索引过度分片:

  • 问题:分片过多可能导致集群资源的浪费,增加维护的复杂性,并降低性能。

示例:索引盲目按时间做索引分片,下面示例,分片50个,但是数据量不大量,非常没有必要,而且导致资源浪费。

  • 解决方案:根据集群的大小和预期的负载量,适当地设置分片数量。一般来说,每个节点上的分片数量不宜过多,建议每个索引保持适量的分片数量。

2. 字段映射不合理:

  • 问题:如果字段映射定义不合理,可能导致索引大小膨胀、性能下降或搜索不准确。如下图,没有用到搜索的字段不要加keyword映射
  • 解决方案:仔细设计字段映射,避免将大量文本字段设置为 text 类型,特别是不需要全文搜索的字段。合理使用 keyword、date、long 等字段类型,并根据需要调整分析器和字段属性。

3. 不合理的分片分配:

  • 问题:如果分片分配不均匀,可能导致部分节点负载过重,而其他节点负载较轻。

//新增索引的同时添加分片,不使用默认分片,分片的数量

//一般以(节点数*1.5或3倍)来计算,比如有4个节点,分片数量一般是6个到12个,每个分片一般分配一个副本

  • 解决方案:根据集群的硬件配置和负载情况,合理配置分片的分配策略。可以考虑使用自定义的分片分配规则,或者通过索引别名和节点属性来控制分片的分配。

4. 忽略索引优化:

  • 问题:忽略索引的优化可能导致查询性能下降,存储空间浪费或者索引不稳定。
  • 解决方案:定期优化索引,包括合并段、刷新索引、压缩存储等操作。可以使用 Elasticsearch 提供的 API 或者自动化工具来执行这些优化操作。

5. 索引过于庞大:

  • 问题:如果索引过于庞大,可能会导致查询性能下降,存储成本增加,维护困难等问题。
  • 解决方案:根据业务需求和数据量的增长趋势,合理规划索引的大小。可以考虑按时间周期划分索引,或者采用分片滚动的方式来管理索引的大小

6. 新加索引字段,不支持旧数据搜索

  • 问题:当向现有索引中添加新的字段时,如果新字段的类型或属性与旧数据不兼容,可能导致无法对旧数据进行搜索,或者搜索结果不准确。
  • 在向索引添加新字段之前,需要仔细考虑旧数据的兼容性。可以采取以下措施来解决这个问题:
    • 在添加新字段时,提供默认值或者进行数据迁移,以确保旧数据的完整性。
    • 如果可能,使用动态映射来自动检测新字段并将其应用于新文档,但需要注意动态映射可能会导致不一致的字段映射。

7. 索引字段类型不支持查询

  • 问题当将字段映射为不支持查询的类型时,可能会导致无法进行有效的搜索或聚合操作。
    如下面示例,metaModelCode是字符类型,无法用数字查询
  • 解决方案将 metaModelCode 字段映射为 keyword 类型,以支持精确匹配查询和聚合操作。如果已经存在的索引中包含了不支持查询的字段类型,可以考虑重新创建索引并正确映射字段类型,或者采取其他数据转换方法来解决这个问题。

深度分页问题

1. 获取当前索引配置

GET /idata_asset_meta_data_index_dev/_settings

2. max_result_window 配置

ES 中的 max_result_window 配置,这个数据默认为 200000,当 from+size > max_result_window ,ES 将返回错误

3. 游标取数

当取数过大,要处理大量数据,而且无法在一次查询中获取所有结果,Elasticsearch 提供了一种使用游标(scroll)进行分页查询的机制。这使得你可以逐批次地获取数据,而不受 max_result_window 的限制。可以用来取出数据

更新实时性问题

1. 获取refresh_interval

由于ES 设置 "refresh_interval" : "1s" ,数据更新后1秒后刷新,所以更新插入数据,不是非常实时的,有时由于机器性能原因,刷新间隔还会更大,有可能是5秒。

所以业务开发遇到这种情况,实时性要求高时,要用到第三方缓存如Redis将业务数据缓存起来,不影响客户体验。

数值超过范围

在 Elasticsearch 中,如果要设置的数值超出了范围,比如对于 long 类型的字段,超出范围报错

1. ES字段类型

类型 说明
byte 有符号的8位整数, 范围: [-128 ~ 127]
short 有符号的16位整数, 范围: [-32768 ~ 32767]
integer 有符号的32位整数, 范围: [−231−231 ~ 231231-1]
long 有符号的64位整数, 范围: [−263−263 ~ 263263-1]
float 32位单精度浮点数
double 64位双精度浮点数
half_float 16位半精度IEEE 754浮点类型
scaled_float 缩放类型的的浮点数, 比如price字段只需精确到分, 57.34缩放因子为100, 存储结果为5734
  • 检查数值范围:确保要设置的数值在 long 类型的范围内。long 类型在 Elasticsearch 中的范围大约是 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。
  • 检查索引映射:确保索引映射中该字段被正确定义为 long 类型。如果字段定义不正确,会导致无法正确存储或查询数据。
  • 确认请求格式:确保你发送的请求格式正确,特别是数值应该以正确的格式传递,如不带引号的整数。
  • 检查索引设置:如果问题仍然存在,可能是因为索引的设置限制了该字段的值。例如,可能设置了最小值或最大值的范围。检查索引的设置,特别是与该字段相关的设置,如 "index.mapping.total_fields.limit" 或 "index.mapping.depth.limit" 等。

IK 分词问题

1. IK分词索引设置不正确

当查询或插入数据时会报ik分词查询异常或查询不出数据

正确的做法是将 nam 的属性 设置为 text,如下

原因:

  • text:可分词,不参与聚合
  • keyword:不可分词,数据会作为完整字段进行匹配,可参与聚合

时区问题

1. ES UTC时间格式

项目中,索引下一般都会存在一个时间的字段,这个字段可以用来排序,或者做时间范围查询,或者聚合的场景等都会用到。

ES底层默认采用UTC时间格式,而中国的时间(CST)是

  • 索引数据时使用 UTC 时间:在索引数据到 Elasticsearch 时,确保将日期时间字段转换为 UTC 时间格式,并将其存储在 Elasticsearch 中。
  • 使用日期映射类型:在定义索引的时候,使用 Elasticsearch 的日期映射类型来存储日期时间字段。这将确保 Elasticsearch 正确处理日期,并能够执行日期相关的查询和聚合操作。
  • 使用日期格式化:在索引数据时,可以使用 Elasticsearch 提供的日期格式化功能,将日期字段格式化为 UTC 时间。这可以通过 Elasticsearch 的日期格式化模式来实现。
  • 在应用层进行时区转换:在从 Elasticsearch 中检索数据并显示给用户时,将 UTC 时间转换为用户所在时区的本地时间。在应用程序中,通常会使用相应的日期时间库来进行这种转换。在 JavaScript 中,可以使用 toLocaleString() 方法,而在其他编程语言中也有类似的方法。
  • 考虑存储时区信息:在一些应用场景中,可能需要存储时间的时区信息,以便更准确地处理时间。在这种情况下,可以将时区信息作为额外的字段存储在 Elasticsearch 中,并在检索数据时进行相应的处理。
  • 考虑索引时区策略:根据应用的需求,可能需要考虑不同的索引时区策略。例如,对于跨时区的应用,可以考虑根据用户所在的时区创建不同的索引,以便更有效地处理时间。

查询踩坑

参考文档:
Elasticsearch之如何合理分配索引分片-阿里云开发者社区

elasticsearch ES 踩坑指南(附带项目整理过程)_elasticsearch踩坑-CSDN博客

避坑指南 | Easy-Es

给你总结几个ES下最容易踩的坑-腾讯云开发者社区-腾讯云

相关推荐
程序员-珍5 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
liuxin3344556623 分钟前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
bug菌1 小时前
Java GUI编程进阶:多线程与并发处理的实战指南
java·后端·java ee
夜月行者3 小时前
如何使用ssm实现基于SSM的宠物服务平台的设计与实现+vue
java·后端·ssm
Yvemil73 小时前
RabbitMQ 入门到精通指南
开发语言·后端·ruby
sdg_advance3 小时前
Spring Cloud之OpenFeign的具体实践
后端·spring cloud·openfeign
猿java4 小时前
使用 Kafka面临的挑战
java·后端·kafka
碳苯4 小时前
【rCore OS 开源操作系统】Rust 枚举与模式匹配
开发语言·人工智能·后端·rust·操作系统·os
kylinxjd4 小时前
spring boot发送邮件
java·spring boot·后端·发送email邮件
2401_857439697 小时前
Spring Boot新闻推荐系统:用户体验优化
spring boot·后端·ux