Flink实时数仓项目—DWS层设计与实现


前言

在前面通过使用分流等方法,把数据拆分成了独立的Kafka Topic,接下来我们就要根据需求得出要计算哪些指标项。我们把指标以主题宽表的形式输出就是DWS层要做的事情。


一、需求梳理

1.需求梳理

项目需求整理如下:
在这里插入图片描述

2.DWS层定位

1)轻度聚合。因为DWS层要应对很多事实查询,如果是完全的明细那么查询的压力是非常大的。
2)将更多的实时数据以主题的方式组合起来便于管理,同时也能减少维度查询的次数。

二、DWS层—访客主题宽表的实现

1.访客主题的需求

在这里插入图片描述

2.访客主题宽表的设计

DWS层中一张主题宽表包括两部分内容:维度数据+度量值(事实数据)
维度数据:维度数据就是数据里面的一些维度信息,这里就指的是日志数据里面的渠道、地区、版本、新老用户等这些数据
度量值:度量值就是上面的需求指标,这里就是PV、UV、跳出次数(这里不是要算出具体结果的,只是轻度聚合)、进入页面次数、连续访问时长

3.实现思路

在观察统计出来的需求表,一些需求指标需要的是DWD层的数据,一些需求指标需要的是DWM层的数据,所以对应了好几个Topic主题,我们要从不同的主题中读取数据,然后把读取到的数据转化为定义的主题宽表的对象,然后再UNION起来。

4.代码实现

1)首先,我们要建一个访客主题的宽表的实体类,用来保存结果。我们需要渠道、地区、新老用户标识、版本这四个维度(根据需求来,其余维度可选),其次,我们的度量值是独立访客数、页面访问数、首次进入页面次数、跳出页面次数、访问页面时间这几个度量值,然后因为是开窗统计,所以为了区分是哪个窗口,要加上窗口开始时间和结束时间。最后,开窗需要事件时间语义,那么就需要提取时间戳,所以要一个时间戳字段,实体类如下:

@Data
@AllArgsConstructor
public class VisitorStats {
   
    //统计开始时间,为了区分是哪个窗口
    private String stt;
    //统计结束时间
    private String edt;
    //维度:版本
    private String vc;
    //维度:渠道
    private String ch;
    //维度:地区
    private String ar;
    //维度:新老用户标识
    private String is_new;
    //度量:独立访客数
    private Long uv_ct=0L;
    //度量:页面访问数
    private Long pv_ct=0L;
    //度量: 进入次数
    private Long sv_ct=0L;
    //度量: 跳出次数
    private Long uj_ct=0L;
    //度量: 持续访问时间
    private Long dur_sum=0L;
    //统计时间
    private Long ts;
}

2)我们根据需求可以知道,总共需要Kafka的dwd_page_log、dwm_unique_visit、dwm_user_jump_detail三个主题的数据,所以,先从这些主题中读取相应的数据,代码如下:

    //2、分别从对应的主题中读取需要的数据
    String pageViewSourceTopic = "dwd_page_log";
    String uniqueVisitSourceTopic = "dwm_unique_visit";
    String userJumpDetailSourceTopic = "dwm_user_jump_detail";
    String groupId = "visitor_stats_app";

    DataStreamSource<String> pageViewDS = env.addSource(MyKafkaUtil.getKafkaSource(pageViewSourceTopic, groupId));
    DataStreamSource<String> uniqueVisitDS = env.addSource(MyKafkaUtil.getKafkaSource(uniqueVisitSourceTopic, groupId));
    DataStreamSource<String> userJumpDS = env.addSource(MyKafkaUtil.getKafkaSource(userJumpDetailSourceTopic, groupId));

3)读取到相应的数据后,拿dwm_user_jump_detail这个主题来说,这个主题存放的是用户跳出页面的次数,它只是用来求这部分的数据的,所以它求的是VisitorStats实体类中的uj_ct这个变量值;dwm_unique_visit这个主题里是只求uv_ct这个变量值的;dwd_page_log这个主题是最全的页面日志,用来求页面总访问次数、页面浏览时间和第一次进入页面的次数的。
**可以看出,这三个流分别求的是实体类中不同的字段,所以我们可以先将它们转化为实体类,将自己能够求的值设置为1或别的,然后将三个流union起来,再进行聚合操作,就可以得到在一个窗口内的一个实体类,这个实体类里面的变量是最终的和。**代码如下:

    //3、将数据的格式转换成相同的主题宽表对象格式
    //处理PV数据
    SingleOutputStreamOperator<VisitorStats> visitorStatsWithPvDS = pageViewDS.map(data -> {
   
        //页面日志数据可以统计出PV、进入页面数、连续访问时长
        JSONObject jsonObject = JSON.parseObject(data);
        //获取维度信息
        JSONObject common = jsonObject.getJSONObject("common");
        //获取页面信息
        JSONObject page = jsonObject.getJSONObject("page");
        //获取上个页面id
        String last_page_id = page.getString("last_page_id");
        //判断上个页面id是否为null
        Long sv=0L;
        if(last_page_id==null || last_page_id.length()==0)
            sv=1L;
        return new VisitorStats("", "",
                common.getString("vc"),
                common.getString("ch"),
                common.getString("ar"),
                common.getString("is_new"),
                0L, 1L, sv, 0L, page.getLong("during_time"),
                jsonObject.getLong("ts"));
    });

    //处理UV数据
    SingleOutputStreamOperator<VisitorStats> visitorStatsWithUvDS = uniqueVisitDS.map(data -> {
   
        //UV数据可以统计出uv数据
        JSONObject jsonObject = JSON.parseObject(data);
        //获取维度信息
        JSONObject common = jsonObject.getJSONObject("common");
        return new VisitorStats("", "",
                common.getString("vc"),
                common.getString("ch"),
                common.getString("ar"),
                common.getString("is_new"),
                1L, 0L, 0L, 0L, 0L,
                jsonObject.getLong("ts"));
    });

    //处理UJ数据
    SingleOutputStreamOperator<VisitorStats> visitorStatsWithUjDS = userJumpDS.map(data -> {
   
        //UJ数据可以统计出跳出页面的次数
        JSONObject jsonObject = JSON.parseObject(data);
        //获取维度信息
        JSONObject common = jsonObject.getJSONObject("common");
        return new VisitorStats("", "",
                common.getString("vc"),
                common.getString("ch"),
                common.getString("ar"),
                common.getString("is_new"),
                0L, 0L, 0L, 1L, 0L,
                jsonObject.getLong("ts"));
    });


    //4、将几个流Union起来
    DataStream<VisitorStats> unionDS = visitorStatsWithPvDS.union(visitorStatsWithUvDS, visitorStatsWithUjDS);

4)经过上面的步骤得到了union之后的流,我们要开窗做计算,所以需要提取水位线生成时间戳,然后开窗计算。因为这里需要提取窗口的开始时间和结束时间,所以可以选择process或者增量函数+全窗口函数。这里选择增量函数+全窗口函数的方法在增量函数中进行规约计算,然后将结果发送到全窗口函数中进行加工,提取窗口开始时间和结束时间,再向下游进行传输。代码如下:

    //6、按照维度信息进行分组
    KeyedStream<VisitorStats, Tuple4<String, String, String, String>> keyedStream = visitorStatsWithWMDS.keyBy(data -> Tuple4.of(data.getVc(), data.getCh(), data.getAr(), data.getIs_new()));

    //7、开窗聚合,10s的滚动窗口
    SingleOutputStreamOperator<VisitorStats> resultDS = keyedStream.window(TumblingEventTimeWindows.of(Time.seconds(10)))
            .reduce(new ReduceFunction<VisitorStats>() {
   
                @Override
                public VisitorStats reduce(VisitorStats visitorStats, VisitorStats t1) throws Exception {
   
                    return new VisitorStats("", "",
                            visitorStats.getVc(),
                            visitorStats.getCh(),
                            visitorStats.getAr(),
                            visitorStats.getIs_new(),
                            visitorStats.getUv_ct() 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
应用业务对实时数据的需求,主要包含两部分内容:1、 整体数据的实时分析。2、 AB实验效果的实时监控。这几部分数据需求,都需要进行的下钻分析支持,我们希望能够建立统一的实时OLAP数据仓库,并提供一套安全、可靠的、灵活的实时数据服务。目前每日新增的曝光日志达到几亿条记录,再细拆到AB实验更细维度时,数据量则多达上百亿记录,多维数据组合下的聚合查询要求秒级响应时间,这样的数据量也给团队带来了不小的挑战。OLAP的技术选型,需要满足以下几点:1:数据延迟在分钟级,查询响应时间在秒级2:标准SQL交互引擎,降低使用成本3:支持join操作,方便维度增加属性信息4:流量数据可以近似去重,但订单行要精准去重5:高吞吐,每分钟数据量在千W级记录,每天数百亿条新增记录6:前端业务较多,查询并发度不能太低通过对比开源的几款实时OLAP引擎,可以发现Doris和ClickHouse能够满足上面的需求,但是ClickHouse的并发度太低是个潜在的风险,而且ClickHouse的数据导入没有事务支持,无法实现exactly once语义,对标准SQL的支持也是有限的。所以针对以上需求Doris完全能解决我们的问题,DorisDB是一个性能非常高的分布式、面向交互式查询的分布式数据库,非常的强大,随着互联网发展,数据量会越来越大,实时查询需求也会要求越来越高,DorisDB人才需求也会越来越大,越早掌握DorisDB,以后就会有更大的机遇。本课程基于真实热门的互联网电商业务场景为案例讲解,具体分析指标包含:AB版本分析,下砖分析,营销分析,订单分析,终端分析等,能承载海量数据的实时分析,数据分析涵盖全端(PC、移动、小程序)应用。整个课程,会带大家实践一个完整系统,大家可以根据自己的公司业务修改,既可以用到项目中去,价值是非常高的。本课程包含的技术:开发工具为:IDEA、WebStormFlink1.9.0DorisDBHadoop2.7.5Hbase2.2.6Kafka2.1.0Hive2.2.0HDFS、MapReduceFlume、ZookeeperBinlog、Canal、MySQLSpringBoot2.0.8.RELEASESpringCloud Finchley.SR2Vue.js、Nodejs、Highcharts、ElementUILinux Shell编程等课程亮点:1.与企业接轨、真实工业界产品2.DorisDB高性能分布式数据库3.大数据热门技术Flink4.支持ABtest版本实时监控分析5.支持下砖分析6.数据分析涵盖全端(PC、移动、小程序)应用7.主流微服务后端系统8.天级别与小时级别多时间方位分析9.数据库实时同步解决方案10.涵盖主流前端技术VUE+jQuery+Ajax+NodeJS+ElementUI11.集成SpringCloud实现统一整合方案12.互联网大数据企业热门技术栈13.支持海量数据的实时分析14.支持全端实时数据分析15.全程代码实操,提供全部代码和资料16.提供答疑和提供企业技术方案咨询企业一线架构师讲授,代码在老师的指导下企业可以复用,提供企业解决方案。  版权归作者所有,盗版将进行法律维权。 
目录 译者序 审、译者简介 前言 第1章 决策支持系统的发展 1 1.1 演化 1 1.2 直接存取存储设备的产生 2 1.3 个人计算机/第四代编程语言技术 3 1.4 进入抽取程序 3 1.5 蜘蛛网 4 1.6 自然演化体系结构的问题 5 1.6.1 数据缺乏可信性 5 1.6.2 生产率问题 8 1.6.3 从数据到信息 10 1.6.4 方法的变迁 11 1.7 体系结构设计环境 12 1.7.1 体系结构设计环境的次 13 1.7.2 集成 14 1.8 用户是谁 15 1.9 开发生命周期 15 1.10 硬件利用模式 16 1.11 建立重建工程的舞台 16 1.12 监控数据仓库环境 17 1.13 小结 19 第2章 数据仓库环境 20 2.1 数据仓库的结构 22 2.2 面向主题 23 2.3 第1天到第n天的现象 26 2.4 粒度 28 2.4.1 粒度的一个例子 29 2.4.2 粒度的双重级别 31 2.5 分割问题 34 2.6 样本数据库 34 2.7 数据分割 35 2.8 数据仓库中的数据组织 37 2.9 数据仓库—标准手册 41 2.10 审计和数据仓库 41 2.11 成本合理性 41 2.12 清理仓库数据 42 2.13 报表和体系结构设计环境 42 2.14 机遇性的操作型窗口 43 2.15 小结 44 第3章 设计数据仓库 45 3.1 从操作型数据开始 45 3.2 数据/过程模型和体系结构设计环境 49 3.3 数据仓库和数据模型 50 3.3.1 数据模型 52 3.3.2 中间数据模型 54 3.3.3 物理数据模型 58 3.4 数据模型和反复开发 59 3.5 规范化/反规范化 60 3.6 数据仓库中的快照 65 3.7 元数据 66 3.8 数据仓库中的管理参照表 66 3.9 数据周期 67 3.10 转换和集成的复杂性 70 3.11 触发数据仓库记录 71 3.11.1 事件 72 3.11.2 快照的构成 72 3.11.3 一些例子 72 3.12 简要记录 73 3.13 管理大量数据 74 3.14 创建多个简要记录 75 3.15 从数据仓库环境到操作型环境 75 3.16 正常处理 75 3.17 数据仓库数据的直接访问 76 3.18 数据仓库数据的间接访问 76 3.18.1 航空公司的佣金计算系统 76 3.18.2 零售个性化系统 78 3.18.3 信用审核 80 3.19 数据仓库数据的间接利用 82 3.20 星型连接 83 3.21 小结 86 第4章 数据仓库中的粒度 87 4.1 粗略估算 87 4.2 粒度划分过程的输入 88 4.3 双重或单一的粒度? 88 4.4 确定粒度的级别 89 4.5 一些反馈循环技巧 90 4.6 粒度的级别—以银行环境为例 90 4.7 小结 95 第5章 数据仓库和技术 96 5.1 管理大量数据 96 5.2 管理多介质 97 5.3 索引/监视数据 97 5.4 多种技术的接口 97 5.5 程序员/设计者对数据存放位置的控制 98 5.6 数据的并行存储/管理 99 5.7 元数据管理 99 5.8 语言接口 99 5.9 数据的高效装入 99 5.10 高效索引的利用 100 5.11 数据压缩 101 5.12 复合键码 101 5.13 变长数据 101 5.14 加锁管理 102 5.15 单独索引处理 102 5.16 快速恢复 102 5.17 其他的技术特征 102 5.18 DBMS类型和数据仓库 102 5.19 改变DBMS技术 104 5.20 多维DBMS和数据仓库 104 5.21 双重粒度级 109 5.22 数据仓库环境中的元数据 109 5.23 上下文和内容 111 5.24 上下文信息的三种类型 111 5.25 捕获和管理上下文信息 113 5.26 刷新数据仓库 113 5.27 小结 114 第6章 分布式数据仓库 116 6.1 引言 116 6.2 局部数据仓库 118 6.3 全局数据仓库 119 6.4 互斥数据 121 6.5 冗余 123 6.6 全局数据存取 124 6.7 分布式环境下其他考虑因素 126 6.8 管理多个开发项目 127 6.9 开发项目的性质 127 6.10 分布式数据仓库 130 6.10.1 在分布的地理位置间协调开发 131 6.10.2 企业数据分布式模型 132 6.10.3 分布式数据仓库中的元数据 134 6.11 在多种次上建造数据仓库 134 6.12 多个小组建立当前细节级 136 6.12.1 不同不同需求 138 6.12.2 其他类型的细节数据 140 6.12.3 元数据 142 6.13 公用细节数据采用多种平台 142 6.14 小结 143 第7章 高级管理人员信息系统 和数据仓库 144 7.1 一个简单例子 144 7.2 向下探察分析 146 7.3 支持向下探察处理 147 7.4 作为EIS基础的数据仓库 149 7.5 到哪里取数据 149 7.6 事件映射 152 7.7 细节数据和EIS 153 7.8 在EIS中只保存汇总数据 154 7.9 小结 154 第8章 外部数据/非结构化数据与 数据仓库 155 8.1 数据仓库中的外部数据/非结构化数据 157 8.2 元数据和外部数据 158 8.3 存储外部数据/非结构化数据 159 8.4 外部数据/非结构化数据的不同 组成部分 160 8.5 建模与外部数据/非结构化数据 160 8.6 间接报告 161 8.7 外部数据归档 161 8.8 内部数据与外部数据的比较 161 8.9 小结 162 第9章 迁移到体系结构设计环境 163 9.1 一种迁移方案 163 9.2 反馈循环 167 9.3 策略方面的考虑 168 9.4 方法和迁移 171 9.5 一种数据驱动的开发方法 171 9.6 数据驱动的方法 172 9.7 系统开发生命周期 172 9.8 一个哲学上的考虑 172 9.9 操作型开发/DSS开发 173 9.10 小结 173 第10章 数据仓库设计复查要目 174 10.1 进行设计复查所涉及的问题 175 10.1.1 谁负责设计复查 175 10.1.2 有哪些议事日程 175 10.1.3 结果 175 10.1.4 复查管理 175 10.1.5 典型的数据仓库设计复查 176 10.2 小结 185 附录 186 技术词汇 215 参考文献 222

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值