New Aggregation Group(新聚合组)

本文根据Apache Kylin官方文档翻译 详见http://kylin.apache.org/blog/2016/02/18/new-aggregation-group/

新聚合组(New Aggregation Group)

文章全标题:新聚合组处理维度灾难问题(尤其是当高基数维度存在的时候)

摘要:

对于所有的基于预计算的OLAP引擎来讲维度灾难是臭名昭著的问题。在1.5之前的版本中,Kylin试着通过一些简单的技术解决这个问题,一定程度上减轻了这个问题。在我们的开源实践中,我们发现这个技术缺乏系统性的设计思想,而且无法解决许多常见问题。在Kylin1.5版本中我们重新设计了聚合组机制让它更好的服务各种各样的cube设计场景。

介绍:

    众所周知,Kylin通过预先计算cubes(多维数据集、数据立方体)提高了查询速度,cubes包括了所有维度的不同组合,也就是cuboids。问题是cubiods随着维度(dimensions)的变化呈指数增长。例如,对于3维的cube有8中可能的cuboids,而4维的cube有16种可用的cuboids。虽然Kylin使用可扩展的计算框架(MapReduce)和可扩展的存储(HBase)来计算和存储cubes,但是cube的规模比原始的数据源大数倍仍然让人难以接受。

 

解决方法是减少不必要的维度。正如我们先前在http://kylin.apache.org./docs/howto/howto_optimize_cubes.html讨论的那样,可以通过下面两种方式实现:

 

首先,我们可以移除非必要的维度。比如,假设一个日期lookup表,在这个表中 cal_dt是主键列还有很多衍生列比如week_begin_dt,month_begin_dt,month_begin_dt。即使分析师需要把week_begin_dt作为维度,我们也可以移除它,因为它总是可以通过维度cal_dt计算,这就是”derived(派生)”优化。

 

其次,一些维度的组合可以被移除。这是此文主要讨论的,我们暂且称之为”combination pruning”(组合修剪)。例如,如果一个维度被指定为”mandatory”(强制性的)。然后所有的不包括这个维度的组合可以被移除。如果维度A、B、C形成了一个“Hierachy(层次)关系”,这样的话只有A、AB和ABC的组合被生成。Kylin版本1.5之前也有一个”aggregationgroup(聚合组)”的概念,也是为组合修剪服务的。然而它没有详细的文档以及很难理解(我发现也很难解释)。不管怎样,我们将略过它,因为我们将重新定义“聚合组”到底是什么。

 

在我们的开源实践中我们发现一些对我们最原始的组合修剪有意义的反馈。首先,这些技术是分离的而不是系统的设计。其次,原始的聚合组没有良好的设计以及文档以至于在eBay之外的公司很难使用。第三,也就是最重要的一点,它在语义描述方面没有足够的表现力。

 

为了说明描述语义问题,我们假设有一个交易数据cube,它有个叫做buyer_id的很高基数的维度以及其它正常维度比如业务日期 cal_dt,购买者城市等等。分析师可能需要通过分组non-buyer_id的维度了解一个大概的印象,例如仅仅分组cal_dt。分析师也可能需要通过过滤buyer_id钻取数据查看一个购买者的行为。鉴于buy_id有很高基数,一旦一个buyer_id确定了,相关的数据应该会非常少(所以至于要只用基本的cubiod并做些查询时间聚合来”解聚合”不想要的维度就可以了)。在这样的例子中,希望的修剪措施的输出应该是:

 

 

 

 

Cuboid

计算or 忽略

原因

———————-

————— 

—————————————————

city

计算

Group by location (按location分组)

cal_dt

计算

Group by date(按date分组)

buyer_id

忽略

Group by buyer yield too many results to analyze, buyer_id should be used as a filter and used by visiting base cuboid

(按buyer字段分组有太多的结果需要分析,buy_id应该被作为过滤器通过访问基本的cubiod使用)

city,cal_dt

计算

Group by location and date

city,buyer_id

忽略

Group by buyer yield too many results to analyze, buyer_id should be used as a filter and used by visiting base cuboid

cal_dt,buyer_id

忽略

Group by buyer yield too many results to analyze, buyer_id should be used as a filter and used by visiting base cuboid

city,cal_dt,buyer_id

计算

Base cuboid

不幸的是在Kylin 1.5版本之前利用现有的语义工具没有方法表示这样的修剪设置

新聚合组设计

 

在Kylin 1.5版本中我们重新设计了聚合组机制,在jira发出https://issues.apache.org/jira/browse/KYLIN-242。这个项被命名为“KylinCubiod WhiteList”因为这个新设计甚至允许cube设计者通过保持白名单指定预期的cuboids,想想下它是多么语义明确。

 

在新设计中,聚集组(简称 AGG)被定义为一组收到相同规则约束的cuboids。Cube设计者可以为一个Cube定义一个或者多个AGG,所有AGG的组合为一个cube提供了有效组合组成的cubiods.注意一个Cuboid允许出现在多个AGG中,它在cube构建的时候只创建一个。

 

如果深入到AGG源码中(https://github.com/apache/kylin/blob/kylin-1.5.0/core-cube/src/main/java/org/apache/kylin/cube/model/AggregationGroup.java)有两个定义的重要属性:@JsonPropertiy(”include”)以及

@JsonProperty(“select_rule”).

 

 

@JsonPropertiy(”include”)

这个属性用来指定哪个维度是包括在AGG中。这个属性的值必须是完整维度的子集。通过只包括必要的维度保持适当的最小限度。

 

@JsonProperty(“select_rule”)

选择规则是在AGG中所有有效的cuboids都必须遵守的。这里Cube设计者可以定义多个规则应用到包括的维度上,想在有3种类型的规则。

Hierarchyrule(层次规则),上文已讨论

Mantatoryrule(强制规则),上文已讨论。

Jointrules。这是新提出的规则。如果两个或者更多维度是”joint”的,那么任何有效的cuboid将要么这些维度一个也不包括,要么包括这些维度的所有。换句话说,这些维度将总是”在一起”的。当cube设计者确定一些维度总是在一起查询的时候这是很有用的。对于组合修剪很少使用的维度它也是强大的武器。假设你有20个维度,前10个维度是频繁使用的,而后10个维度是很少使用的。通过将后10个维度作为”joint”,你能有效的减少cubiod数量从2^20到2^11。事实上这是旧的”聚合组”机制能达到的。如果你使用Kylin 1.5之前的版本,我们的元数据更新工具将会自动将它翻译成joint语义。

 

通过灵活的使用新的聚合组你可以在理论上控制任何cubiod的计算或者跳过。这个可以显著的减少计算和存储开销,尤其是当cube为一个固定的仪表盘服务时,他将再现只需要一些具体的cuboids的sql查询。在极端情况下你可以配置每一个AGG只包括一个cuboid,少数的几个AGG将由你需要的cuboid whiltelist组成。

 

Kylincuboid计算调度会基于AGG定义指定所有的有效的cuboids计算顺序。你不必关心他是如何实现的,因为每个cuboid将会得到计算并且只计算一次。你需要铭记在心的唯一一件事是:不要滥用AGG。尽可能的使用AGG的select rule,避免引进大量的”single cuboid AGG”除非它真是必须的。太多的AGG对于cuboid计算调度是个负担,对于查询引擎也是。

 

Buyer_id问题再探

 

既然我们已经获得了新的AGG工具,buyer_id问题可以被重新探究。我们需要做的就是为这个cube定义两个AGG:

 

AGG1包括:[cal_dt,city,buyer_id]select_rules:{joint:{cal_dt,city,buyer_id}}

AGG2包括:[cal_dt,city]select rules{}

 

第一个AGG将只提供基本的cuboid,第二个AGG提供没有buy_id的所有cuboids。

 

开始使用它

新聚合组机制在Kylin 1.5版本应该就可以使用。

 

Elasticsearch 聚合查询(Aggregation)是一种用于对数据进行多维度分析的功能。聚合查询可以用于分析数据的分布情况、计算数据的统计信息、生成图表等。在 Elasticsearch 中,聚合查询是通过使用特定的聚合器(Aggregator)来完成的。 Java 中使用 Elasticsearch 聚合查询需要使用 Elasticsearch Java API。首先需要创建一个 SearchRequest 对象,并设置需要查询的索引和查询条件。然后创建一个 AggregationBuilder 对象,用于定义聚合查询的规则和参数。最后将 AggregationBuilder 对象添加到 SearchRequest 中,执行查询操作。 以下是一个简单的 Java 代码示例,用于查询某个索引下的数据,并按照某个字段进行分聚合查询: ``` SearchRequest searchRequest = new SearchRequest("index_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_field").field("field_name"); searchSourceBuilder.aggregation(aggregationBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); Terms terms = searchResponse.getAggregations().get("group_by_field"); for (Terms.Bucket bucket : terms.getBuckets()) { String key = bucket.getKeyAsString(); long count = bucket.getDocCount(); System.out.println("key: " + key + ", count: " + count); } ``` 在上面的代码中,首先创建了一个 SearchRequest 对象,设置需要查询的索引和查询条件。然后创建了一个 TermsAggregationBuilder 对象,用于按照某个字段进行分聚合查询。最后将 TermsAggregationBuilder 对象添加到 SearchRequest 中,执行查询操作。 查询结果会返回一个 Terms 对象,其中包含了分聚合查询的结果。可以使用 Terms 对象的 getBuckets() 方法获取分聚合查询的结果列表。每个分聚合查询结果由一个 Terms.Bucket 对象表示,其中包含了分聚合查询的键和文档数量等信息。 以上是简单的聚合查询示例,Elasticsearch 聚合查询功能非常强大,支持多种聚合器和聚合规则,可以根据具体需求进行调整和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值