在日常数据处理过程中避免不了要计算跨长周期数据指标统计需求,类似于如下:

1、  统计每个城市(过去30天)用户浏览次数;

统计每个城市(本年)用户浏览次数;

统计每个城市(历史至今)用户浏览次数;

2、统计每个城市(过去30天|本年|历史至今)交易用户数;

3、数据集部分数据行存在状态变化数据指标需求。

通常面对以上数据指标需求,最大的问题是跨长周期数据量往往是巨大的或者数据周期范围不固定。下面依次求解。

场景1:统计(过去30天|本年|历史至今)用户浏览次数?

常规解决方案如下:

select

city_id as city_id,

count(1) as pv

from events t1

where p_date >= date_add(current_date(),-31)

and p_date <= date_add(current_date(),-1)

group by city_id

;

面临的问题,过去30天埋点事件数据量巨大,服务器无法承受且此简单SQL运行时间太长。

解决思路:

通过构建增量更新的中间表,降低结果SQL扫描数据量,从而优化任务的执行时间和资源消耗问题。

1、  设计中间表

create table e_city_day_indi(

city_id     bigint

pv         int

)

partitioned by(p_date string)

stored as parquet

;

e_city_day_indi有两种加载方法,我分别称其为日增量更新方法和循环迭代更新方法,用于方便后续问题描述。

l  日增量更新:每天汇总当天数据计算出每个城市PV,并且存储到当天日期分区;

优点 更通用;

缺点 不能完全避免多分区扫描,且可能造成小文件过多。

l  循环迭代更新:每天新增数据和前一天快照数据做合并,并且将结果存储到当天日期分区。

优点 应用端仅扫描最新分区即可满足需求;

缺点 应用面较窄,部分长周期需求无法满足。

2、  ETL实现

日增量更新

insert overwrite table e_city_day_indi partition(p_date)

select

city_id as city_id,

count(1) as pv,

date_add(current_date(),-1) as p_date

from events

where p_date = date_add(current_date(),-1)

group by city_id

;

循环迭代更新

insert overwrite table e_city_day_indi partition(p_date)

select

city_id,

sum(pv) as pv,

date_add(current_date(),-1) as p_date

from (

select

city_id as city_id,

count(1) as pv

from events

where p_date = date_add(current_date(),-1)

group by city_id

union all

select

city_id,

pv

from e_city_day_indi

where p_date = date_add(current_date(),-2)

) t

group by city_id

;

3、  优化后取数逻辑

日增量更新取数SQL

select

city_id,

sum(pv) as pv

from e_city_day_indi

where p_date >= date_add(current_date(),-31)

and p_date <= date_add(current_date(),-1)

group by city_id

;

循环迭代更新取数SQL

select

city_id,

pv

from e_city_day_indi

where pdate = date_add(current_date(),-1)

;

以上两种增量加载方法可以满足问题1需求,同时降低了加工数据量。

场景2:统计每个城市(过去30天|本年|历史至今)交易用户数

常规解决方案如下:

select

city_id,

count(distinct user_id) as uv

from events

where p_date >= date_add(current_date(),-31)

and p_date <= date_add(current_date(),-1)

group by city_id

;

典型count distinct类型需求,面临的问题,过去30天埋点事件数据量巨大,服务器无法承受且此简单SQL运行时间太长。

解决思路:

通过构建增量更新的中间表,降低结果SQL扫描数据量,从而优化任务的执行时间和资源消耗问题。

1、  设计中间表

create table e_city_day_indi(

city_id     bigint,

user_id     bigint,

pv          int

) partitioned by(p_date)

stored as parquet

;

e_city_day_indi数据加载方法在这里仅介绍日增量更新方法。

2、ETL实现

日增量更新

insert overwrite table e_city_day_indi partition(p_date)

select

city_id,

user_id,

count(1) as pv,

date_add(current_date(),-1) as p_date

from events

where p_date = date_add(current_date(),-1)

group by city_id,user_id

;

3、优化后取数逻辑

日增量更新

select

city_id,

count(distinct user_id) as uv,

sum(pv) as pv

from e_city_day_indi

where p_date >= date_add(current_date(),-31)

and p_date <= date_add(current_date(),-1)

group by city_id

;

场景3:数据集部分数据行存在状态变化数据指标需求

这种需求场景比较特殊,是针对全量数据做update操作,一般性问题是全表数据量较大,但是需要update数据量较小,且基于hive解决方案,update是较难以处理的场景。

解决思路:将变化数据和明确不变数据做分离(能否合理做数据热度分离是关键)。具体实施细节是设计分区表,将少量变化数据存储一个分区,将大量不变数据存储在另一个分区,设计历史数据更新的仅扫描活跃分区即可。

实施方案:

l  设计目标表两个分区(或者日期分区下设计二级分区)

活跃分区:用来存储生命周期未结束且可能存在update操作的数据。

非活跃分区:用来存储明确生命周期结束数据。

l  设计日期分区

历史日期分区(p_date <= current_date())存储生命周期结束的数据行;

未来日期分区(p_date = ‘9999-12-31’)存储生命周期尚未结束的数据行。

以上3种典型场景是做数据开发过程中较基础也是比较常见的增量ETL开发场景,使用合适的方法处理问题可以大大减少资源消耗同时可以有效降低执行时间。

增量ETL (长周期指标) 优化方案的更多相关文章

  1. 数据库SQL优化大总结之 百万级数据库优化方案(转载)

    网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 这篇文章我花费了大量的时间查找资料.修改.排版,希望大家阅读之后,感觉 ...

  2. mysql 百万级数据库优化方案

    https://blog.csdn.net/Kaitiren/article/details/80307828 一.百万级数据库优化方案 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 wher ...

  3. 前端项目优化 -Web 开发常用优化方案、Vue & React 项目优化

    github github-myBlob 从输入URL到页面加载完成的整个过程 首先做 DNS 查询,如果这一步做了智能 DNS 解析的话,会提供访问速度最快的 IP 地址回来 接下来是 TCP 握手 ...

  4. C++高并发场景下读多写少的优化方案

    概述 一谈到高并发的优化方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也能很大的影响整体性能,本文从单模块下读 ...

  5. Redmine性能优化方案

    近来公司redmine服务器表现很糟糕,在16核,64GRAM的机器上,压测结果竟然只有每秒5~7个请求,部分页面一个都出不来. 以下是我对Redmine性能优化方案: redmine服务器性能问题排 ...

  6. 移动 H5 首屏秒开优化方案探讨

    转载bang大神文章,原文<移动 H5 首屏秒开优化方案探讨>,此文仅仅用做自学与分享! 随着移动设备性能不断增强,web 页面的性能体验逐渐变得可以接受,又因为 web 开发模式的诸多好 ...

  7. 五个Taurus垃圾回收compactor优化方案,减少系统资源占用

    简介 TaurusDB是一种基于MySQL的计算与存储分离架构的云原生数据库,一个集群中包含多个存储几点,每个存储节点包含多块磁盘,每块磁盘对应一个或者多个slicestore的内存逻辑结构来管理. ...

  8. 从350ms到80ms,揭秘阿里工程师 iOS 短视频优化方案

    内容作为 App 产品新的促活点,受到了越来越多的重视与投入,短视频则是增加用户粘性.增加用户停留时长的一把利器.短视频的内容与体验直接关系到用户是否愿意长时停留,盒马也提出全链路内容视频化的规划,以 ...

  9. 揭秘盒马鲜生 Android 短视频秒播优化方案

    短视频作为内容重要的承载方式,是吸引用户的重点,短视频的内容与体验直接关系到用户是否愿意长时停留.因此,体验的优化就显得尤为重要.上一篇我们分享了 iOS 短视频秒播优化,这篇我们来聊聊 Androi ...

随机推荐

  1. spring data jpa 表关联设置用户表关联角色表配置

    User 表: @ManyToMany(cascade = { CascadeType.MERGE }) @JsonIgnore @JoinTable(name = "UserRole&qu ...

  2. golang测试

    简述 Go语言中自带有一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试. go test [-c] [-i] [build flags] [packages] [f ...

  3. linux 使用ssh-keygen生成ssh公钥和私钥

    linux一般为在自己的家目录下建立 .ssh 文件夹 中生成密钥 /home/username/.ssh 生成的命令如下: ssh-keygen -t rsa -C "yourname@y ...

  4. 内核中dump_stack的实现原理(1) —— 栈回溯

    环境 Aarch64 Qemu aarch64-linux-gnu-gcc linux-4.14   概述     栈回溯的目的是将函数的调用栈打印出来,对于分析函数调用和debug系统异常会很有帮助 ...

  5. 如何在macOS下调整磁盘分区大小?

    可以在“macOS”下利用磁盘工具并且不抹掉主分区的情况下,随意更改磁盘分区大小的方法.“OS X”经过几次大版本升级以后,也改名为“macOS”,而且系统自带的“磁盘工具”无论是功能和界面也有很大的 ...

  6. Socket网络编程-SocketServer

    Socket网络编程-SocketServer 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.SocketServer概述 socket编程过于底层,编程虽然有套路,但是想要写 ...

  7. php备忘录模式(memento pattern)

    晚上刷起来. <?php /* The memento pattern provides the object restore functionality. Implementation is ...

  8. Educational Codeforces Round 69 D. Yet Another Subarray Problem

    Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 题目链接 题意: 求\(\sum_ ...

  9. 项目Beta冲刺(团队)--6/7

    课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺 团队名称:葫芦娃队 作业目标:进行新一轮的项目冲刺,尽力完成并完善项目 团队博客 队员学号 队员昵称 博客地址 04160242 ...

  10. Ubuntu设置终端操作行为的回收站

    Ubuntu设置终端操作行为的回收站(默认情况下,在终端删除文件,会直接删除) 参考自:https://help.aliyun.com/knowledge_detail/41359.html?spm= ...