1、Druid 查询概述
上一节完成数据导入后,接下来讲讲Druid如何查询及统计分析导入的数据。
Druid的查询是使用REST风格的HTTP请求查询服务节点(Broker、Historical、Realtime),这些服务节点暴露REST查询接口,客户端发送Json对象请求查询接口。一般情况下,查询服务接口发布在Broker节点,基于Linux 的POST请求查询如下所示:
/**
* port: 查询请求接口对应Broker,默认8082端口
* query_json_file: 查询Json对象文件(配置)
*/
curl -X POST '<queryable_host>:<port>/druid/v2/?pretty' -H 'Content-Type:application/json' -d @<query_json_file>
2、Druid 查询类型
Druid在不同场景下,有很多的查询类型。查询是由各种JSON属性和Druid有不同类型的不同场景下查询组成。对于各种类型的查询类型的配置可以json属性文件设置。Druid查询类型,概括一下为3大类:
1. 聚合查询 - 时间序列查询(Timeseries)、排名查询(TopN)、分组查询(GroupBy)
2. 元数据查询 - 时间范围(Time Boundary) 、段元数据(Segment Metadata)、数据源(Datasource)
3. Search查询 - Search
本节以聚合查询为主,其它查询类型比较简单,使用上相对比较少,暂不介绍。对聚合查询类型下的3种查询如何选择进行一下概述:
在可能的情况下,我们建议使用的时间序列和TopN查询代替分组查询,分组查询是Druid最灵活的的查询,但是性能最差。时间序列查询是明显快于GROUPBY查询,因为聚合不需要分组尺寸。对于分组和排序在一个单一的维度,TopN查询更优于GROUPBY。
2.1 Json查询属性
在讲聚合查询下的3种查询类型之前,我们需要对3种查询类型共有的特别重要的Json属性理解与熟悉,常用属性如:queryType、dataSource、granularity、filter、aggregator等。
2.1.1 查询类型(queryType)
对应聚合查询下的3种类型值:timeseries、topN、groupBy
2.1.2 数据源(dataSource)
数据源,类似数据库中表的概念,对应数据导入时Json配置属性dataSource值
2.1.3 聚合粒度(granularity)
粒度决定如何得到数据块在跨时间维度,或者如何得到按小时,天,分钟的汇总等。在配置查询聚合粒度里有三种配置方法:
1. 简单聚合粒度 - 支持字符串值有:all、none、second、minute、fifteen_minute、thirty_minute、hour、day、week、month、quarter、year
(1) all - 将所有块变成一块
(2) none - 不使用块数据(它实际上是使用最小索引的粒度,none意味着为毫秒级的粒度);按时间序列化查询时不建议使用none,因为所有的毫秒不存在,系统也将尝试生成0值,这往往是很多。
2. 时间段聚合粒度 - Druid指定一精确的持续时间(毫秒)和时间缀返回UTC(世界标准时间)。
3. 常用时间段聚合粒度 - 与时间段聚合粒度差不多,但是常用时间指平时我们常用时间段,如年、月、周、小时等。
下面对3种聚合粒度配置举例说明:
简单聚合粒度
查询粒度比数据采集时配置的粒度小,则不合理,也无意义,因较小粒度(相比)者无索引数据;如
查询粒度小于采集时配置的查询粒度时,则Druid的查询结果与采集数据配置的查询粒度结果一样。
假设我们存储在Druid的数据使用毫秒粒度获取,数据如下:
{"timestamp": "2013-08-31T01:02:33Z", "page": "AAA", "language" : "en"}
{"timestamp": "2013-09-01T01:02:33Z", "page": "BBB", "language" : "en"}
{"timestamp": "2013-09-02T23:32:45Z", "page": "CCC", "language" : "en"}
{"timestamp": "2013-09-03T03:32:45Z", "page": "DDD", "language" : "en"}
以"小时" 粒度提交一个groupby查询,查询配置如下:
{
"queryType":"groupBy",
"dataSource":"dataSource",
"granularity":"hour",
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"2000-01-01T00:00Z/3000-01-01T00:00Z"
]
}
按小时粒度进行的groupby查询结果中timestamp值精确到小时间,比小时粒度更小粒度值自动补填零,
以此类推按天查询,则小时及小粒度补零。timestamp值为UTC
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如果指定查询粒度为 none,则返回结果与数据导入时设置粒度(queryGranularity属性值)结果一样,
此处的导入粒度为毫秒,结果如下:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T01:02:33.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T23:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T03:32:45.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
如果指定查询粒度为 all,返回数组长度结果为1,结果如下:
[ {
"version" : "v1",
"timestamp" : "2000-01-01T00:00:00.000Z",
"event" : {
"count" : 4,
"language" : "en"
}
} ]
时间段聚合粒度
指定一个精确时间持续时长(毫秒表示)及时间缀,返回UTC时间;支持可选项属性origin,不指定时
默认开始时间(1970-01-01T00:00:00Z)
/**持续时间段2小时,从1970-01-01T00:00:00Z开始*/
{"type": "duration", "duration": 7200000}
/**持续时间1小时,从origin开始*/
{"type": "duration", "duration": 3600000, "origin": "2012-01-01T00:30:00Z"}
以上简单聚合粒度的示例数据为例,提交groupby查询,持续时间段为24小时,查询配置如下:
{
"queryType":"groupBy",
"dataSource":"dataSource",
"granularity":{"type": "duration", "duration": "86400000"},
"dimensions":[
"language"
],
"aggregations":[
{
"type":"count",
"name":"count"
}
],
"intervals":[
"2000-01-01T00:00Z/3000-01-01T00:00Z"
]
}
查询结果:
[ {
"version" : "v1",
"timestamp" : "2013-08-31T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-01T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-02T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
}, {
"version" : "v1",
"timestamp" : "2013-09-03T00:00:00.000Z",
"event" : {
"count" : 1,
"language" : "en"
}
} ]
常用时间段聚合粒度
略...
2.1.4 过滤(Filters)
一个Filter就是一个Json对象,用于过滤数据行过滤,类似SQL中的Where子句。过滤器类型有如下:Selector filte、Regular expression filter(正则表达式过滤)、Logical expression filters(AND、OR、NOT)、In filter、Bound filter、Search filter、JavaScript filter、Extraction filter
示例简单查看使用方式:
查询过滤(Selector filte)
等价于:WHERE <dimension_string> = '<dimension_value_string>'
"filter": { "type": "selector", "dimension": <dimension_string>, "value": <dimension_value_string> }
正则表达过滤(Regular expression filter)
与Selector filte差不多,只是这里使用正则表达式,表达式为标准的Java正则表达式规范
"filter": { "type": "regex", "dimension": <dimension_string>, "pattern": <pattern_string> }
逻缉表达过滤(Logical expression filters)
AND
"filter": { "type": "and", "fields": [<filter>, <filter>, ...] }
OR
"filter": { "type": "or", "fields": [<filter>, <filter>, ...] }
NOT
"filter": { "type": "not", "field": <filter> }
IN过滤(In filter)
SQL查询
SELECT COUNT(*) AS 'Count' FROM `table` WHERE `outlaw` IN ('Good', 'Bad', 'Ugly')
Druid IN 过滤表示
{
"type": "in",
"dimension": "outlaw",
"values": ["Good", "Bad", "Ugly"]
}
范围过滤(Bound filter)
Bound filter 过滤比较值大小或小于某值,默认按字符串比较,使用数据比较需要设置alphaNumeric 属
性为true;默认 Bound filter为非严格性(类闭区间),如 inputString <= upper && inputSting >= lower
{
"type": "bound",
"dimension": "age",
"lower": "21",
"upper": "31" ,
"alphaNumeric": true
}
上述表示等价如:21 <= age <= 31
Bound filter 严格性,需要设置lowerStrict or/and upperStrict 属性值为true如下:
{
"type": "bound",
"dimension": "age",
"lower": "21",
"lowerStrict": true,
"upper": "31" ,
"upperStrict": true,
"alphaNumeric": true
}
等价如:21 < age < 31
2.1.5 聚合(Aggregations)
聚合可以在采集时间时规格部分的一种方式,汇总数据进入Druid之前提供。聚合也可以被指定为在查询时多查询的部分,聚合类型如下:Count aggregator、Sum aggregators、Min / Max aggregators、Approximate Aggregations、Miscellaneous Aggregations
Count aggregator
查询返回匹配过滤条件的数据行数,需要注意的是:Druid进行Count查询的数据量并不一定等于数据采
集时导入的数据量,因为Druid在采集数据并导入时已经对数据进行了聚合。
{ "type" : "count", "name" : <output_name> }
Sum aggregator
longSum aggregator:计算值为有符号位64位整数
{ "type" : "longSum", "name" : <output_name>, "fieldName" : <metric_name> }
doubleSum aggregator:与longSum类似,计算值为64位浮点型
{ "type" : "doubleSum", "name" : <output_name>, "fieldName" : <metric_name> }
Min / Max aggregators
doubleMin aggregator
{ "type" : "doubleMin", "name" : <output_name>, "fieldName" : <metric_name> }
doubleMax aggregator
{ "type" : "doubleMax", "name" : <output_name>, "fieldName" : <metric_name> }
longMin aggregator
{ "type" : "longMin", "name" : <output_name>, "fieldName" : <metric_name> }
longMax aggregator
{ "type" : "longMax", "name" : <output_name>, "fieldName" : <metric_name> }
类似聚合(Approximate Aggregations)
基数聚合(Cardinality aggregator)
计算Druid多种维度基数,Cardinality aggregator使用HyperLogLog评估基数,这种聚合比带有索引的
hyperUnique聚合慢,运行在一个维度列,意味着不能从数据集中删除字符串维度来提高聚合;一般我们
强力推荐使用hyperUnique aggregator而不是Cardinality aggregator,格式如下:
{
"type": "cardinality",
"name": "<output_name>",
"fieldNames": [ <dimension1>, <dimension2>, ... ],
"byRow": <false | true> # (optional, defaults to false)
}
. 维度值聚合-当设置属性byRow为false(默认值)时,通过合并所有给定的维度列来计算值集合。
对于单维度,等价如下:
SELECT COUNT(DISTINCT(dimension)) FROM <datasource>
对于多维度,等价如下:
SELECT COUNT(DISTINCT(value)) FROM (
SELECT dim_1 as value FROM <datasource>
UNION
SELECT dim_2 as value FROM <datasource>
UNION
SELECT dim_3 as value FROM <datasource>
)
. 行聚合-当设置属性byRow为true时,根所不同维度的值合并来计算行值,等价如下:
SELECT COUNT(*) FROM ( SELECT DIM1, DIM2, DIM3 FROM <datasource> GROUP BY DIM1, DIM2, DIM3 )
许多不同国家的人出生地或来自哪里,用druid配置如下:
{
"type": "cardinality",
"name": "distinct_countries",
"fieldNames": [ "coutry_of_origin", "country_of_residence" ]
}
HyperUnique aggregator
已经被“hyperunique”在创建索引时聚合的维度值使用HyperLogLog计算估计,更多资料请参考官网
{ "type" : "hyperUnique", "name" : <output_name>, "fieldName" : <metric_name> }
后聚合(post-aggregators)
后聚合是对Druid进行聚合后的值进行聚全,如果查询中包括一个后聚合,那么确保所有聚合满足后聚合要求;后聚合有以下几种类型:
1. Arithmetic post-aggregators
2. Field accessor post-aggregator
3. Constant post-aggregator
4. JavaScript post-aggregator
5. HyperUnique Cardinality post-aggregator
Arithmetic post-aggregators
算术后聚合应用已提供的函数从左到右获取字段,这些字段可聚合或后聚合;支持+
, -
, *
, /
, and quotient。
算术后聚合可以指定ordering属性,用于聚合结果排序(对topN查询很有用 ):
(1) 如果无ordering属性(或null),使用默认的浮点排序。
(2) numericFirst 首先返回有限值,其次是NaN,最后返回无限值。
算术后聚合语法如下:
postAggregation : {
"type" : "arithmetic",
"name" : <output_name>,
"fn" : <arithmetic_function>,
"fields": [<post_aggregator>, <post_aggregator>, ...],
"ordering" : <null (default), or "numericFirst">
}
Field accessor post-aggregator - fieldName引用aggregator定义的名称
{ "type" : "fieldAccess", "name": <output_name>, "fieldName" : <aggregator_name> }
Constant post-aggregator - 返回指定值
{ "type" : "constant", "name" : <output_name>, "value" : <numerical_value> }
2.2 时间序列查询(Timeseries)
这些类型的查询以时间序列查询对象和返回一个JSON数组对象,每个对象表示时间序列查询的值,时间序列查询请求的Json的7个主要属性如下:
属性 |
描述 |
必填项 |
queryType |
字符串类型,时间序列 "timeseries" |
是 |
dataSource |
字符串类型,数据源(类似数据库表) |
是 |
descending |
排序标志,默认为 "false"(升序) |
否 |
intervals |
查询时间范围跨度,JSON对象,ISO-8601区间 |
是 |
granularity |
定义查询结果块粒度 |
是 |
filter |
过滤条件 |
否 |
aggregations |
聚合 |
是 |
postAggregations |
后聚合 |
否 |
context |
上下文 |
否 |
{
"queryType": "timeseries",
"dataSource": "sample_datasource",
"granularity": "day",
"descending": "true",
"filter": {
"type": "and",
"fields": [
{ "type": "selector", "dimension": "sample_dimension1", "value": "sample_value1" },
{ "type": "or",
"fields": [
{ "type": "selector", "dimension": "sample_dimension2", "value": "sample_value2" },
{ "type": "selector", "dimension": "sample_dimension3", "value": "sample_value3" }
]
}
]
},
"aggregations": [
{ "type": "longSum", "name": "sample_name1", "fieldName": "sample_fieldName1" },
{ "type": "doubleSum", "name": "sample_name2", "fieldName": "sample_fieldName2" }
],
"postAggregations": [
{ "type": "arithmetic",
"name": "sample_divide",
"fn": "/",
"fields": [
{ "type": "fieldAccess", "name": "postAgg__sample_name1", "fieldName": "sample_name1" },
{ "type": "fieldAccess", "name": "postAgg__sample_name2", "fieldName": "sample_name2" }
]
}
],
"intervals": [ "2012-01-01T00:00:00.000/2012-01-03T00:00:00.000" ]
}
上述配置了过滤条件,2个聚合,后聚合器将2个聚合结果进行相除。查询结果如下,查询结果存储在属性result,以键值对方式存储:
[
{
"timestamp": "2012-01-01T00:00:00.000Z",
"result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
},
{
"timestamp": "2012-01-02T00:00:00.000Z",
"result": { "sample_name1": <some_value>, "sample_name2": <some_value>, "sample_divide": <some_value> }
}
]
2.3 排名查询(TopN query)
TopN查询根据规范返回给定维度的有序的结果集,从概念上来讲,TopN查询被认为单维度、有序的类似分组查询。在某些情况下,TopN查询比分组查询(groupby query)快。TopN查询结果返回Json数组对象。 TopN在每个节点将顶上K个结果排名,在Druid默认情况下最大值为1000。在实践中,如果你要求前1000个项顺序排名,那么从第1-999个项的顺序正确性是100%,其后项的结果顺序没有保证。你可以通过增加threshold值来保证顺序准确。
属性 |
描述 |
必填项 |
queryType |
字符串类型,时间序列 "topN" |
是 |
dataSource |
字符串类型,数据源(类似数据库表) |
是 |
intervals |
查询时间范围跨度,JSON对象,ISO-8601区间 |
是 |
granularity |
定义查询结果块粒度 |
是 |
filter |
过滤条件 |
否 |
aggregations |
聚合 |
是 |
postAggregations |
后聚合 |
否 |
dimension |
查询的维度(列) |
是 |
threshold |
返回Top N个结果 |
是 |
metric |
字符串或Json对象指定度量对Top N个结果排序 |
是 |
context |
上下文 |
否
|
Metric
属性 |
描述 |
必填项 |
type |
数字排序 |
是 |
metric |
排序字段 |
是
|
数据排序(Numeric TopNMetricSpec) - 最简单的规范指定一个字符串值指示排序TopN结果的度量
"metric": "<metric_name>"
metric属性通常配置为Json对象,上述等价于:
"metric": {
"type": "numeric",
"metric": "<metric_name>"
}
topN query 配置示例如下:
{
"queryType": "topN",
"dataSource": "sample_data",
"dimension": "sample_dim",
"threshold": 5,
"metric": "count",
"granularity": "all",
"filter": {
"type": "and",
"fields": [
{
"type": "selector",
"dimension": "dim1",
"value": "some_value"
},
{
"type": "selector",
"dimension": "dim2",
"value": "some_other_val"
}
]
},
"aggregations": [
{
"type": "longSum",
"name": "count",
"fieldName": "count"
},
{
"type": "doubleSum",
"name": "some_metric",
"fieldName": "some_metric"
}
],
"postAggregations": [
{
"type": "arithmetic",
"name": "sample_divide",
"fn": "/",
"fields": [
{
"type": "fieldAccess",
"name": "some_metric",
"fieldName": "some_metric"
},
{
"type": "fieldAccess",
"name": "count",
"fieldName": "count"
}
]
}
],
"intervals": [
"2013-08-31T00:00:00.000/2013-09-03T00:00:00.000"
]
}
查询前Top 5个结果,按count排序:
[
{
"timestamp": "2013-08-31T00:00:00.000Z",
"result": [
{
"dim1": "dim1_val",
"count": 111,
"some_metrics": 10669,
"average": 96.11711711711712
},
{
"dim1": "another_dim1_val",
"count": 88,
"some_metrics": 28344,
"average": 322.09090909090907
},
{
"dim1": "dim1_val3",
"count": 70,
"some_metrics": 871,
"average": 12.442857142857143
},
{
"dim1": "dim1_val4",
"count": 62,
"some_metrics": 815,
"average": 13.14516129032258
},
{
"dim1": "dim1_val5",
"count": 60,
"some_metrics": 2787,
"average": 46.45
}
]
}
]
待续。。。
相关推荐
《Druid实时大数据分析原理与实践__欧阳辰》是一本深度探讨Druid系统在实时大数据分析领域的应用和技术细节的专业书籍。Druid作为一个高效、可扩展的开源数据存储和查询引擎,广泛应用于在线分析处理(OLAP)场景,...
《Druid数据分析原理与实践》一书主要涵盖了Druid这一高效大数据分析组件的详细知识,由欧阳辰撰写,是理解数据仓库架构的重要参考资料。Druid以其实时性、高可用性和可扩展性在大数据处理领域备受青睐,尤其适用于...
### Druid与实时多维数据分析 ...综上所述,Druid作为一种先进的实时多维数据分析工具,不仅具备出色的性能,还能适应大规模数据集的需求,成为了现代数据仓库和多维数据分析领域的重要组成部分。
Druid是一个用于大数据实时查询和分析的高容错、高性能开源分布式系统,旨在快速处理大规模的数据,并能够实现快速查询和分析。尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持...
Druid实时大数据分析:原理与实践
Druid实时大数据分析,主要讲的是Druid的使用以及Druid如何与其他大数据插件之间关系
标题所指的知识点为“Druid 源码分析 逐层详解”,意味着我们需要深入分析Druid这一开源数据处理工具的...通过逐层深入,从系统的总体架构到各个组件的具体实现,我们可以全面掌握Druid数据处理工具的设计和实现原理。
从架构上看,Druid采用了类LSM-tree(日志结构合并树)的设计,这种设计非常适合大规模的实时数据分析。通过这种方式,Druid能够优化写入和查询的性能。Druid的一些高级特性还包括支持近似直方图和分位数、预估数据...
首先,Druid数据源监控是其核心特性之一,能够实时展示数据库连接池的状态,包括连接数量、空闲连接、等待连接等关键指标。这有助于开发者了解数据库连接的使用情况,预防资源耗尽的问题。同时,Druid还能记录SQL...
Storm是一个开源的分布式实时计算系统,它可以持续处理数据流,确保每个消息只被处理一次,适用于实时数据分析和事件驱动的应用。而Druid则是一个高性能、分布式的数据存储和查询引擎,特别适合实时分析和大数据聚合...
它既支持高速的数据实时摄入处理,也支持实时且灵活的多维数据分析查询。因此Druid最常用的场景就是大数据背景下、灵活快速的多维OLAP分析。 另外,Druid还有一个关键的特点:它支持根据时间戳对数据进行预聚合摄入...
* 适用于需要监控和扩展功能的应用场景,例如数据分析、数据挖掘等。 Druid 的下载地址: * Maven 中央仓库:http://central.maven.org/maven2/com/alibaba/druid/ * GitHub:https://github.com/alibaba/druid * ...
在本文中,我们将深入探讨如何在SpringBoot项目中配置并使用Druid数据源监控页面。Druid是一个功能强大的数据库连接池,它提供了丰富的监控和管理功能,有助于优化数据库操作和性能。SpringBoot作为轻量级的Java框架...
这份42页的PDF文档《Druid之旅》深入探讨了Druid如何解决传统数据库(如RDBMS)和NoSQL键值存储在大数据分析中的局限性,并阐述了Druid的独特优势。 首先,文档提到了大数据分析的基本需求,包括高效的数据摄入能力...
利用其高效的数据摄入机制(如Kafka、Tranquility),以及灵活的查询接口(如Hive、Spark Streaming等),Druid为知乎提供了快速、多样化的数据分析能力。 3. Druid的数据处理框架:在数据处理流程中,Druid支持从...
本文档主要探讨了如何基于Druid构建大数据采集即计算的实践方案,以提升数据分析的效率和实时性。 首先,大数据架构通常包括各种数据源,如ETL(提取、转换、加载)过程、数据库日志、Web页面日志、开放SQL和Open...
Druid是一款开源的分布式分析型数据库,专为高吞吐量、实时性、高...Druid的设计目标是通过其独特的数据存储模型、实时摄入能力和优化的查询性能来满足大规模数据集的分析需求,尤其是对于那些需要即时反馈的分析场景。
在大数据分析场景中,Druid可以与Hadoop、Spark等其他工具结合,构建端到端的数据分析平台。 总的来说,理解并掌握如何有效地摄入数据和提交任务是使用Druid的关键。通过文中提到的三个示例,读者可以逐步了解并...