hadoop
hadoop是大数据生态圈的核心
大 1024T=1P
大量数据怎么存 H D F S 分布式 集群
大量数据怎么算 MapReduce 分析用的 编程
对分布式的理解 :
分布式不是一个技术,是一个抽象的概念
这种概念描述了一个思想,把一个大的问题化为多个小问题去解决
一张a4 与多张小条
}
多台可以有机的组合在一起并可以共同的解决一个问题
的计算机
Hadoop HDFS MapReduce 分布式 集群 规范
}
1 MR的思想 通过两个阶段Map、Reduce来完成数据分析的工作,如果一次不行就再来一次map、reduce
2 Map的工作:拢数据 (对数据进行整理,包括格式的处理,不合理数据的清洗等等)
3 Reduce的工作:对拢好的数据进行统计计算
]
1 MR的整个流程是一条线 源数据->map->reduce->结果
2 上面1那条线上的数据传递都是以key,value形式传递的
K,V K,V K,V
源数据----》Map ----》Reduce---》结果
3 map会将数据以K,V的形式发送到Reduce
4 Reduce会将收到K,V根据K进行合并V以集合的形式存在
]
求最值问题思路:[
A 首先要有单词和出现次数的数据 ---通过一个MR来解决
B 然后再A这个MR的基础上在进行求最值
C 求最值的思路?定义一个Max变量作为最值 保存
]
代码:[
A 值得注意的是map和reduce 未必是一个 一般都是多个map和多个reduce共同工作
B 所以我们要考虑到多个map的情况 要把每个map的最大值传给reduce reduce才可以得出最终的最大值
C 那么reduce的数量就应该为一个
D 通过cleanup方法来输出map计算后的最大值 一次
cleanup的方法特点是在map执行完执行一次
E 通过最大值问题数量掌握cleanup方法的使用
]
}
map到reduce的过程需要序列化 (其实很多过程都需要序列化)
而hadoop并不满意jdk的序列化方案,它认为又大又慢
所以hadoo采用了新的序列化方案
这就是xxxWritable
通过查看IntWritable我们发现它实现了Writable接口
在hadoop里实现了Writable接口的类可以被序列化
}
A 所有的键值必须实现Writable接口
B 所有的键必须实现Comparable接口
C 一般键都实现了WritableComparable
}
自定义键值{
我们已经知道了MR中键值的规则,那么就可以利用这个柜子
自己建立(键值)的数据类型
自定义键要正确重写compareTo方法
自定义值要正确重写序列化方法[
重写序列化方法的要求
1 写入顺序要和读取顺序一致
2 写入的类型要和读取的类型一致
3 不能写入null
]
}
代码思路[
因为要取前三所以要取每组的前三 进行比较才能得到真正的前三
所以要讲所以map的topN传给reduce 来比较出最终的topN
所以在map中应该定义个集合进行保存topN
]
topN的性能分析[
因为每个map都要将自己的前N条数据发送给reduce
所以当N值非常大的时候 性能较差
极端的例子,比如求一千万条数据的前九百万
用topN不如全排序来的痛快
]
//单词 词频
//aaaaa 11111
//bbbb2 11
//确定比较规则的方法
@Override
public int compareTo(ForWord o) {
//如果词频相同 按单词的字典顺序比
if(o.times==this.times){
return o.word.compareTo(this.word);
}
//如果词频不同按降序比较
return o.times-this.times;
}
//序列化时写入的方法
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(this.times);
out.writeUTF(this.word);
}
//反序列化时读取的方法
@Override
public void readFields(DataInput in) throws IOException {
this.times=in.readInt();
this.word=in.readUTF();
}
1 Map到reduce的过程中必须经历的一个阶段
2 分区机制的作用是用来决定哪些map的数据应该被哪些reduce进行处理
3 分区的规则可以指定,如果不指定有默认的分区机制(规则)
4 默认的分区规则是根据hash来分区
5 MR使用HashPartitioner类来描述hash分区规则
6 重写分区规则的步骤[
1 编写一个类实现Partitioner接口
2 并重写getPartition方法
]
}
找粉丝 ,通过将键和值在map中进行调换完成 粉丝<->关注的映射
}
用于帮助我们对MR程序进行分析和排错,还有统计的功能
用作统计性能高
]
如何自定义计数器[
有两种方法 ,一种是指定计数器的group和name
另一种是使用一个枚举 枚举的类名作为组名,枚举的实例名作为name
通过context.getCounter() 来获得一个计数器 两种方法 ( 组+ 名 ) 枚举名+名
通过,increment方法对计数器进行值的累加 调用一次累加一次
通过,getValue方法来获得当前计数器的值
最后再日志结果里会打印相应计数器的结果
]
}
Combiner{ 提前将年月合并 积温??? 鸡瘟2010-01 22 2010-01 77
什么是Combiner[
1 Combiner作用的位置 是map和reduce之间
2 他是一个可选的操作
3 它的核心作用是减少map对reduce的输出
4 它的样子和reduce几乎一样
5 但是它是在map端(机器)进行工作
]
如何定义一个Combiner[
1 编写一个类继承Reducer 就搞定啦
2 然后在job中进行设置Combiner
3 以温度求和为例
]
Combiner使用的要求[
1 Combiner的输入和输出类型一定是一样的
2 当数据量少的时候combiner的效果未必明显,但是数据量大的时候就有效果了
3 使用combiner的计算要求是满足结合律的,比如简单的求平均就不适合使用combiner
4 但是可以将求平均运算转换成求和再平均的运算
]
对的就是你以为的那个表连接 和sql是一样的
表连接的操作[
有两种方式A 在map端连接 小 快 B在reduce端连接 大
]
map端连接[ setup
一般先将小表进行缓存 内存,使用集合这样快,但是表不能太大
否则内存装不下
思路:
通过一个map集合对小表继续进行缓存
读取大表,根据连接字段从map中取小表的值继续进行连接
]
所以步骤:【
A 确定两个表中连接字段是哪个
B 将小表缓存到Map集合中
C 读取大表
D 根据相应的字段从Map集合中取值
E 将大表和从map中取出值继续进行连接
F 所整个过程不需要reduce
】
}
reduce端连接{
和map端连接不同,可以做两个大表的连接 虽然慢但能成功
使用reduce端连接的思路[
A 利用map到reduce时会将相同的键进行合并的原理
B 那就应该用谁做key?用相同的字段(键)做MR的key
C 但是两个表的字段不一致,用一个大实体包含两个表的所有字段
D 涉及到判断当前是哪个表取出的数据
E 对数据进行整理
]
}
倒排索引
统计每个次在不同的文件中的次数
核心技巧是:key的变化 合并-》拆分 (单词和文件组成key 然后再重新拆分 )
排序 Comparator 和 Comparable
GroupComparator 修改key的判断相同的规则( 捏key)
倒排索引{
倒排索引的核心目的是知道某个词在哪些文件中分别都出现多少次
所以结果应该是 a a.txt->3 ,b.txt-4,c.txt->5
b a.txt->1 ,b.txt-2,c.txt->6
a -a.txt 3
a -b.txt 4
a -c.txt 5
将文件按次数排序输出
}
分组 Map到reduce的过程一定是要分组的 何为一组 ?
相同的key为一组
GroupComparator的功能就是提供了一种修改分组的规则的机制
换句话将 就是修改判断key相同的规则
编写一个类 继承WritableComparator 类并重写方法
并设置使其生效
}
1 多文件输入 job方法提供了设置多个文件夹的api
2 读取压缩文件 用于解决小文件太多的问题
3 默认使用TextInputFormat具有解压功能
4 输入的类型能改么?能。输入的类型取决于我们使用的XXXInputFormat 默认是TextInputFormat 更换的方法是在job里设置即可
5 自定义输入类型
}
很少的时候我们需要自定义输入类型
需求1 可以重写分片规则 2 可以重写 key value的取值规则 文件名当键 内容当值
步骤:【
A 要写一个类直接或间接的实现InputFormat
B 按照要求重写里面的方法 nextKeyValue()返回false 不分片
C 最关键的是重写RecordReader
D 设置你的自定义类型使其生效
】
]
输出也可以压缩[
map到reduce的过程也可以压缩 目的是减少网络开销
reduce压缩
FileOutputFormat.setCompressOutput(job,true);
FileOutputFormat.setOutputCompressorClass(job, (Class<? extends CompressionCodec>) o.getClass());
]
继承xxxOutputFormat
重写方法
编写RecordWriter
编写业务逻辑
指定我们的输出类型生效
]
}
shuffle {
混洗混排 指的是map 到reduce的过程
要考虑的:
第一步解析数据 按" 切分 split(""")
数据不合理的过滤
时间类型的处理
业务上的代码处理
}