druid.io 去重计数

   在大数据分析中,对数据进行计数去重是比较常见的需求,而druid.io中提供了多种去重计数的aggregtions函数,对于这些去重的aggregtions也不尽相同。druid中提供的去重aggregation如下:

   1、DataSketches aggregtions :

    yahoo提供的分析包,此算法也是采用最大估计的算法,在数据摄入阶段(ingestion time),druid会存储sketch 相关数据,在query查询阶段,查询效率也可以更快,此hyperloglog准确一些,速度也快一点。

   简单配置说明:  

"metricsSpec": [
         {
          "name" : "count",
          "type" : "count"
         },
         {
         "name":"sketch_deviceid",
         "type":"thetaSketch",
          "fieldName":"deviceid",
         "isInputThetaSketch":"false",
         "size":"16384"
          }
       ],

   query阶段:

"aggregations": [
    {
       "type": "longSum",
       "name": "count",
       "fieldName": "count"
    },
    {
       "type"  : "thetaSketch",
       "name": "sketch_success",
       "fieldName"  : "sketch_deviceid"
    }        
]

官方参考文档:http://druid.io/docs/latest/development/extensions-core/datasketches-aggregators.html

   2、HyperUnique aggregtions:   

       利用HyperLogLog计算估计值,结果为小数,但需要在indexing time阶段加入“hyperUnique” metric 以支持此aggregation。在摄入阶段进行优化,比Cardinality aggregtions聚合效率要高。

官方参考文档: http://druid.io/docs/latest/querying/aggregations

   3、Cardinality aggregtions : 

  基于HyperLogLog算法,只在查询阶段做了优化,不能减少存储容量,基数大时,效率可能会有问题。

由于在metabase 中对druid数据源采用的是Cardinality aggregtions,所以重点研究了一下。

首先Cardinality aggregtions结果返回值也为估算值小数,在metabase中对于Cardinality 的postaggregation是错误的,是个bug,对于cardinality和hyperUnique的聚合, post-aggregator type 的类型为“finalizingFieldAccess”,而非“fieldAccess”,采用fieldAccess type的话,查询会报 java.lang.ClassCastException 。正确的写法如下:

{ "queryType":"timeseries",
  "dataSource": "out-tvs-timeon.behavior",
  "granularity":{"type":"period","period":"P1D","timeZone":"UTC"},
  "context":{"timeout":60000,"queryId":"2f8cd622-0aca-48a7-8945-f21f869a2886"} ,
  "descending": "true",
  "aggregations": [
    { "type": "count", "name": "___COUNT_209" },
    { "type": "cardinality", "name": "___DISTINCT_210", "fields": ["session_id"],"round":"true" }
  ],
  "postAggregations": [
    { "type": "arithmetic",
      "name": "sample_divide",
      "fn": "/",
      "fields": [
        { "type": "fieldAccess","name":"___COUNT_2091","fieldName": "___COUNT_209" },
        { "type": "finalizingFieldAccess","name":"___DISTINCT_2101","fieldName": "___DISTINCT_210"}
      ]
   }],
 "intervals": ["2018-07-22T00:00:00.000Z/2018-08-23T00:00:00.000Z"]
}

    注意并且当在druid的0.10版本中,上述查询会出现“finalizingFieldAccess not recoginez”,此错误为druid的0.10版本的bug,将druid的版本升级至0.12版本即可。

  类似,druid已支持简单的SQL查询,但在0.10上不支持,需升级druid至0.12

  4、druid-distinctCount:

     第三方community extensions包,结果为整数。效率还未大数据量测试。

     首先需要到maven仓库下载对应druid版本的jar,并druid中的extensions目录下,并建立druid-distinctcount,将jar复制到目录下,并在druid 的common.runtime.properties中添加此extension的配置

druid.extensions.loadList=["mysql-metadata-storage", "druid-hdfs-storage","druid-kafka-indexing-service","kafka-emitter","druid-datasketches","druid-distinctcount"]

   重启druid即可。

但是distinctCount 存在较大的误差,有时候会出现错误,其具有较多限制,也不适合生产环境使用。具体可参照官网

http://druid.io/docs/latest/development/extensions-contrib/distinctcount.html

    综合上述分析,DataSketches 和HyperUnique的聚合效率要比cardinality的高,两者在ingestion 阶段就做了相关优化,cardinality的效率较前两者较低,但这三者的结果都为小数,为估算值,druid-distinctCount的聚合结果为整数,但是存在较多限制,并且在大数据量的效率如何还需验证。

  

猜你喜欢

转载自blog.csdn.net/xiaobai51509660/article/details/82011877