SELECT udtf_group_points(A.id,A.timestamp,A.x,A.y)
AS (id,stime,etime,elapse,length,count,points)
FROM (
SELECT id, timestamp,x,y
FROM car_point
DISTRIBUTE BY id
SORT BY id,timestamp
)A;
轨迹切分是交通大数据基础架构的重要组成部分,功能是把GPS点切分为每个车辆一次有明确起点和终点的GPS点序列。上述SQL是轨迹切分业务的基本实现,业务逻辑封装在udtf中。请指出这个语句,哪些部分对应mapper,哪些部分对应partitioner,哪些部分对应reducer。
需求:统计移动交通台每个城市、每个厂商的每5分钟的用户数(即UV)、访问次数(即PV) 输入说明:
Field | Type | Comment |
---|---|---|
time | string | 时间,格式yyyy-mm-dd HH:MM:SS |
cpcode | string | 厂商 |
eid | string | 用户ID |
adcode | bigint | 城市编码 |
type | bigint | 服务类型 |
status | bigint | 服务返回状态 |
要求输出:
Field | Type | Comment |
---|---|---|
time | string | 时间,格式yyyy-mm-dd HH:MM:SS |
cpcode | string | 厂商 |
adcode | bigint | 城市编码 |
user_view | bigint | 用户数 |
page_view | bigint | 访问次数 |
注:统计时要求统计status值为0,type值为1或2,cpcode为字母、数字、下划线组成的字符串
参考答案:
SELECT from_unixtime(unix_timestamp(time)-pmod(unix_timestamp(time),300)) as time,
adcode,
cpcode,
count(distinct eid) as users,
count(eid) as request_count
FROM
traffic_logs
WHERE cpcode regexp '^[a-zA-Z0-9_]+$'
and status = 0
and (type = 1 or type = 2)
GROUP BY
from_unixtime(unix_timestamp(time)-pmod(unix_timestamp(time),300)),
adcode,
cpcode;
Join倾斜时,如果某路输入比较小,可以采用Mapjoin避免倾斜。Mapjoin的原理是将Join操作提前到Map端执行,这样可以避免因为分发Key不均匀导致数据倾斜。但是Mapjoin的使用有限制,必须是Join中的从表比较小才可用。所谓从表,即Left Outer Join中的右表,或者Right Outer Join中的左表。
做left outer join时,左表存在大量空值,聚集到了一个reducer处。通过coalesce(left_table.key, rand()*9999)
将key为空的情况下赋予随机值,来避免空值集中。
从连接表a中取出热点值,建立临时表t。 a表mapjoin表t,取出非热点值的部分,与表b连接输出r1。此时因为无热点值,这部分不再存在长尾问题。
用mapjoin取出表a的热点值部分得到c,用mapjoin取出表b的热点值部分得到d,c再mapjoin表d,得到热点值的输出r2.
r1和r2 union all得到最后的结果。
Map端读数据时,由于文件大小分布不均匀,一些map任务读取并处理的数据特别多,一些map任务处理的数据特别少,造成map端长尾。这种情形没有特别好的方法,只能调节splitsize来增加mapper数量,让数据分片更小,以期望获得更均匀的分配。
典型case是Multi Distinct。一个distinct的实现是将group by的key和distinct的字段合并在一起作为mapreduce的key,将group by的key作为partition的key,然后在reduce端去重计数即可。而Multi Distinct,map端的一行数据就会输出n行。
可以将multi distinct改为两层group by,第一层的group by的key为multi distinct group by的key与distinct的key,第二层为multi distinct的group by的key。