【实时数仓】DWS层访客主题计算(续)、商品主题计算

一 DWS层-访客主题计算

1 写入OLAP数据库

(1)增加ClickhouseUtil

a JdbcSink.sink( )的四个参数说明
  • 参数1: 传入Sql,格式如:insert into xxx values(?,?,?,?)
  • 参数2: 可以用lambda表达实现(jdbcPreparedStatement, t) -> t为数据对象,要装配到语句预编译器的参数中。
  • 参数3:设定一些执行参数,比如重试次数,批次大小。
  • 参数4:设定连接参数,比如地址,端口,驱动名。
b ClickhouseUtil中获取JdbcSink函数的实现
package com.hzy.gmall.realtime.utils;
/**
 * 操作ClickHouse的工具类
 */
public class ClickhouseUtil {
   
   
    public static <T> SinkFunction<T> getJdbcSink(String sql){
   
   
        // "insert into visitor_stats_2022 values(?,?,?,?,?,?,?,?,?,?,?,?)"
        SinkFunction<T> sinkFunction = JdbcSink.<T>sink(
                sql,
                new JdbcStatementBuilder<T>() {
   
   
                    // 参数 T obj:就是流中的一条数据
                    @Override
                    public void accept(PreparedStatement ps, T obj) throws SQLException {
   
   
                        // 获取流中obj属性值,赋值给问号

                    }
                },
                // 构造者设计模式
                new JdbcExecutionOptions.Builder()
                        // 5条数据为一批,一批处理一次
                        // 4个并行度,每一个slot数量到5,才会保存到ClickHouse
                        .withBatchSize(5)
//                        // 2s后直接保存到ClickHouse
//                        .withBatchIntervalMs(2000)
//                        // 最大重试次数为3
//                        .withMaxRetries(3)
                        .build(),
                new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
                        .withDriverName("ru.yandex.clickhouse.ClickHouseDriver")
                        .withUrl(GmallConfig.CLICKHOUSE_URL)
                        .build()
        );
        return sinkFunction;
    }
}
c 构造者设计模式

在设置一个对象属性值时,通常方式有两种:

第一种
Animal animal=new Animal("XX","XXkg","XX");
第二种
Animal animal=new Animal();
animal.setAge("XX");
animal.setweight("XXkg");
animal.setFood("XX");
  • 第一种方式::相当于在构造函数里传递参数,但这样加入参数的时候,如果属性过多,不能明确的知道往这个对象里加入了哪种属性的内容。
  • 第二种方式:虽然可以根据set函数名看到将要设置的值是什么值,但是这种写法,略显冗余。

在设计模式中有构造者模式(builder),在类的构造器或静态工厂具有多个参数。设计这种类时,builder模式就是个不错的选择。

构造者就是在外部类中创建的一个内部类,然后在内部类中对属性赋值,一次赋值完成后,返回的类型是内部类自己,而上面的第二种赋值方式没有返回值,不可以链式赋值,而构造者模式可以进行链式赋值。在经过许多步赋值操作之后,通过.build()方法通过内部类去创建外部类对象。

详情见Java的构造者模式(builder)

d 赋值给问号占位符并创建TransientSink注解

该注解标记不需要保存的字段。

由于之前的ClickhouseUtil工具类的写入机制就是把该实体类的所有字段按次序一次写入数据表。但是实体类有时会用到一些临时字段,计算中有用但是并不需要最终保存在临时表中。我们可以把这些字段做一些标识,然后再写入的时候判断标识来过滤掉这些字段。

为字段打标识通常的办法就是给字段加个注解,这里就增加一个自定义注解@TransientSink来标识该字段不需要保存到数据表中。

new JdbcStatementBuilder<T>() {
   
   
    // 参数 T obj:就是流中的一条数据
    // 获取流中对象obj的属性值,赋值给问号占位符
    @Override
    public void accept(PreparedStatement ps, T obj) throws SQLException {
   
   
        // 获取流中对象所属类的属性
        Field[] fields = obj.getClass().getDeclaredFields();
        int skipNum = 0;
        // 对属性数组进行遍历
        for (int i = 0; i < fields.length; i++) {
   
   
            // 获取每一个属性对象
            Field field = fields[i];
            // 判断该属性是否有@trannsient注解修饰
            TransientSink transientSink = field.getAnnotation(TransientSink.class);
            if (transientSink != null){
   
   
                skipNum++;
                continue;
            }
            // 设置私有属性的访问权限
            field.setAccessible(true);
            try {
   
   
                // 获取对象的属性值
                Object fieldValue = field.get(obj);
                // 将属性的值赋值给问号占位符
                // JDBC相关操作和查询结果集的列从1开始
                ps.setObject(i+1-skipNum,fieldValue);
            } catch (IllegalAccessException e) {
   
   
                e.printStackTrace();
            }
        }
    }
}
e 在GmallConfig中配置ClickHouse的连接地址
public static final String CLICKHOUSE_URL = "jdbc:clickhouse://hadoop101:8123/default";
f 为主程序增加写入ClickHouse的Sink
// TODO 9 将聚合统计之后的数据写到ClickHouse
reduceDS.addSink(
        ClickhouseUtil.getJdbcSink("insert into visitor_stats_2022 values(?,?,?,?,?,?,?,?,?,?,?,?)")
);

(2)整体测试

  • 启动ZK、Kafka、logger.sh、ClickHouse、【HDFS】
  • 运行BaseLogApp
  • 运行UniqueVisitApp
  • 运行UserJumpDetailApp
  • 运行VisitorStatsApp
  • 运行rt_applog目录下的jar包
  • 查看控制台输出
  • 查看ClickHouse中visitor_stats_2022表数据

ClickHouse中数据如下:

在这里插入图片描述

二 DWS层-商品主题计算

统计主题 需求指标 输出方式 计算来源 来源层级
商品 点击 多维分析 page_log dwd
曝光 多维分析 page_log dwd
收藏 多维分析 favor_info dwd
加入购物车 多维分析 cart_info dwd
下单 可视化大屏 order_wide dwm
支付 多维分析 payment_wide dwm
退款 多维分析 order_refund_info dwd
评价 多维分析 comment_info dwd

与访客的dws层的宽表类似,也是把多个事实表的明细数据汇总起来组合成宽表

1 需求分析与思路

  • 从Kafka主题中获得数据流
  • 把Json字符串数据流转换为统一数据对象的数据流
  • 把统一的数据结构流合并为一个流
  • 设定事件时间与水位线
  • 分组、开窗、聚合
  • 写入ClickHouse

整体流程如下图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OneTenTwo76

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值