大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图 ...

打印 上一主题 下一主题

主题 875|帖子 875|积分 2625

点一下关注吧!!!非常感谢!!连续更新!!!

目前已经更新到了:



  • Hadoop(已更完)
  • HDFS(已更完)
  • MapReduce(已更完)
  • Hive(已更完)
  • Flume(已更完)
  • Sqoop(已更完)
  • Zookeeper(已更完)
  • HBase(已更完)
  • Redis (已更完)
  • Kafka(已更完)
  • Spark(已更完)
  • Flink(已更完)
  • ClickHouse(已更完)
  • Kudu(已更完)
  • Druid(已更完)
  • Kylin(正在更新…)
章节内容

上节我们完成了如下的内容:


  • 构建Cube 按照日期、区域、产物、渠道
  • Cube 优化方案

增量 Cube



  • 在大多数业务场景下,Hive中的数据处于不停增长的状态
  • 为了支持在构建Cube,无需重复处理惩罚历史数据,引入增量构建功能
Segment

Kylin将Cube划分为多个Segment(对应就是HBase中的一个表)


  • 一个Cube可能由1个或多个Segment组成,Segment是指定时间范围的Cube,可以明白为Cube的分区
  • Segment是针对源数据中的某个片段计算出来的Cube数据,代表一段时间内源数据的预计计算效果
  • 每个Segment用起始时间和结束时间来标记
  • 一个Segment的起始时间等于它之前Segment的结束前时间,它的结束时间等于它后面谁人Segment的起始时间
  • 同一个Cube下差别的Segment除了背后的源数据差别之外,其他如布局定义、构建过程、优化方法、存储方式等完全雷同

Segment示意图


例如:以下为针对某个Cube的Segment

全量构建与增量构建

全量构建

在全量构建中:


  • Cube中存在唯逐一个Segment
  • 每Segment没有分割时间的概念,即没有起始时间和结束时间
  • 对于全量构建来说,每当需要更新Cube数据时,它不会区分历史数据和新加入的数据,即在构建时导入并处理惩罚全部的数据
增量构建

在增量构建中:


  • 只会导入新Segment指定的时间区间内的原始数据,并只对这部分原始数据举行预计算
相互对比


全量构建与增量构建的Cube查询的方式对比:
全量构建Cube:


  • 查询引擎只需要向存储引擎访问单个Segment所对应的数据,无需举行Segment之间的聚合
  • 为了增强性能,单个Segment的数据也有可能被分片存储到引擎的多个分区上,查询引擎可能仍然需要对单个Segment差别分区的数据进一步聚合
增量构建Cube:


  • 由于差别的时间的数据分布在差别的Segment中,查询引擎需要向存储引擎请求读取各个Segment的数据
  • 增量构建的Cube上的查询会比全量构建的做更多的运行时聚合,通常来说增量构建的Cube上查询会比全量构建的Cube上的查询要慢一些
对于小数据量的Cube,大概常常需要全表更新的Cube,使用全量构建需要更少的运维精力,以少量的重复计算降低生产情况中的维护复杂度。
对于大数据量的Cube,例一个包含较长历史数据的Cube,如果每天更新,那么大量的资源是在用于重复计算,这个情况下可以考虑使用增量构建。
增量构建Cube过程

指定分割时间列

增量构建Cube的定义必须包含一个时间维度,用来分割差别的Segment,如许的维度称为分割时间列(Partition Date Column)。
增量构建过程



  • 在举行增量构建时,将增量部分的起始时间和结束时间作为增量构建请求的一部分提交给Kylin的使命引擎
  • 使命引擎会根据起始时间和结束时间从Hive中抽取相应时间的数据,并对这部分数据做预处理惩罚计算
  • 将预计算的效果封装成一个新的Segment,并将相应的信息生存到元数据和存储引擎中,一般来说,增量部分的起始时间等于Cube中末了一个Segment的结束时间
增量Cube构建

步调:定义数据源 => 定义Model => 定义Cube => 构建Cube
SQL 语句

  1. -- 数据结构类似,只是改为了分区表
  2. drop table wzk_kylin.dw_sales1;
  3. create table wzk_kylin.dw_sales1(
  4.   id string,
  5.   channelId string,
  6.   productId string,
  7.   regionId string,
  8.   amount int,
  9.   price double
  10. )
  11. partitioned by (dt string)
  12. ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
  13. -- 加载数据
  14. load data local inpath "dw_sales20240101_data.txt"
  15. into table wzk_kylin.dw_sales1
  16. partition(dt="2024-01-01");
  17. load data local inpath "dw_sales20240102_data.txt"
  18. into table wzk_kylin.dw_sales1
  19. partition(dt="2024-01-02");
  20. load data local inpath "dw_sales20240103_data.txt"
  21. into table wzk_kylin.dw_sales1
  22. partition(dt="2024-01-03");
  23. load data local inpath "dw_sales20240104_data.txt"
  24. into table wzk_kylin.dw_sales1
  25. partition(dt="2024-01-04");
复制代码
生成数据

同样,我们先编写一个脚本来生成对应的数据:
  1. import random
  2. # 设置参数
  3. dates = ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04"]
  4. num_records_per_file = 100
  5. # 定义可能的值
  6. channel_ids = ['C001', 'C002', 'C003', 'C004']
  7. product_ids = ['P001', 'P002', 'P003', 'P004']
  8. region_ids = ['R001', 'R002', 'R003', 'R004']
  9. # 生成数据
  10. for dt in dates:
  11.     output_file = f'dw_sales{dt.replace("-", "")}_data.txt'
  12.    
  13.     with open(output_file, 'w') as f:
  14.         for i in range(num_records_per_file):
  15.             record_id = f"{i+1:04d}"
  16.             channel_id = random.choice(channel_ids)
  17.             product_id = random.choice(product_ids)
  18.             region_id = random.choice(region_ids)
  19.             amount = random.randint(1, 100)
  20.             price = round(random.uniform(10.0, 500.0), 2)
  21.             
  22.             line = f"{record_id},{channel_id},{product_id},{region_id},{amount},{price}\n"
  23.             f.write(line)
  24.    
  25.     print(f"{num_records_per_file} records have been written to {output_file}")
  26. print("All data files have been generated.")
复制代码
执行的效果如下图所示:

上传数据

通过你习惯的方式,将这几个txt上传到服务器上,预备执行:

执行脚本

  1. hive -f kylin_partition.sql
复制代码
执行效果如下图:

加载数据源

Load Table From Tree

选择刚才创建的表,wzk_kylin.dw_sales1:

定义Model

增量构建的Cube需要指定分割时间列,例如:将日期分区字段添加到维度列中:
Data Model:New Join Condition,需要设置好几个:

设置成如下的效果:

维度设置如下图所示:

度量选择 AMOUNT 和 PRICE,末了的设置:

定义Cube

填写名字等跳过,维度需要添加 DT、其他都要:

设置完的效果如下图:

度量设置如下:(Bulk Add Measures 快速设置)

剩余的信息都默认填写即可:

构建Cube

接下来构建Cube的时候,举行Build:

选部分的日期,就不选全部数据了:

继续等待构建完毕:

查看Segment

刚才我们构建了


  • 2024-01-01 到 2024-01-02 的数据
  • 我们继续build 2024-01-02 到 2024-01-03
  • 完成后继续build 2024-01-03 到 2024-01-04
    分段的举行build的使命,末了我们查看 Segment如下:
2024-01-01 到 2024-01-02 完成之后,我们继续使命:

2024-01-02 到 2024-01-03 完成之后,我们继续使命:

漫长等待,使命都完成之后如下图所示:

查询测试

第一部分:按日期和地区汇总销售数据
  1. -- 第一部分查询:按日期和地区汇总销售数据
  2. SELECT
  3.     t1.dt,
  4.     t2.regionname,
  5.     SUM(t1.price) AS total_money,
  6.     SUM(t1.amount) AS total_amount,
  7.     MAX(t1.price) AS max_price,
  8.     MIN(t1.amount) AS min_amount
  9. FROM
  10.     dw_sales1 t1
  11. JOIN
  12.     dim_region t2
  13. ON
  14.     t1.regionid = t2.regionid
  15. GROUP BY
  16.     t1.dt,
  17.     t2.regionname
  18. ORDER BY
  19.     t1.dt;
复制代码
运行的效果如下图所示:

另一部分:按日期、地区和产物汇总销售数据
  1. -- 第二部分查询:按日期、地区和产品汇总销售数据
  2. SELECT
  3.     t1.dt,
  4.     t2.regionid,
  5.     t2.regionname,
  6.     t3.productid,
  7.     t3.productname,
  8.     SUM(t1.price) AS total_money,
  9.     SUM(t1.amount) AS total_amount
  10. FROM
  11.     dw_sales1 t1
  12. INNER JOIN
  13.     dim_region t2
  14. ON
  15.     t1.regionid = t2.regionid
  16. INNER JOIN
  17.     dim_product t3
  18. ON
  19.     t1.productid = t3.productid
  20. GROUP BY
  21.     t1.dt,
  22.     t2.regionid,
  23.     t2.regionname,
  24.     t3.productid,
  25.     t3.productname
  26. ORDER BY
  27.     t1.dt,
  28.     t2.regionname,
  29.     t3.productname;
复制代码
查询效果如下图所示:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农妇山泉一亩田

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表