文章目录
  1. hive处理增量数据
  2. 1. 场景
  3. 2. 增量处理

[TOC]

hive处理增量数据

1. 场景

  • 前提:通过 Sqoop 拉取的数据含有 主键 或者 唯一键
  • 场景:每天 按时间 或者 其他列值 增量拉取数据, 如下
1
2
3
每天按照时间(如更新时间updated_at),来增量拉取数据。然后把每天的拉取的数据,增量放入到hive表中的一个时间分区中。

问题:由于按照更新时间来增量拉取,hive表肯定会存在重复数据。

例子:

  • 源表 user 的数据,id是主键,更新时间省去
id name age
1 张三 23
2 李四 24
3 王五 25
4 赵六 26
  • 第一天拉取数据到hive的一张表中如:s_user分区 pt为:2016-10-10

  • 第二天,由于源表的信息发生变化, 数据如下。然后将数据放入到 s_user 的分区 2016-10-11中。

id name age
1 张三 23
2 李四 24
3 王五 255
4 赵六 266
5 贱人 11
  • 这样 s_user 表中的数据就会存在重复。

  • 这个时候最正常的解决办法就是,将 s_user 的数据每天计算,根据id进行分组,然后相同id的去最新pt的那一条记录,最后将数据插入到一张明细表中 dwd_user(结构与 s_user一致)。(这里面省去的数据的清洗)

1
2
3
4
5
6
7
8
9
-- 语句
INSERT OVERWRITE TABLE dwd_user
SELECT t.id, t.name, t.age FROM (
SELECT id, name, age, ROW_NUMBER() OVER(PARTITION BY id ORDER BY pt DESC) as num
FROM s_user
) t
WHERE t.num = 1

## ROW_NUMBER() OVER() 参考 http://blog.csdn.net/lsxy117/article/details/50387395
  • 这样 dwd_user 中的数据就能保证最新了。

  • 问题:由于dwd_user是每天都覆盖的,那么每天都要把 s_user 表所有数据统计一遍,这样肯定不行。我们的做法是 dwd_user 也有分区pt,然后每天将最新统计完的数据放入到 dwd_user的最新分区中(弊端:dwd_user 表会越来越大。优点:可以回溯每天的历史数据)。

2. 增量处理

基于上述 dwd_user 存在分区的情况之下,这样就可以将原先的处理逻辑进行优化。

  • 第一天的数据情况

  • 第二天的数据情况

处理流程

1、为了将最新的数据处理到 dwd_user 的新分区中 2016-10-11
2、这个时候你只要关心 s_user2016-10-11 分区以及 dwd_user2016-10-10分区。
3、这样你就能避免重复去算 s_user 的旧数据。
4、步骤如下:将 s_user(2016-10-11) 数据和 dwd_user(2016-10-10)数据合并,然后按id分组,取最新 pt 的数据,最后插入到 dwd_user2016-10-11 分区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
INSERT OVERWRITE TABLE dwd_user partition(pt='2016-10-11')
SELECT id, name, age FROM (
SELECT id, name, age, ROW_NUMBER() OVER(PARTITION BY id ORDER BY pt DESC) as num
FROM (
SELECT id, name, age, pt
FROM dwd_user
WHERE pt='2016-10-10'
UNION ALL
SELECT id, name, age, pt
FROM s_user
WHERE pt='2016-10-11'
)
) t
WHERE t.num = 1

5、这样就能很好的处理每天增量的数据。

参考:

  1. http://blog.csdn.net/qq_20641565/article/details/52763663

没有主键的方案参考:

  1. http://blog.csdn.net/qq_20641565/article/details/52852168
文章目录
  1. hive处理增量数据
  2. 1. 场景
  3. 2. 增量处理