Elasticsearch 中的分析
Posted
技术标签:
【中文标题】Elasticsearch 中的分析【英文标题】:Analytics in Elasticsearch 【发布时间】:2014-09-17 02:59:34 【问题描述】:我正在处理事件分析,我使用 hadoop 处理日志并将一些结果存储在 mysql 中。由于日志每天都在不断出现,因此由于可扩展性问题,这现在不起作用。
我们需要显示每年、每月、每周、每天、每小时的统计数据以及过滤功能 我们的样本可以增长到 10 万用户,每个用户每小时使用 20 个网站 100,000(用户)* 20(唯一网站)* 2(位置)* 24(小时)= 96,000,000(每天最多 9600 万条记录)
我们的表格看起来像event_src_id、时间、用户、网站、位置、一些统计数据
一些查询示例是
1) select website, sum(stats), count(distinct(user_id)) from table group by website;
2) select website, sum(stats), count(distinct(user_id)) from table where YEAR(Time) = 2009 group by website, MONTH(Time);
3) select website, sum(stats), count(distinct(user_id)) from table group by website where event_src_id=XXXXXXXXXXX;
4) select website, sum(stats), count(distinct(user_id)) from table group by website where time > 1 jan 2014 and time <=31 jan 2014;
5) select website, location, sum(stats), count(distinct(user_id)) from table group by website, location;
6) select website, sum(stats) as stats_val from table group by website order by stats_val desc limit 10;
select location, sum(stats) as stats_val from table group by location order by stats_val desc limit 10;
7) delete from table where event_src_id=XXXXXXXXXXX; (may delete all 96M records)
我尝试了 Hadoop 弹性搜索,它似乎可以修复插入部分,我更担心阅读部分。 聚合框架似乎给了一些希望,但我无法按照查询一工作。如何同时分组和求和和区分? 我如何才能最好地将 Elasticsearch 与 Hadoop 结合使用,并为基于 OLAP 的查询提供给定的可扩展性和性能。 任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:首先,我认为将 ElasticSearch 用于类似 OLAP 的查询并不是一个好主意。我建议您使用一些支持您指定的 sql 的类似 Dremel 的技术(Impala、TEZ、Storm 等)。它有一些优点,例如:
您不必将数据从 Hadoop 传输到 ElasticSearch。 你可以使用sql 您不必关心从 ElasticSearch 查询答案中解析 json。不要误会我的意思,我喜欢 ElasticSearch/Logstash/Kibana,但用于日志收集和可视化。当然可以进行一些高级查询,但是我在个人项目中发现了一些限制。
另外考虑使用 Kibana,它是 ElasticSearch 中数据统计的绝佳工具,你可以用它做很多事情。
以下是您要求的一些查询示例(我没有测试过):
1)
"aggs":
"website":
"terms":
"field": "website"
,
"aggs":
"sum_stats":
"sum":
"field": "stats"
,
"aggs":
"distinct_user":
"cardinality":
"field": "user_id",
"precision_threshold": 100
2-6 是相似的,使用 1) 中的东西和不同的filters 像这样:
"aggs":
"your_filter":
"filter":
"term": "event_src_id" : "XXXXXXXXXXX"
,
"aggs":
"website":
"terms":
"field": "website"
,
"aggs":
"sum_stats":
"sum":
"field": "stats"
,
"aggs":
"distinct_user":
"cardinality":
"field": "user_id",
"precision_threshold": 100
7) 删除很简单
"query" :
"term" : "event_src_id" : "XXXXXXXXXXX"
【讨论】:
是的,使用 HDFS 似乎是正确的,但是任何一个都可以用于实时吗? 目前因 AggregationInitializationException 而失败[[sum] 类型的聚合器 [sum_stats] 无法接受子聚合]; 只需将 agg 转换为 sum (sum_stats) 与不同的用户,如下所示: "aggs": "website": "terms": "field": "website" , "aggs": "distinct_user": "cardinality": "field": "user_id", "precision_threshold": 100 , "aggs": "sum_stats": "sum": "field": "stats"
您可以实时使用 HDFS。你是对的,这并不理想,但它是可能的。我也在考虑与您类似的架构-logstash 将数据放入 ElasticSearch,而不是在 Kibana/ElasticSearch 中将其可视化,然后将数据从 ES 批量下载到 HDFS 以用于 OLAP 目的。这是一个关于近实时 HDFS 的有趣幻灯片分享 - slideshare.net/tobym/data-pipeline-at-tapad。这个话题对我来说真的很有趣,所以如果你想更深入地讨论它,你可以给我写一封电子邮件。
不,它没有给出 sum_stats,也只产生了 10 个网站,我怎样才能得到所有的网站(使用分页)?酷,你能用电子邮件更新你的个人资料,以便我可以给你发电子邮件吗?上面幻灯片中使用的堆栈是 vertica。【参考方案2】:
如何同时分组、求和和区分
聚合可以有sub-aggregations。
首先,组功能对应于terms aggregation 和(有时)top_hits aggregation。 其次,有一个sum aggregation,一个简单的统计指标聚合。 最后,在这种情况下,您使用 distinct 是执行 count(distinct),它对应于 cardinality aggregation,根据您的需要可以是近似值或精确值。
7) 从表中删除 event_src_id=XXXXXXXXXXX; (可能会删除所有 96M 记录)
您可以使用delete by query api,但请注意删除文档的百分比很高; Lucene 和 Elasticsearch 并未为此进行优化,您会因删除数据中的标记而产生开销。
示例
按网站从表组中选择网站、sum(stats)、count(distinct(user_id))
GET /_search
"aggs":
"website_stats":
"terms":
"field": "website"
,
"aggs":
"sum_stats":
"sum":
"field": "stats"
,
"count_users":
"cardinality":
"field": "user_id"
select website, sum(stats), count(distinct(user_id)) from table where YEAR(Time) = 2009 group by website, MONTH(Time)
GET /_search
"query":
"filter":
"range":
"Time":
"gt": "2009-01-01 00:00:00",
"lt": "2010-01-01 00:00:00"
,
"aggs":
"monthly_stats"
"terms":
"field": "website"
,
"aggs":
"months":
"date_histogram":
"field": "Time",
"interval": "month"
,
"aggs" :
"sum_stats":
"sum":
"field": "stats"
,
"count_users":
"cardinality":
"field": "user_id"
【讨论】:
为了完整起见,您能否分享一些 1 到 7 的查询示例? 添加了两个示例——希望这足以扩展到其他查询 因 AggregationInitializationException 失败[[sum] 类型的聚合器 [sum_stats] 不能接受子聚合]; hmmm "sum_stats" 没有子聚合,"months" 有两个子聚合:"sum_stats" 和 "count_users" 我认为它缺少***聚合的名称;查看编辑的示例以上是关于Elasticsearch 中的分析的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:如何分析和优化 Elastic 部署的存储空间
Elastic Stack(ElasticSearch Kibana 和 Logstash) 实现日志的自动采集搜索和分析