Elasticsearch 高基数聚合性能提升3倍,改动了什么?

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 1、上问题这是来自球友实战问题。大致需求介绍如下:约 3600 万的数据,其中关键字段如下所示:

image.png

链接


_id creator

doc_1 [张三,李四,王五,赵六]

doc_2 [陈胜,吴广,张三]

用 cardinality 聚合统计,creator 的个数有约 1300 万。


问题:但在高基数(high cardinality)的情形下,性能不理想。


2、概念解读:什么是高基数?

为了更精确解读,这里直接拿:Elastic 官方博客只字不差的翻译。


The performance of terms aggregations can be greatly impacted by the cardinality of the field that is being aggregated.

Cardinality refers to the uniqueness of values stored in a particular field.

High cardinality means that a field contains a large percentage of unique values.

Low cardinality means that a field contains a lot of repeated values.

For example, a field storing country names will be relatively low cardinality since there are less than two hundred countries in the world. Alternatively, a field storing IBAN numbers or email addresses is high cardinality since there may be millions of unique values stored.

terms 聚合的性能可能会受到所聚合字段的基数的极大影响。


基数(Cardinality)是指存储在特定字段中的值的唯一性。


高基数:意味着一个字段包含很大比例的唯一值。


举例:电子邮件地址可能会有数千万+唯一值,属于高基数。(换了举例)


低基数:意味着一个字段包含很多重复的值。


举例:因为世界上少于200个国家,国家名称就是低基数。


3、问题本质

经反复讨论,本质问题:高基数业务场景下,聚合慢,达不到预期。


我记得刚入职场,我向导师的导师(辈分应该是:师爷)当面请教一个问题,我说了很长,他实在听不下去了,就说了一句:“你的问题是什么?”,一语惊醒梦中人,我一直记到今天。


后面当我再向别人请教问题的时候,我都提前打好草稿、列好提纲,快速且直接说出重点、交流效率提升不少。


毫不夸张的说,能用简短的话描述清楚问题,问题就能基本解决了一大半。


4、怎么改进呢?

经反复讨论,结合球友之前的实践,思路如下:


第一 :对于字段值,存储Hash值(写入时处理)。


第二 :基于Hash 做聚合和统计分析操作。


5、Elasticsearch 有 Hash 值类型吗?

早期版本(7.X 之前)没有,但是 7.X 之后有。


如下借助 mapper-murmur3 插件实现:


插件地址:


https://www.elastic.co/guide/en/elasticsearch/plugins/7.2/mapper-murmur3.html


murmur3 需要着重介绍一下:


维基百科解读:MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。


由 Austin Appleby 在 2008年发明, 并出现了多个变种,都已经发布到了公有领域(public domain)。


与其它流行的哈希函数相比,对于规律性较强的 key,MurmurHash的随机分布特征表现更良好。


Redis 在实现字典时用到了两种不同的哈希算法,MurmurHash 便是其中一种(另一种是djb),在 Redis 中应用十分广泛,包括数据库、集群、哈希键、阻塞操作等功能都用到了这个算法。


发明算法的作者被邀到 google 工作,该算法最新版本是 MurmurHash3 , 基于MurmurHash2改进了一些小瑕疵,使得速度更快,实现了 32 位(低延时)、128 位 HashKey,尤其对大块的数据,具有较高的平衡性与低碰撞率。


6、mapper-murmur3 插件实践一把

第一步:插件安装


bin/elasticsearch-plugin install mapper-murmur3

第二步:导入Demo测试


PUT my_index

{

 "mappings": {

   "properties": {

     "my_field": {

       "type": "keyword",

       "fields": {

         "hash": {

           "type": "murmur3"

         }

       }

     }

   }

 }

}

PUT my_index/_doc/1

{

 "my_field": "This is a document"

}

PUT my_index/_doc/2

{

 "my_field": "This is a document"

}

GET my_index/_search

{

 "aggs": {

   "my_field_cardinality": {

     "terms": {

       "field": "my_field.hash"

     },

    "aggs": {

       "top_sales_hits": {

         "top_hits": {

           "size": 2

         }

       }

     }

   }

 }

}

聚合结果如下:

image.png

这时候,就能比较清晰的看出murmur3的作用:

  • 属于 Mapping的特定字段类型。
  • 可以和keyword类型组合当做复合类型使用。
  • _source  不存储结果值。
  • 只在聚合后才能看到结果。

7、加了 mapper-murmur3 Hash 后效果如何呢?

image.png

8、在相对低基数聚合性能如何呢?

实战一把。

image.png

8.1 模拟生成 1000W+数据。

文本文件输入了 39415 name信息(随机生成)。通过 python-dsl 随机生成写入 ES集群。

写入结果如下所示:

image.png

索引1:


PUT my-index-000002

{

 "mappings": {

   "properties": {

     "creator":{

       "type":"keyword"

     }

   }

 }

}

索引2:


PUT my-index-000003

{

 "mappings": {

   "properties": {

     "creator": {

       "type": "keyword",

       "fields": {

         "hash": {

           "type": "murmur3"

         }

       }

     }

   }

 }

}

8.2 低基数有多低?

POST my-index-000002/_search

{

 "size": 0,

 "aggs": {

   "count_aggs": {

     "cardinality": {

       "field": "creator"

     }

   }

 }

}

去重后的结果:39415。


原始数据量:11509010。


占比:0.342%


虽然高、低基数没有明确数据量多少的定义,但,这明显是低基数。


8.2 聚合结果对比

POST my-index-000002/_search

{

 "aggs": {

   "terms_agg": {

     "terms": {

       "field":"creator",

       "size":3,

       "shard_size":1000

     }

   }

 }

}

image.png

如上所示 ,未加Hash的索引聚合要被加了Hash 的快一倍!


这也初步说明:Hash 在低基数聚合没有效果。


9、小结

以上验证和测试仅供参考,实际选型需要结合业务场景实际,进行充分验证后再做定夺。


类似高基数聚合业务场景,你实践中的优化点是什么?欢迎留言交流。


参考:


https://www.elastic.co/cn/blog/improving-the-performance-of-high-cardinality-terms-aggregations-in-elasticsearch


https://cloud.tencent.com/developer/article/1421924


加微信:elastic6(仅有少量坑位了),和 BAT 大佬一起精进 Elastic 技术!

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
6月前
|
存储 搜索推荐 Java
|
6月前
|
机器学习/深度学习 搜索推荐 关系型数据库
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
号称Elasticsearch 10倍性能搜索引擎到底有多强悍
218 0
|
存储 人工智能 自然语言处理
Elasticsearch Relevance Engine---为AI变革提供高级搜索能力[ES向量搜索、常用配置参数、聚合功能等详解]
Elasticsearch Relevance Engine---为AI变革提供高级搜索能力[ES向量搜索、常用配置参数、聚合功能等详解]
Elasticsearch Relevance Engine---为AI变革提供高级搜索能力[ES向量搜索、常用配置参数、聚合功能等详解]
|
自然语言处理 数据可视化 Java
Spring Data Elasticsearch 聚合查询
如需要统计某件商品的数量,最高价格,最低价格等就用到了聚合查询,就像数据库中的group by
212 0
|
2月前
|
缓存 固态存储 Java
Elasticsearch 的扩展性和性能调优
【9月更文第2天】Elasticsearch 是一个分布式的搜索和分析引擎,适用于各种大规模数据处理场景。随着数据量的增长和查询复杂度的增加,Elasticsearch 的性能优化变得尤为重要。本文将详细介绍如何通过硬件配置、集群规模调整以及查询优化策略来提升 Elasticsearch 的性能。
197 6
|
10天前
|
存储 SQL 监控
|
1月前
|
存储 缓存 监控
深入解析:Elasticsearch集群性能调优策略与最佳实践
【10月更文挑战第8天】Elasticsearch 是一个分布式的、基于 RESTful 风格的搜索和数据分析引擎,它能够快速地存储、搜索和分析大量数据。随着企业对实时数据处理需求的增长,Elasticsearch 被广泛应用于日志分析、全文搜索、安全信息和事件管理(SIEM)等领域。然而,为了确保 Elasticsearch 集群能够高效运行并满足业务需求,需要进行一系列的性能调优工作。
78 3
|
2月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
|
3月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
ElasticSearch 实现分词全文检索 - 聚合查询 cardinality
118 1
|
6月前
|
测试技术 定位技术 API
万字长文:一文彻底搞懂Elasticsearch中Geo数据类型查询、聚合、排序
万字长文:一文彻底搞懂Elasticsearch中Geo数据类型查询、聚合、排序
95109 140