在工作中 ElasticSearch 的一些使用规范总结

简介: 自己在工作中总结的关于 ElasticSearch 的一些使用规范,如有不当的地方,欢迎指正。

前言

大家好,我是路由器没有路

今天跟大家聊下自己在工作中总结的关于使用 ElasticSearch 的一些规范,如有不当的地方,欢迎指正。

Elasticsearch 是一个基于 Lucene 的搜索引擎,支持分布式搜索、多租户、实时搜索和分析等能力,具有高效、稳定、可扩展的优势,被广泛应用于企业级搜索和数据分析场景。

关于 ElasticSearch 的介绍,这里不再赘述了,有兴趣的同学可以看下我前面写的一篇文章:Elasticsearch 的简单介绍和如何使用

基础配置规划

分片(shard)容量

  • 非日志型(搜索型、线上业务型)的 shard 容量在 20~40GB(建议在 20G)
  • 日志型的 shard 容量在 35~100GB(建议 35G)
  • 单个 shard 的文档个数不能超过 20 亿左右(Integer.MAX_VALUE - 128)

注:一个 shard 就是一个 lucene 分片,ES 底层基于 lucene 实现。

索引(index)数量

大索引需要拆分:提高性能,降低风险,将风险分散化。

反例:例如一个 10 多 T 的索引,按 date 查询、name 查询

正例:indexname 拆成多个 index_name\${date}

正例:indexname 按 hash 拆分 index_name{1,2,3,...100..}

节点、分片、索引

一个节点管理的 shard 数不要超过 200 个

索引 mapping 的设计原则

大原则:不使用默认配置和动态 mapping、数据用途(类型、分词、存储、排序)弄清,下面是一个标准 mapping

{
   
  "aliases": {
   
    "my_index_name": {
   }
  },
  "settings": {
   
    "index": {
   
      "refresh_interval": "1s",
      "number_of_shards": "12",
      "number_of_replicas": "1",
      "search.slowlog.threshold.query.warn": "5s",
      "search.slowlog.threshold.query.info": "1s",
      "search.slowlog.threshold.fetch.warn": "1s",
      "search.slowlog.threshold.fetch.info": "800ms",
      "indexing.slowlog.threshold.index.warn": "12s",
      "indexing.slowlog.threshold.index.info": "2s"
    }
  },
  "mappings": {
   
    "_default_": {
   
      "_all": {
   
        "enables": false
      }
    },
    "my_type_name": {
   
      "properties": {
   
        "xxx_id": {
   
          "type": "keyword"
        },
        "timestamp": {
   
          "type": "long"
        },
        "xxx_status": {
   
          "type": "integer"
        },
        "xxx_content": {
   
          "type": "ztext"
        }
      }
    }
  }
}

refresh 频率(refresh_interval)

ES 的定位是准实时搜索引擎,该值默认是 1s,表示写入后 1 秒后可被搜索到,所以这里的值取决于业务对实时性的要求。

注意这里并不是越小越好,刷新频率高也意味着对 ES 的开销也大,通常业务类型在 1-5s,日志型在 30s-120s,如果集中导入数据可将其设置为-1,ES 会自动完成数据刷新(注意完成后更改回来,否则后续会出现搜索不到数据)。

别名(aliases)

记住:在某些场景下可使用别名,但不要过度依赖别名功能。

正例

索引名:index_name_v1

别名:index_name

未来重建 index_name_v2 索引,对于业务来说只需要换别名。

type 个数

1 个就够了,从 ES6 开始只支持一个 type,这个 type 比较鸡肋,后面的版本可能会去掉。

如果一定用:针对已经使用多个 type 的场景,一定要保证不同 type 下字段尽量保持一致,否则会加大数据稀疏性,存储与查询性能受影响

慢日志(slowlog)

一定要配置,默认不记录慢查询,kcc 提供了 grafana、kibana 查询功能。

副本(number_of_replicas)

1 个就够用,副本多写入压力不可忽视。极端情况下:譬如批量导入数据,可以将其调整为 0。

字段设计

  • textkeyword 的用途必须分清:分词和关键词(确定字段是否需要分词)

  • 确定字段是否需要独立存储

  • 字段类型不支持修改,必须谨慎

  • 对不需要进行聚合/排序的字段禁用 doc_values

  • 不要在 text 做模糊搜索

text 类型:适用于分词用于搜索,适用于 email 、内容、描述等需要分词的全文检索,不适用聚合。

keyword 类型:无需分词,整段完整精确匹配,适用于:email 、地址、状态码、分类 tags。

设置合理的 routing key(默认是 id)

id 不均衡:集群容量和访问不均衡,对于分布式存储是致命的。

关闭 _all

ES6.0 已经去掉,对容量(索引过大)和性能(性能下降)都有影响。

避免大宽表:

ES 默认最大 1000,但建议不要超过 100

text 类型的字段不要使用聚合查询

text 类型 fileddata 会加大对内存的占用,如果有需求使用,建议使用 keyword

聚合查询避免使用过多嵌套,

聚合查询的中间结果和最终结果都会在内存中进行,嵌套过多,会导致内存耗尽。

以下是聚合就嵌套了 3 层,结果都会保存在内存中,

如果唯一值较多,就会导致内存耗尽:

{
   
  "aggs": {
   
    "country": {
   
      "terms": {
   
        "filed": "country",
        "size": 10
      },
      "aggs": {
   
        "city": {
   
          "terms": {
   
            "filed": "city",
            "size": 20
          },
          "aggs": {
   
            "salary": {
   
              "terms": {
   
                "filed": "salary",
                "size": 20
              }
            }
          }
        }
      }
    }
  }
}

谨慎操作

  1. 原则:不要忽略设计,快就是慢,坏的索引设计后患无穷.
  2. 拒绝大聚合 :ES 计算都在 JVM 内存中完成。
  3. 拒绝模糊查询:es 一大杀手

    wildcard 搜索

    {
         
      "query": {
         
        "wildcard": {
         
          "title.keyword": "*张三*"
        }
      }
    }
    
  4. 拒绝深度分页
    ES 获取数据时,每次默认最多获取 10000 条,获取更多需要分页,但存在深度分页问题,一定不要使用 from/Size 方式,建议使用 scroll 或者 searchAfter 方式。

    scroll 会把上一次查询结果缓存一定时间(通过配置 scroll=1m 实现),所以在使用 scroll 时一定要保证 search 结果集不要太大。

  5. 基数查询
    尽量不要用基数查询去查询去重后的数据量大小(kibana 中界面上显示是 Unique Count,Distinct Count 等)

    即少用以下查询:

    "aggregations": {
         
        "cardinality": {
         
            "field": "userId"
        }
    }
    
  6. 禁止查询 indexName-*

  7. 避免使用 scriptupdate_by_querydelete_by_query,对线上性能影响较大。

需注意的问题

  1. 一个索引的 shard 数一旦确定不能改变
  2. ES 不支持事务 ACID 特性。
  3. reindex
    reindex 可以实现索引的 shard 变更,但代价非常大:速度慢、对性能有影响,所以好的设计和规划更重要

总结

以上是自己在工作中总结的关于 ElasticSearch 的使用规范,如对你有帮助,可以给个赞。

另外,Elasticsearch 的使用需要结合实际业务场景,通过优化和管理来提高其性能和稳定性,我们需要根据特定的业务场景和使用需求来选择合适的方案。

相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
SQL JavaScript 数据库
树层级处理上万条数据优化!
树层级处理上万条数据优化!
|
4月前
|
并行计算 API Docker
Docker+vLLM内网离线部署Qwen3 流程
本教程详解如何在A10四卡内网环境中,通过Docker+ vLLM离线部署Qwen3-32B/Qwen3-VL-30B-Instruct大模型。涵盖环境准备、镜像离线导入、模型下载、容器启动及参数调优,支持FP8/KV缓存/张量并行等高性能配置,助力安全高效私有化推理
6324 8
|
6月前
|
SQL 缓存 NoSQL
深入骨髓!MyBatis二级缓存实战指南
本文全面解析MyBatis二级缓存的核心原理与实践应用。作为Mapper级别的缓存机制,二级缓存能有效降低数据库压力,提升查询性能。文章详细介绍了二级缓存的启用配置、工作流程、源码实现及事务一致性机制,并针对分布式环境提出了Redis集成方案。同时总结了适用场景与禁用场景,提供缓存策略选择建议,强调数据一致性的保障措施。最后给出最佳实践指南,包括缓存容量设置、性能优化技巧及常见问题解决方案,帮助开发者合理利用二级缓存实现性能优化。
748 7
|
Java 关系型数据库 API
ElasticSearch使用篇
ElasticSearch使用篇
|
存储 Java 测试技术
阿里巴巴java开发手册
这篇文章是关于阿里巴巴Java开发手册的整理,内容包括编程规约、异常日志、单元测试、安全规约、MySQL数据库使用以及工程结构等方面的详细规范和建议,旨在帮助开发者编写更加规范、高效和安全的代码。
|
SQL 监控 搜索推荐
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
Elasticsearch 与 OpenSearch:开源搜索技术的演进与选择
|
SQL 分布式计算 数据处理
实时计算 Flink版产品使用问题之怎么将数据从Hive表中读取并写入到另一个Hive表中
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
缓存 监控 Java
深入Elasticsearch:线程池的原理与应用
深入Elasticsearch:线程池的原理与应用
|
机器学习/深度学习 传感器 编解码
Hy-Tracker来啦 | 带有YOLO的跟踪算法家族再添新成员,尺度变化和遮挡都不是问题!
Hy-Tracker来啦 | 带有YOLO的跟踪算法家族再添新成员,尺度变化和遮挡都不是问题!
691 1
|
开发工具 git
Idea(二) 解决IDEA卡顿问题及相关基本配置(转)
一、IDEA太卡顿,设置使用IDEA的内存 在IDEA的安装目录下的bin目录下: 打开设置: 将idea.exe.vmoptions文件内由-server-Xms128m-Xmx512m-XX:MaxPermSize=250m-XX:ReservedCodeCacheSize=150m-ea-Dsun.
2746 0