1.mapreudce流程:
官网:
(1)整体流程
(input) <k1, v1> -> map -> <k2, v2> -> reduce -> <k3, v3> (output)
(2)解释:
1)整个过程 跟 kv
数据类型=》 mr
2)kv:
1.The key and value classes have to be serializable
2.序列化=》 kv数据类型 实现 =》 Writable interface
3.k 的数据类型=》 WritableComparable 【序列化 + 排序 】
4.【mr 过程 是按照key 进行排序】
5.每个阶段的输出作为下一个阶段的输入
以wordcount为例:
(1)input [跟切片有关系] =》 “文件里的数据 一行一行读取”
a,a,a
b,b,b
=>
k:line号的偏移量
v: 每行的数据
(offset1,"a,a,a")
(offset1,"b,b,b")
【input】
(1)【大部分场景下 一个文件 一个task 处理一个block 】
注意:
不是说每个文件都能进行split(分片):
能分片: 200m =》128m + 剩余的部分 =》 2个task
不能分片: 1T =》 只有一个task 处理
(2)map: 一一映射 =》 y=f(x)
(offset1,"a,a,a")
(offset1,"b,b,b")
f(x) :按照分割符进行拆分 每个单词赋值成1
(offset1,"a,a,a") =》 "a,a,a".split(",")
=>
(a,1)(a,1)(a,1)
(b,1)(b,1)(b,1)
(3)reduce:归约 聚合 + 函数 =》
1.按照某一个规则 把key 拉倒一起 【分组 聚合】
2.“做一些事情” 【函数】
(a,1)(a,1)(a,1)
(b,1)(b,1)(b,1)
=》 “分组” shuffle [k,v是一个集合 ]
a,<1,1,1>
b,<1,1,1>
=> "函数"
a,3
b,3
2.mapreudce 作业 =》 yarn
app master => driver [mian ]
maptask => mapper阶段的代码
reduce task =》 reduce 阶段的代码
mian{
mapper
reduce
driver => map + reduce => yarn
}
8.mapper阶段:
Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
(input)
KEYIN:输入数据key的数据类型
VALUEIN: 输入数据value的数据类型
map:
KEYOUT:输出数据key的数据类型
VALUEOUT 输出数据value的数据类型
方法:
setup 每个maptask 开始的时候 执行一次
cleanup每个maptask 结束的时候 执行一次
3.reducer阶段
KEYIN,VALUEIN,KEYOUT,VALUEOUT
(map)
KEYIN:输入数据key的数据类型
VALUEIN: 输入数据value的数据类型
reduce:
KEYOUT:输出数据key的数据类型
VALUEOUT 输出数据value的数据类型
注意:
map阶段的输出作为reduce阶段的输入
4.kv的数据类型:
mr:
k: Text
v:IntWritable
java:
String =>Test
int => IntWritable
double => doubleWritable
null => NUllWritable
kv => Writable
k=》 WritableComparable
k:IntWritable
5.提交服务器运行代码:
hadoop jar \
/home/hadoop/project/mapreduce/bigdata-hdfs-1.0.jar \
com.bigdata.mapreduce.WordCount \
/data/wc.data /out-wc
6.需求: mr 统计每个手机号的上行总流量、下行总流量 、总流量
mr:
mapper:
phone up down
key:phone
value :up down
reduce:
key:phone => 分组
value: <(up down)...>
key:phone => 分组
value:up_totol down_totol totol
table:
phone up down
sql:
维度:phone
指标:上行总流量、下行总流量 、总流量
select
phone,
up_totol,
down_totol,
(up_totol+ down_totol) as totol
from
(
select
phone,
sum(up) as up_totol,
sum(down) as down_totol
from log
group by
phone
) a ;
7.sql:
group by 分组
distinct 去重
join 表关联
order by 排序
parition表 分区:
eg;
517 => /0517/*
(1)order by 排序
需求;
phone uptotl downtotol totol
分析:
mr :
map:
k =》totol
v: phone uptotl downtotol
reduce:
k :
phone uptotl downtotol totol
(2)parition表 分区
1)处理好的文件 文件生成的个数由谁决定的?reducetask 个数由谁决定的?
reducetask 个数由谁决定的?
a.开发人员决定的
b.默认:reducetask 是1个
2)文件生成的个数由谁决定的?
reducetask 个数
3)reducetask 要求:
a.reducetask 个数 >= 分区数 会有空文件
b,reducetask 个数 < 分区数 报错
c.reducetask 个数 1 没有问题
(3)distinct
需求: mr 对数据进行去重
sql: name
select name from table group by name ;[去重]
(4)group by 分组
需求:
sql =》 mr
select deptno ,count(1) as cnt from emp group by deptno;
input
处理 :
mapper:
all =>
deptno
(20,1),(20,1)
reducer:
20,<1,1,1>
聚合统计
20,3
ouput :
1.file
2.mysql
8.切片机制
input =》 数据加载
file
db
InputFormat:
数据源类型
OutputFormat:
数据存储类型
思考:1.maptask个数由什么决定的?
分片的个数
2.什么是分片?(split)
和块有点像
block:
1.文件拆分 形成的block
blocksize =》 128m
split:
1.加载数据 形成的切片
splitsize =》blocksize 128m
3.一个文件加载的时候 会形成多少个切片?
前提:
(1)文件可以被分割
(2)文件不可以被分割
切片的个数 就是一个
文件是否可以被分割?
(1)文件存储格式 :
text、orc、parquet =》 支持分割
(2)文件存储的压缩格式:
有的可以分割的 有的不可以
4.分片的个数如何计算?
(1)文件不可被分割:
就是一个分片
(2)文件可被分割:
1)文件大小 小于 128m
一个文件对应一个切片 一个maptask 【 文件大小 小于 切片的大小】
2)文件大小 大于 128m
filesize /128 = num 切片个数
剩余部分= filesize - num*128
剩余部分 比较大小 splitssize*10%=128*10% = 12.8m
大于等于 开启一个maptask
小于 不会开启maptask 【剩余的部分 合并到之前的切片中】
案例:
130m 文件 问几个切片?
130/128 = 1
130-128*1=2m<12.8m
160m 文件 几个切片 ?
160/128 = 1
160-128*1 = 32m
32m>12.8m => 1
1+1 =2
5.为什么要知道切片的个数呢?
切片的个数 =》 maptask的个数
=》 yarn
一个task 申请一个container 【cpu、mem】
6.wc文件 137m
137/128 =1
137-128*1=9>12.8
idea => local => 切片大小 是128???
本地 32m
137/32=4
9>3.2 =>1