Apache Kylin中对上亿字符串的精确Count_Distinct示例

简介:

如果业务中能接受1.22%的误差,那么肯定首选近似算法,因为它能节省很多资源和时间。如果业务中必须使用精确去重,那么就看看本文的例子(针对上亿字符串的精确去重)。

事实表


  
  
  1. hive> desc test_t_pbs_uv_fact; 
  2. OK 
  3. ad_id                   string  //维度 
  4. material_id             string   //维度 
  5. city_code               string  //维度 
  6. user_id                 string   //指标,需要精确Count Distinct 
  7. bid_request             bigint  //指标,SUM 
  8. device_bid_request      bigint      //指标,SUM 
  9. win                     bigint  //指标,SUM  
  10. ck                      bigint  //指标,SUM  
  11. pt                      string  //维度,日期,yyyy-MM-dd 
  12.   

该事实表一天的数据记录大概1.5亿+,其中user_id为字符串,类似MD5后的字符串。

创建Model

在Kylin中创建名为lxw1234_uv_model的模型。

选择维度和指标字段:

创建Cube

创建名为lxw1234_uv_cube的Cube,其中,指标定义如下:

其他请按实际业务需求配置。

手动修改Cube(JSON)

如果不修改,精确Count Distinct使用了Default dictionary来保存编码后的user_id,而Default dictionary的最大容量为500万,并且,会为每个Segment生成一个Default dictionary,这样的话,跨天进行UV分析的时候,便会产生错误的结果,如果每天不重复的user_id超过500万,那么build的时候会报错:


  
  
  1. java.lang.IllegalArgumentException: Too high cardinality is not suitable for dictionary — cardinality: 43377845  
  2. at org.apache.kylin.dict.DictionaryGenerator.buildDictionary(DictionaryGenerator.java:96) 
  3. at org.apache.kylin.dict.DictionaryGenerator.buildDictionary(DictionaryGenerator.java:73) 

该值由参数 kylin.dictionary.max.cardinality 来控制,当然,你可以修改该值为1亿,但是Build时候可能会因为内存溢出而导致Kylin Server挂掉:


  
  
  1. # java.lang.OutOfMemoryError: Requested array size exceeds VM limit  
  2. # -XX:OnOutOfMemoryError=”kill -9 %p”  
  3. # Executing /bin/sh -c “kill -9 16193″… 

因此,这种需求我们需要手动使用Global Dictionary,顾名思义,它是一个全局的字典,不分Segments,同一个user_id,在全局字典中只有一个ID。

目前Kylin的UI中没有可以直接配置Global Dictionary的地方,需要手动修改Cube的JSON描述:

在状态为DISABLED的Cube列表中,点击”Admins”菜单下的”Edit(JSON)”,进入Cube JSON描述的编辑页面,

添加下面的JSON

其中,在override_kylin_properties 中增加了两个Cube的配置参数,用于增加Mapper的运行内存。


  
  
  1. "dictionaries": [ 
  2.     { 
  3.       "column""USER_ID"
  4.       "builder""org.apache.kylin.dict.GlobalDictionaryBuilder" 
  5.     } 
  6.   ] 

定义了对USER_ID字段使用全局字典。

之后,保存JSON。

Build与查询

Build完成后,在Hive和Kylin中执行下面的查询:

SELECT city_code,SUM(bid_request) AS bid_request,COUNT(DISTINCT user_id) AS uvFROM liuxiaowen.TEST_T_PBS_UV_FACTGROUP BY city_codeORDER BY uv DESC limit 30;

Hive中耗时:181.134 seconds

Kylin中耗时:9 seconds

查询结果完全一致:

Global Dictionary存在问题

由于Global Dictionary 底层基于bitmap,其最大容量为Integer.MAX_VALUE,即21亿多,如果全局字典中,累计值超过Integer.MAX_VALUE,那么在Build时候便会报错。

因此,使用全局字典还是有容量的限制。


本文作者:佚名

来源:51CTO

相关文章
|
2月前
|
消息中间件 分布式计算 大数据
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
75 5
|
2月前
|
存储 SQL 分布式计算
大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图
大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图
65 3
|
2月前
|
Java 大数据 数据库连接
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
33 2
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
|
2月前
|
SQL 分布式计算 NoSQL
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
36 1
大数据-164 Apache Kylin Cube优化 案例1 定义衍生维度与对比 超详细
|
2月前
|
SQL 存储 分布式计算
大数据-157 Apache Kylin 背景 历程 特点 场景 架构 组件 详解
大数据-157 Apache Kylin 背景 历程 特点 场景 架构 组件 详解
41 9
|
2月前
|
分布式计算 大数据 分布式数据库
大数据-158 Apache Kylin 安装配置详解 集群模式启动(一)
大数据-158 Apache Kylin 安装配置详解 集群模式启动(一)
49 5
|
2月前
|
SQL 分布式计算 大数据
大数据-160 Apache Kylin 构建Cube 按照日期构建Cube 详细记录
大数据-160 Apache Kylin 构建Cube 按照日期构建Cube 详细记录
48 2
|
2月前
|
资源调度 大数据 分布式数据库
大数据-158 Apache Kylin 安装配置详解 集群模式启动(二)
大数据-158 Apache Kylin 安装配置详解 集群模式启动(二)
50 2
|
2月前
|
存储 大数据 分布式数据库
大数据-165 Apache Kylin Cube优化 案例 2 定义衍生维度及对比 & 聚合组 & RowKeys
大数据-165 Apache Kylin Cube优化 案例 2 定义衍生维度及对比 & 聚合组 & RowKeys
47 1
|
2月前
|
SQL 消息中间件 大数据
大数据-159 Apache Kylin 构建Cube 准备和测试数据(一)
大数据-159 Apache Kylin 构建Cube 准备和测试数据(一)
72 1

推荐镜像

更多
下一篇
DataWorks