Druid查询

概述

Druid查询是通过HTTP REST方式发送查询请求,查询的描述写在一个JSON文件中,可以处理查询请求的服务包括Broker、Historical和Realtime,这几个服务节点都提供了相同的查询接口,但一般是将查询请求发送至Broker节点,由Broker节点根据查询的数据源来转发至Historical或者RealTime节点。

另外,目前已有很多开源的使用其他语言查询Druid数据的包。具体可参考:http://druid.io/docs/latest/development/libraries.html

Druid自带的JSON+HTTP的查询方式,使用的数据源为lxw1234。

执行查询(这里指定的是Broker Node的地址):

curl -X POST 'http://node2:8092/druid/v2/?pretty' -H 'content-type: application/json' -d @query.json

Druid关于Query的官方文档地址在:http://druid.io/docs/latest/querying/querying.html

查询分类:

基本的查询有三类:聚合查询(Aggregation Queries)、元数据查询(Metadata Queries)和搜索查询(Search Queries)。

  • 聚合查询(Aggregation Queries)
    • Timeseries
    • TopN
    • GroupBy
  • 元数据查询(Metadata Queries)
    • TimeBoundary
    • SegmentMetadata
    • DatasourceMetadata
  • 搜索查询(Search Queries)
    • Search

1、聚合查询(Aggregation Queries)

聚合查询就是指标数据根据一定的规则,在一个或多个维度上进行聚合。

分为三类:

  • Timeseries
  • TopN
  • GroupBy

1.1 Timeseries

Timeseries查询根据指定的时间区间及时间间隔进行聚合查询,在查询中还可以指定过滤条件,需要聚合的指标列、等。

timeseries 查询包括如下的字段:

字段名 描述 是否必须
queryType 查询类型,这里只有填写timeseries查询
dataSource 要查询的数据源
intervals 查询的时间范围,默认是ISO-8601格式
granularity 查询结果进行聚合的时间粒度(时间间隔)
aggregations 聚合的类型、字段及结果显示的名称
postAggregations 后期聚合
filter 过滤条件
descending 是否降序
context 指定一些查询参数

timeseries输出每个时间粒度内指定条件的统计信息,通过filter指定条件过滤,通过aggregations和postAggregations指定聚合方式。timeseries不能输出维度信息,granularity支持all,none,second,minute,hour,day,week,month,year等维度。

一个简单的Timeseries查询配置文件如下:

{
    "queryType": "timeseries",
    "dataSource": "lxw1234",
    "intervals": [ "2015-11-15/2015-11-18" ],
    "granularity": "day",
    "aggregations": [
        {"type": "longSum", "fieldName": "count", "name": "total_count"}
    ]
}

运行结果:
在这里插入图片描述
Zero-filling:
一般情况下,使用Timeseries查询按天汇总,而某一天没有数据(被过滤掉了),那么在结果中会显示该天的汇总结果为0。比如上面的数据,假设2015-11-15这一天没有符合条件的数据,那么结果会变成:

{
  "timestamp" : "2015-11-15T00:00:00.000Z",
  "result" : {
    "total_count" : 0
  }
}

如果不希望这种数据出现在结果中,那么可以使用context选项来去掉它,context是用来指定一些查询参数,配置如下:

"context" : {
    "skipEmptyBuckets": "true"
 }

1.2 TopN(TopN queries)

TopN就是基于一个维度GroupBy,然后按照汇总后的指标排序,取TopN.

在Druid中,TopN查询要比相同实现方式的GroupBy+Ordering效率快。

实现原理上,其实也就是分而治之,比如取Top10,由每个任务节点各自取Top10,然后统一发送至Broker,由Broker从各个节点的Top10中,再汇总出最终的Top10.

TopN 查询包括如下的字段:

字段名 描述 是否必须
queryType 查询类型,这里只有填写timeseries查询
dataSource 要查询的数据源
intervals 查询的时间范围,默认是ISO-8601格式
granularity 查询结果进行聚合的时间粒度(时间间隔)
dimension 进行TopN查询的维度,一个TopN查询只能有一个维度
threshold TopN中的N值
metric 进行统计并排序的metric
aggregations 聚合的类型、字段及结果显示的名称
postAggregations 后期聚合
filter 过滤条件
context 指定一些查询参数

一个简单的TopN查询配置文件:

{
  "queryType": "topN",
  "dataSource": "lxw1234",
  "granularity": "day",
  "dimension": "cookieid",
  "metric": "total_count",
  "threshold" : 3,
  "aggregations": [
    {"type": "longSum", "fieldName": "count", "name": "total_count"}
  ],
  "intervals": ["2015-11-17/2015-11-18"]
}

该查询查出每天pv最多的Top 3 cookieid,查询结果:
在这里插入图片描述
注意:metric:是TopN专属
metric 配置方式:

"metric":"<metric_name>" 默认情况是升序排序的
 
"metric" : {
    "type" : "numeric", //指定按照numeric 降序排序
    "metric" : "<metric_name>"
}
 
"metric" : {
    "type" : "inverted", //指定按照numeric 升序排序
    "metric" : "<metric_name>"
}
 
"metric" : {
    "type" : "lexicographic", //指定按照字典序排序
    "metric" : "<metric_name>"
}
 
"metric" : {
    "type" : "alphaNumeric", //指定按照数字排序
    "metric" : "<metric_name>"
}

1.3 GroupBy

GroupBy聚合查询就是在多个维度上,将指标聚合。Druid中建议,能用TimeseriesQueries和TopN实现的查询尽量不要用GroupBy,因为GroupBy的性能要差一些。

// TODO
参考:http://lxw1234.com/archives/2015/11/561.htm

2、元数据查询(Metadata Queries)

2.1 时间范围查询(Time Boundary Queries)

时间范围查询用来查询一个数据源的最小和最大时间点。

{
    "queryType" : "timeBoundary",
    "dataSource": "lxw1234"
}

查询结果:

[ {
  "timestamp" : "2015-11-15T00:00:00.000+08:00",
  "result" : {
    "minTime" : "2015-11-15T00:00:00.000+08:00",
    "maxTime" : "2015-11-18T23:59:59.000+08:00"
  }
} ]

另外,还有个bound选项,用来指定返回最大时间点还是最小时间点,如果不指定,则两个都返回:

{
    "queryType" : "timeBoundary",
    "dataSource": "lxw1234",
    "bound": "maxTime"
}

此时只返回最大时间点:

[ {
  "timestamp" : "2015-11-18T23:59:59.000+08:00",
  "result" : {
    "maxTime" : "2015-11-18T23:59:59.000+08:00"
  }
} ]

2.2 Segments元数据查询(Segment Metadata Queries)

Segments元数据查询可以查询到每个Segment的以下信息:

  • 列名
  • Segment中所有列的基数(Cardinality),非STRING类型的列为null;
  • 每个列的预计大小(Bytes);
  • 该Segment的时间跨度;
  • 列的类型;
  • 该Segment的预估总大小;
  • Segment ID;

查询配置:

{
  "queryType":"segmentMetadata",
  "dataSource":"lxw1234",
  "intervals":["2015-11-15/2015-11-19"]
}

查询结果(只取了一个Segment):

{
  "id" : "lxw1234_2015-11-17T00:00:00.000+08:00_2015-11-18T00:00:00.000+08:00_2015-11-18T16:53:02.158+08:00_1",
  "intervals" : [ "2015-11-17T00:00:00.000+08:00/2015-11-18T00:00:00.000+08:00" ],
  "columns" : {
    "__time" : {
      "type" : "LONG",
      "size" : 46837800,
      "cardinality" : null,
      "errorMessage" : null
    },
    "cookieid" : {
      "type" : "STRING",
      "size" : 106261532,
      "cardinality" : 1134359,
      "errorMessage" : null
    },
    "count" : {
      "type" : "LONG",
      "size" : 37470240,
      "cardinality" : null,
      "errorMessage" : null
    },
    "ip" : {
      "type" : "STRING",
      "size" : 63478131,
      "cardinality" : 735562,
      "errorMessage" : null
    }
  },
  "size" : 272782823
}

2.3 数据源元数据查询(Data Source Metadata Queries)

这个查询只是返回该数据源的最后一次有数据进入的时间。

比如,查询配置文件:

{
    "queryType" : "dataSourceMetadata",
    "dataSource": "lxw1234"
}

结果为:

[ {
  "timestamp" : "2015-11-18T23:59:59.000+08:00",
  "result" : {
    "maxIngestedEventTime" : "2015-11-18T23:59:59.000+08:00"
  }
} ]

3、搜索查询(Search Queries)

select 类似于sql中select操作,select用来查看druid中的存储的数据,并支持按照指定过滤器和时间段查看指定维度和metric,能通过descending字段指定排序顺序,并支持分页拉取,但不支持aggregations和postAggregations。

json 实例如下:

{
  "queryType": "select",
  "dataSource": "app_auto_prem_qd_pp3", 
  "granularity": "all", 
  "intervals": "1917-08-25T08:35:20+00:00/2017-08-25T08:35:20+00:00",
  "dimensions": [
      "status",
      "is_new_car"
  ], 
  "pagingSpec":{
  "pagingIdentifiers":{},
  "threshold":
  },
  "context" : {
   "skipEmptyBuckets" : "true"
  }
}

相当于SQL语句

select status,is_new_car from app_auto_prem_qd_pp3 limit 3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章