带你读《Elastic Stack 实战手册》之83:——4.3.2.Elasticsearch 开发人员最佳实践指南(1)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 带你读《Elastic Stack 实战手册》之83:——4.3.2.Elasticsearch 开发人员最佳实践指南(1)

4.3.2.Elasticsearch 开发人员最佳实践指南

创作人:铭毅天下


几个月以来,我一直在记录自己开发 Elasticsearch 应用程序的最佳实践。本文梳理的内容试

图传达 Java 的某些思想,我相信其同样适用于其他编程语言。我尝试尽量避免重复教程和

Elasticsearch 官方文档中已经介绍的内容。


本文梳理的内容都是从线上实践问题和个人总结的经验汇总得来的。


文章从以下几个维度展开讲解:

·映射(Mapping)

·设置(Setting)

·查询方式(Querying)

·实战技巧(Strategy)

映射(Mapping)

避免使用 Nested 类型

每个 Elasticsearch 文档都对应一个 Lucene 文档。


Nested 类型是个例外,对于 nested 类型,每个字段都作为单独的文档存储与父 Lucene 的关

联。


其影响是:


·Nested 与父文档中的字段相比,查询字段的速度较慢。

·检索匹配 Nested 字段会降低检索速度。1595


·  一旦更新了包含 Nested 字段的文档的任何字段(与是否更新嵌套字段无关,则所有基础

Lucene 文档(父级及其所有 Nested 子级)都需要标记为已删除并重写)。除了降低更新

速度外,此类操作还会产生大量垃圾文件,直到通过段合才能进行清理。


在某些情况下,你可以将 Nested 字段展平。

例如,给定以下文档:


{ "attributes": [
{"key": "color", "val": "green"}, {"key": "color", "val": "blue"}, {"key": "size", "val": "medium"}
]
}

展平如下:


{ "attributes": { "color": ["green", "blue"], "size": "medium"
}
}

Mapping 设置 strict

实际业务中,如果不明确设定字段类型,Elasticsearch 有动态映射机制,会根据插入数据自动

匹配对应的类型。

假定本来准备插入浮点型数据,但由于第一个插入数据为整形,Elasticsearch 自定会判定为

long 类型,虽然后续数据也能写入,但很明显“浮点类型”只阉割保留了整形部分。


铭毅给个 Demo 一探究竟:

POST my_index03/_doc/1
{ "tvalue":35
}
POST my_index03/_doc/2
{ "tvalue":3.1415
}
GET my_index03/_mapping
GET my_index03/_search
{ "query": { "term": { "tvalue": { "value": 3.1415
}
}
}
}


注意:term 查询是不会返回结果的。

所以,实战环境中,Mapping 设定要注意如下节点:


·显示的指定字段类型

·尽量避免使用动态模板(dynamic-templates)

·禁用日期检测 (date_detection),默认情况下处于启用状态。“strict” 实践举例:


PUT my_index
{ "mappings": { "dynamic": "strict", "properties": { "user": { "properties": { "name": { "type": "text"
},"social_networks": { "dynamic": "strict", "properties": { "network_id": { "type": "keyword"
},"network_name": { "type": "keyword"
}
}
}
}
}
}
}
}

合理的设置 string 类型

Elasticsearch 5.X 之后,String 被分成两种类型,text 和 keyword。两者的区别:


·  text:适用分词全文检索场景

·  keyword:适用字符串的精准匹配场景


默认,如果不显示指定字段类型,字符串类型自定映射后的 Mapping 如下所示:

"cont" : { "type" : "text",
"fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256
}
}

而公司实战的业务场景,通常会面临:

·需不需要分词,不需要的话仅保留 keyword 即可。

·需要用什么分词?英文分词还是中文分词?

·分词后是否还需要排序和聚合,即 fielddata 是否需要开启。

·是否需要精准匹配,即是否需要保留 keyword。

所以,回答了如上几个问题,再有针对的显示设定 string 类型的 Mapping 方为上策


设置(Setting)

在这里我分享了 Elasticsearch 集群设置相关的技巧。


避免过度分片

分片是 Elasticsearch 的最大优势之一,即将数据分散到多个节点以实施并行化。关于这个主

题有过很多讨论。

但请注意,索引的主分片一旦设置便无法更改(除非重建索引或者 reindex)。对于新来者来

说,过度分片是一个非常普遍的陷阱。在做出任何决定之前,请确保先通读官方的这篇博文:

我在 Elasticsearch 集群内应该设置多少个分片?

https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster


铭毅提示:

·主分片数过多:

批量写入或者查询请求被分割成过多的子写入、子查询,导致索引的写入、查询拒绝率上

升。

·主分片数过少:

尤其对于数据量非常庞大的索引,若分片数过少或者就 1 个分片,会导致无法利用集群多

节点资源(也就是分布式特性),造成资源利用率不高或者不均衡,影响写入或者查询效

率。

并且,一旦该大的主分片出现问题,恢复起来耗时会非常长。


取消学习任何段合并的技巧


从本质上讲,Elasticsearch 是另一种分布式 Lucene 产品,就像 Solr 一样 。在底层,大多

数时候,每个 Elasticsearch 文档都对应一个 Lucene 文档(

nested 除外)。在 Lucene 中,文档存储在 segment 中。后台的 Elasticsearch 通过以下两种模式连续维护这些 Lucene 段:

·在 Lucene 中,当你删除或更新文档时,旧文档被标记为已删除,而新文档被创建。 Elast

icsearch 会跟踪这些标记为 deleted 的文档,适时对其段合并。

·新添加的文档可能会产生大小不平衡的段。Elasticsearch 可能会出于优化目的而决定将它们

合并为更大的段。

image.png

实战中一定要注意:段合并是高度受磁盘 I/O 和 CPU 约束的操作。作为用户,我们不想让段

合并破坏 Elasticsearch 的查询性能。


事实上,在某些情况下可以完全避免使用它们:一次构建索引,不再更改它。尽管在许多应用

场景中可能很难满足此条件。一旦开始插入新文档或更新现有文档,段合并就成为不可避免的

一部分。


正在进行的段合并可能会严重破坏集群的总体查询性能。在 Google 上进行随机搜索,你会发

现许多人发帖求助求助:“在段合并中减少对性能的影响的配置“,还有许多人共享某些适用

于他们的配置。但很多配置都是早期 1.X,2.X 版本的设置,新版本已经废弃。

综上我进行段合并的经验法则如下:


·取消学习任何段合并的技巧。早期版本的段合并配置是与 Elasticsearch 的内部紧密耦合的

操作,新版本一般不再兼容。几乎没有“神秘”的底层配置修改可以使它运行得更快。


·  找到 translog flush 的最优配置 。尝试调整 index.translog.sync_interval 和 index.transl

og.flush_threshold_size 设置。

详见:https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-tra

nslog.html

·  动态调整 index.refresh_interval 以满足业务需求。如果实时性要求不高,可以调大刷新频

率(默认是 1s,可以调到 30s 甚至更大)。


PUT /twitter/_settings
{ "index" : { "refresh_interval" : "30s"
}
}

注意 JVM 内存设置

Elasticsearch 可以根据两个主要内存设置产生引人注目的性能特征:

·  JVM 堆空间——主要用途:缓存(节点缓存、分片请求缓存、Field data 缓存以及索引缓存)

·   堆外内存空间—— Lucene 段文件缓存

image.png


提醒你不要根据过去的非 Elasticsearch JVM 应用程序经验来盲目设置 Elasticsearch JVM堆大小。

详见官方文档:

https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html


《Elastic Stack 实战手册》——四、应用实践——4.3 性能优化场景——4.3.2.Elasticsearch 开发人员最佳实践指南(2): https://developer.aliyun.com/article/1225222spm=a2c6h.13148508.setting.15.438f4f0e18NXNE




相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 缓存 监控
深入解析:Elasticsearch集群性能调优策略与最佳实践
【10月更文挑战第8天】Elasticsearch 是一个分布式的、基于 RESTful 风格的搜索和数据分析引擎,它能够快速地存储、搜索和分析大量数据。随着企业对实时数据处理需求的增长,Elasticsearch 被广泛应用于日志分析、全文搜索、安全信息和事件管理(SIEM)等领域。然而,为了确保 Elasticsearch 集群能够高效运行并满足业务需求,需要进行一系列的性能调优工作。
83 3
|
4月前
|
存储 人工智能 自然语言处理
阿里云Elasticsearch AI场景语义搜索最佳实践
本文介绍了如何使用阿里云Elasticsearch结合搜索开发工作台搭建AI语义搜索。
17295 68
|
6月前
|
存储 监控 Java
视频 | Elasticsearch 8.X 企业内训之最佳实践10 讲
视频 | Elasticsearch 8.X 企业内训之最佳实践10 讲
64 0
|
3月前
|
机器学习/深度学习 数据采集 缓存
Elasticsearch与机器学习集成的最佳实践
【8月更文第28天】Elasticsearch 提供了强大的搜索和分析能力,而机器学习则能够通过识别模式和预测趋势来增强这些能力。将两者结合可以实现更智能的搜索体验、异常检测等功能。
103 0
|
4月前
|
存储 监控 Java
使用Elasticsearch实现全文搜索的最佳实践
使用Elasticsearch实现全文搜索的最佳实践
|
4月前
|
存储 监控 Java
使用Elasticsearch实现全文搜索的最佳实践
使用Elasticsearch实现全文搜索的最佳实践
|
5月前
|
存储 Java API
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧———索引与数据上传(二)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧———索引与数据上传(二)
|
5月前
|
缓存 Java API
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)
|
5月前
|
存储 监控 搜索推荐
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)
|
6月前
|
API 数据安全/隐私保护 开发者
用 Python 优雅地玩转 Elasticsearch:实用技巧与最佳实践
用 Python 优雅地玩转 Elasticsearch:实用技巧与最佳实践
206 6

相关产品

  • 检索分析服务 Elasticsearch版