Hadoop学习从基础到精通

##Bigdata

#day1
tar zxvf weather.tgz

退出安全模式: hdfs dfsadmin -safemode leave

大数据:通过传统数据库存储技术以及数据处理工具不能处理的庞大而复杂的数据的集合

大数据的四个特点:数量大,速度快,种类多,价值密度低
大数据处理,大数据分析

Hadoop
离线分析

Spark
在线分析,实时分析

大数据存储:
HDFS: Hadoop Distributed File System

HBase:列式数据库,非关系型数据库

Hive:数据仓库,类SQL

全球的数据分为三种:
1.结构化数据:Structured:database,spreadsheet,file in record format
2.半结构化数据:demiStructured:-XML Docs,Logs,Click-Stream,Equiment/Device,
3.非结构化数据:unStructured:

大数据的四个特点:数量大,速度快,种类多,价值密度低
大数据处理,大数据分析

大数据的整体架构:用户端,应用计算,云计算,服务

集群:cluuster
数据密集型:DIC
计算密集型:CIC
向上扩展:纵向扩展
向外扩展:横向扩展
机器学习:
云计算:

移动计算:把应用程序分发到不同的节点上处理
移动数据:把数据分发到不同的节点上计算

集群搭建:
单机模式:Hadoop解压之后,不需要做任何配置直接使用
伪分布式模式:关于集群的所有服务都只在一台节点上启动
全分布式模式:有多个节点,其中一个作为主节点,运行主节点需要运行的服务;其余的作为从节点,每个节点上都运行从节点需要运行的服务。

Hadoop集群伪分布式搭建

0.规划
1.在/opt/目录下创建softwarres和links目录
2.softwares用于安装软件,links用于创建软件的软链接
3.环境变量 配置到当前用户的家目录下的.bashrc中
用户环境变量:.bashrc .bashrc_profile
系统环境变量:/etc/profile /etc/bashrc

1.创建目录并分配权限:
1.sudo mkdir /opt/softwarres /opt/links

2.更改 opt 目录的所属者以及所属组为当前用户
	sudo chown yfl:yfl /*

2.安装和配置jdk
1.解压
tar zxvf jdk。。。 -C /opt/softwares
2.创建软链接
ln -sf /opt/softwares/jdk。。。 /opt/links/jdk
3.配置环境变量
vi ~/.bashrc

	####__JAVA__CONF__####
	export JAVA_HOME=/opt/links/jdk
	export JRE_HOME=$JAVA_HOME/jre
	export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
	export PATH:$PATH:$JAVA_HOME/bin
	
	source ~/.bashrc·~
	java/javac

3.安装Hadoop
1.解压
tar zxvf hadoop。。。 -C /opt/softwares

2.创建软链接
	ln -s /opt/softares/hadoop.. /opt/links/hadoop

3.配置环境变量
	
	vi ~/.bashrc
	
	####_HADOOP_CONF_####
	export HADOOP_HOME=/opt/softwares/hadoop
	export HADOOP_USER_NAME=yfl1
	export PATH:$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
	
	source ~/.bashrc

4.配置HDFS集群
1.Hadoop程序安装目录中的内容

2.配置core_site.xml文件
	<configuration>
	        <property>
	                <name>fs.defaultFS</name>
	                <value>hdfs://192.168.1.131:9000</value>
	        </property>
	</configuration>


3.配置hdfs-site.xml文件:创建目录用于存放HDFS集群所存储的文件的实际位置。
	主节点:      NameNode             nn
	从节点:      DataNode             dn
	第二主节点    SecondaryNameNode    snn

	mkdir ~/Bigdata
	mkdir -p ~/Bigdata/hadoop/data/nn
	mkdir -p ~/Bigdata/hadoop/data/dn
	mkdir -p ~/Bigdata/hadoop/data/snn

	vi /opt/links/hadoop/etc/hadoop/hdfs-site.xml	
	<configuration>
	        <property>
	                <name>dfs.nameservices</name>
	                <value>hdfs-cluster</value>
	        </property>
	        <property>
	                <name>dfs.namenode.name.dir</name>
	                <value>file:///home/yfl1/Bigdata/hadoop/data/nn</value>
	        </property>
	        <property>
	                <name>dfs.datanode.data.dir</name>
	                <value>file:///home/yfl1/Bigdata/hadoop/data/dn</value>
	         </property>
	         <property>
	                <name>dfs.namenode.checkpoint.edits.dir</name>
	                <value>file:///home/yfl1/Bigdata/hadoop/data/snn</value>
	         </property>
	         <property>
	                <name>dfs.namenode.checkpoint.edits.dir</name>
	                <value>file:///home/yfl1/Bigdata/hadoop/data/snn:</value>
	         </property>
	</configuration>


4.集群的格式化:只需要在主节点上执行
	hdfs namenode -format
	
	**:如果需要重新进行HDFS集群的格式化,则需要将全部节点中的nn,dn,snn等目录中的内容全部清除。
	**:一般hdfs集群只需要格式化一次


5.启动HDFS集群服务
	主节点:hadoop-daemon.sh start/stop namenode
	从节点:hadoop-daemon.sh start/stop datanode

	查看集群是否启动成功
		jps  有namenode和datanode说明启动正常


6.从web监控页面查看hdfs集群:
	[hadoop2.x] http://IP:50070
	[hadoop3.x] http://IP:9870

7.HDFS集群的常用命令:几乎和linux一样,但是使用方式不一样。
	语法:hdfs dfs -命令 【选项(s)】 【参数(s)】
	
	创建家目录:用户为HADOOP_HOME_NAME_UESR所配置的用户
	hdfs dfs -mkdir -p /user/yfl1

	1.查看集群某个目录下的所有文件
		hdfs dfs -ls /

		注意:
			1.在hdfs中家目录的概念是用“.”表示
			2.在hdfs中没有当前目录或当前路径的概念
			3.关于hdfs集群中用户的家目录的位置:/user/用户名
			
	2.上传文件至hdfs集群
		hdfs dfs -put 本地文件 hdfs://IP:9000/集群目录/文件名
	下载文件
		hdfs dfs -get
	查看 
		hdfs dfs -ls -l

在hadoop中所有的用户都属于同一个组:supergroup

##day2

sudo vi /etc/hosts

hadoop命令:

mv / cp 只能从一个集群到另一个集群

yarn集群的配置

1.mapred-site.xml
cd /opt/links/hadoop/etc/hadoop/
cp mapred-site.xml.template mapared-site.xml
vi mapared-site.xml

<property>
	<name>mapreduce.framework.name</name>
	<value>yarn</value>
</property>

2.yarn-site.xml

vi/opt/links/hadooop/etc/hadoop/yarn-site.xml
	
<property>
	<name>yarn.resoucemanager.hostname</name>
	<value>1.0.0.223</value>
</property>
<property>
	<name>yarn.nodemanager.aux-services</name>
	<value>mapreduce_shuffle</value>
</property>
<property>
	<name>yarn.nodemanager.local-dirs</name>
	<value>file:///home/kevin/Bigdata/data/hadoop/data/yarn/nm</value>
</property>

3.启动yarn集群:
主节点:yarn-daemon.sh start resourcmanager
从节点:yarn-daemon.sh start datamanager
jps

4.yarn集群的web监控页面

IP:8088

5.提交一个Hadoop已提供的作业到yarn:
/opt/links/hadoop/share/hadoop/mapreduce

yarn jar *.jar x.y.z.Abc 类参数
例:yarn jar /opt/links/hadoop/share/hadoop/mapreduce pi 2 10

6.启动作业历史服务:
mr-jobhistory-daemon.sh start historyserver

C:\windows\System32\drivers\etc\hosts

192.168.1.131 yfl1

集群管理的另一种方式:通过主节点管理(启动或停止)所有的从节点
免密登录:
A->B:
1.ssh-keygen,生产公钥(加密),私钥(解密)
2.A的公钥给B,~/.ssh/authorized_keys
3.必须是AB上的用户名相同

ssh-keygen
cat .ssh/id_rsa.pub >> .ssh/authorized_keys
ssh yfl1
start-dfs.sh

将环境变量修改为系统变量:
sudo vi /etc/profile
####JAVA__CONF####
export JAVA_HOME=/opt/links/jdk
export JRE_HOME= J A V A H O M E / j r e e x p o r t C L A S S P A T H = . : JAVA_HOME/jre export CLASSPATH=.: JAVAHOME/jreexportCLASSPATH=.:JAVA_HOME/lib: J R E H O M E / l i b e x p o r t P A T H = JRE_HOME/lib export PATH= JREHOME/libexportPATH=PATH:$JAVA_HOME/bin

####__HADOOP__CONF__####
export HADOOP_HOME=/opt/links/hadoop
export HADOOP_USER_NAME=yfl1
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

vi /opt/links/hadoop/etc/hadoop/hadoop-env.sh
25行:export JAVA_HOME=/opt/links/jdk

sudo reboot

主节点:
vi /opt/links/hadoop/etc/hadoop/slaves
把从节点的ip/name写进去
1.HDFS:start-dfs.sh
2.YARN:start-yarn.sh

3.start-all.sh

4.mr-jobhistory-daemon.sh start historyserver

5.yarn-daemon.sh start proxyserver

全分布式集群配置:n个节点
1.最好保证每个节点的操作系统和版本都一样,不同的操作系统或者相同的操作系统不同的版本之间存在细微的差别
2.保证网络类型一致,至少n个节点之间能互访
3.每个节点上的配置都一模一样
1./etc/hosts
127.0.0.1 localhost
1.0.0.1 1
2./etc/profile文件
1.JDK的环境变量
2.Hadoop的环境变量
3.Hadoop集群的配置文件
0.用于存储各个集群产生的数据的目录一致

		1./opt/links/hadoop/etc/hadoop/hadoop-env.sh
			L25:export JAVA_HOME=/opt/links/jdk
		2./slaves文件

		3.core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml
		4.免密登录
		5.集群管理

		注意:由于每个节点上的配置文件都一样,先配置好一个,scp远程拷贝过去

主节点到vi ~./bashrc

全分布式模式:一般在生产环境中
伪分布式模式:在处理小数据或者mapreduce程序调试
单机模式:只用于mapreduce程序调试,直接解压hadoop,不做任何配置,只需要配置环境变量,然后直接使用

HDFS:hadoop distributed file system

1.数据存储
2.hdfs一般不做删改,只做增查;由于hdfs集群中存储的是一些应用产生的原始数据,所以不删改
3.不适合低延迟的数据访问:hadoop不适合于实时数据
4.不适宜存储大量的小文件。HDFS中的nn承担了索引区的内容,DN承担了数据区功能,当存储大量小文件时nn的负载会加重,会影响整个集群的性能。(格式化:分为索引区和数据区)。
5.主从式结构的集群。
6.数据分块 和数据块的备份保证了数据在HDFS上存储的安全性,HDFS在做备份的过程中会尽可能的将不同的数据块备份到不同的节点上,如果对于数据的安全性要求比较高,则可以备份多次,可以在HDFS配置文件中设置备份数,牺牲空间换取数据的安全性。

副本:replication
掩码:umask

#day3

数据块(DateBlock):一个大文件上传 到DFS集群之前,被DFS按照配置的数据块的大小切分成n多的块,把每一个块称之为数据块。

数据块副本(备份数):对数据库进行备份处理,以保障数据的安全性。可以配置 dfs.replication dfs.blocksize(配置块大小)

HDFS中的文件是一次性写入的,并且保证同一时刻针对于一个文件只能有一个写入者。

Namenode:HDFS中的主节点:
1.在HDFS集群中至少有一个NN;
2.维护着HDFS文件系统中文件的元数据(文件的属性信息)和文件系统树。(HDFS为了提高性能,将文件系统树加载在内存当中);
1.HDFS的NN所产生的数据中有两个文件,一个是FSImage,存放的事当前文件系统的状态;另一个是Edits,存放的是某个时刻或某个时间段对于该集群的操作,上传和删除的行为所产生的结果会暂时存放在edits中。当HDFS集群空闲的时候或者距离该操作时间较长的时候,SNN会将FSImage和Edits文件合并,如果没有配置SNN,则该操作由NN完成。
3.协调客户端对文件的访问操作

DataNode:数据节点:HDFS集群中用于存储文件的内容数据的节点。
1.一个集群中可以存在多个DN
2.接收客户端或者NN的调度
3.DN会定期向NN汇报自身存储的数据块列表以及可用空间
4.最主要的功能:检索存储的数据块。

SecondaryNameNode:辅助节点
1.合并FSImage和Edits
2.做NN的备份节点

HDFS命令

cp 时不需要加-r

mv 移动

-cat 查看文件内容

-text 查看时会根据查看的内容做相应的转换

-df 查看集群容量详细信息

保障hdffs集群数据可靠性的措施

1.冗余备份:备份副本
2.副本存放:将数据存放在不同的机架上
3.心跳监测:NN周期性地从集群中的每个DN中接受心跳包和块报告
4.安全模式:0.999
5.数据完整性检测:HDFS客户端软件实现了对HDFS文件内容的校验和  检查

HDFS联邦:多个NN

maven:管理jar包

hadoop-common

hadoop-client

##day4

基于JavaAPI的HDFS编程:
1.org.apache.hadoop.conf.Configuration:获取集群的相关配置信息。(core-default.xml,core-site.xml。。。)
2.org.apache.hadoop.fs.FileSystem:获取集群的文件系统,目录树结构。
3.org.apache.hadoop.fs.Path:该类封装了要访问的文件的路径。
4.org.apache.hadoop.fs.FSDataInputStream:从集群中读取文件形成流。
5.org.apache.hadoop.fs.FSDataOutputStream:将文件写入到集群形成的流。

6.步骤:
	1.Configuration conf=new Configuration();
      conf.set("fs.defaultFS","file:///....");

	2.FileSystem fs=FileSystem.get(conf);
		注意:获取到的对象并不只是针对于集群的对象,还可以是本地文件系统,或者FTP文件系统的对象。

	3.获取和集群文件相关的流:输入流和输出流。

	4.对流进行操作。

hadoop中的输入输出:IO
1.数据一致性,
2.压缩和解压缩,编解码器
3.hadoop中的序列化
4.序列文件

1.数据一致性校验是在文件上传的时候,先生成一个CRC32的检验码文件,该文件会随着文件一起上传到集群,然后集群再根据原文件生成一个CRC32校验核文件,然后对比集群生成的校验核文件和上传的文件

2.压缩和解压缩,编解码器:
hadoop中默认的是deflate压缩方式
1.程序会通过写入或者读取的文件的扩展名来判断使用哪种编解码器
2.如果文件的扩展名和本身使用的编解码器不一致的时候,需要自定义编解码器, 需调用set方法将conf对象传递进去。

##day5

HDFS读取文件的流程:
HDFS客户端创建DistributedFileSystem对象,通过open操作和主节点进行通信,告诉主节点他想取得的文件,然后主节点检查一系列的权限,检查通过后,NN会返回给客户端一个FSDataInputStream对象,(FSDataIputStream对象中包含客户端想要读取的文件的数据块信息),客户端拿到流对象后发出读操作(read),开始从每一个DN上面读取,读取时由DFSInputStream去读,读取后交给客户端,当所有的读操作完成后close流,
HDFS写文件的流程:半异步过程
客户端发起写操作,创建DistributedFileSystem对象,调用create方法(和NN进行通讯,传递给NN一些文件的属性包括写入文件的用户的一些属性,NN做一些列的检查),检查通过后,NN会返回给客户端一个FSDataOutputStream对象(里面包括要把文件写入到哪一个DN,数据块的大小等信息),客户端拿到输出流在之后。执行写操作write,在FSDataOutputStrem 内部产生一个DFSOuutputStream流对象,封装成包,把包交给DN,在从节点内部产生一个 流对象DataStream,DataStream对象才是真正将数据写入DN的流,当所有的DataStream写入数据后返回给DFSOutputStream写数据成功,DfSOutputStream返回给FSDataOutputStream,返回给客户端写入成功,关闭流

hadoop中的序列化和反序列化:

序列化:将对象或者数据转化成字节流的过程
反序列化:将字节流转化成对象或者数据的过程

java中如何实现序列化?
实现java.io.serializable接口
此接口中没有方法,此接口被称之为标记接口

序列化要求:
1.紧凑
2.快速
3.可扩展
4.可交互

由于大数据的特殊性,hadoop需要实现自己的序列化机制
hadoop.io.Writable接口用于实现hadoop中的序列化;该接口只是提供序列化的标准。
1.void write(DataOutput dop) //序列化
2.void readFiels(DataInput dip) //反序列化

Attribute:
Propertites:
Argument:
Parameter:
Field:
Variable:

hadoop中数据类型和java的数据类型基本一致,只不过都被writable进行了包装

writable:该接口用于hadoop中的序列化

Hadoop中已经提供的能够使用Hadoop序列化机制进行序列化的数据类型:
1.int IntWritable 4
VIntWritable 1-5

2.double	DoubleWritable		8

3.String	Text				x

4.long		LongWritable		8
			VLongWritable		1-9

5.byte		ByteWritable		1

6.short		ShortWritable		2

7.char		没有,可用IntWritable代替

8.float		FloatWritable		4

9.boolean	BooleanWritable		1

comparable:用于对象的大小比较。【MR程序中的Key需要具有比较大小功能】

java中的String类型对应到hadoop中是Text类型;也就是Text类也实现了上面的两个接口。

java中已经有序列化机制,为何hadoop还要实现自己的序列化机制?
java序列化机制的序列化结果所占用的字节数太多,导致不适合大量数据的传输。

问:为什么要做序列化?
答:方便网络应用程序之间的数据交互【Hadoop】;将数据持久化到磁盘。

1.紧凑
2.快速
3.可扩展
4.可交互

Java中也有序列化:实现java.io.Serializable接口
此接口中没有方法,此接口被称之为标记接口。

Hadoop中的序列化:实现org.apache.hadoop.io.Writable接口
1.void write(DataOutput dop); // 序列化
2.void readFields(DataInput dip); // 反序列化

自定义数据类型:在hadoop中,自定义数据类型需要注意,
1.如果该数据类型必须能够被hadoop的序列化机制序列化与反序列化,也就是自定义的类需要实现writable接口;
2.如果该数据类型需要作为MR程序中的key,则要求该数据类型具备可比较性,也就是自定义类需要实现Comparable接口或者直接实现WritComparable接口;

Comparable和Comparator
相同点
都能比较
都是接口
不同的
comparable是让它的实现类 具有可比较性

	comparator的实现类可以比较没有可比较性的类的对象

自定义一个可序列化的类:

##day6

重载:
1.只和方法名和参数列表有关
2.该现象只存在于同一个类中
重写:
1.该现象存在于子类中
2.和权限修饰符、返回值类型、方法名、参数列表、异常相关
1.权限修饰符:子类要大于父类
2.返回值类型要一致
3方法名必须一致
4.参数列表必须一致
5.子类异常要小于父类异常

Comparable接口:让该接口的实现类具有可比较性;
1.int compareTo(Object o);
Comparator接口:让该接口的实现类具备对其他对象进行比较的功能。
1.int compare(Object a,Object b);

WritableComparable:接口;继承自Writable接口和Comparable接口;该接口中没有特有方法,只有来自于父接口中的三个方法;

RawComparator:接口;继承自Comparator接口;该接口能够使用的方法有俩,一个是来自于父接口中的;一个是特有方法,该方法是从字节层面进行比较:
int compare(byte[] a,int as,int al,byte[] b,int bs,int bl);

WritableComparator:类;实现了RawComparator接口,该类中能够使用方法有很多,通常关注的是他的一个特有方法:
int compare(WritableComparable a, WritableComparable b);
// 该方法主要用于对WritableComparable类型的两个对象做大小比较。

该类一般用于自定义的类中的比较规则不符合当前的比较需求时,则需要重新定义比较器对其进行比较。适用于二次排序。

super(T.class,【true】);

如何自定义一个能够作为MR程序中的Key的数据类型?
1.实现Writable接口,目的是能够进行序列化;
1.write
2.readFields
2.实现Comparable接口,目的是能够进行大小比较;
1.int compareTo();
3.一般还需要【必须】重写父类【Object类】中的hashCode方法和equals方法。(为了防止和compareTo比较结果产生二义性)
equals()方法用于比较两个对象是否相等:
1.如果子类没有重写该方法,使用==比较,==比较的是两个对象的内存地址【哈希值的十六进制表示】。

4.一般还需要重写父类中的toString方法。

自定义数据类型中get set方法需要注意的点:
再进行赋值操作时,要使用值赋值【值复制】,而不是引用赋值。

SequenceFile:基于二进制的文件,该文件的主要作用是用程于后期的MR序,用于存储小文件。

基于记录的压缩:同步标记:随机定位,跳过有问题的数据
基于块的压缩:
生成:
0.至少给提供三个选项:
1.路径:SequenceFile.Write.Option o1 =
2.key类型:SequenceFile.Write.Option o2 =
3.Value类型:SequenceFile.Write.Option o3 = S.W.valueClass(Writable.class)
1.获取SequenceFile.Write对象

	2.写入数据
		writer.append(new KeyType(),new ValueType());

读取:
	1.至少提供路径选项
	2.创建SequenceFi.Reader对象,通过new关键字直接创建
	3.boolean x = reader.next(key,value)
		1.reader对象先判断序列文件中有么有下一个键值对,如果有,将键读取到key中,如果没有,将值读取到value中。

##day7

关于序列文件的压缩
1.在生成序列文件是,使用选项指定进行压缩的类型和编码器,但是编码器只能使用defaultcodec和bzip2codec
2.在读取压缩序列文件时,不需要使用任何解码器,因为SequenceFile.Reader本身就具备解码功能

使用序列文件存储大量的小文件
练习1:以文件的绝对路径名作为key,文件的内容作为value,将某个目录下的所有文件【包括文件和子目录】存储到序列文件中
注意:当该目录下是文件时。value是 文件内容

练习2:将上述内容以递归的形式存储

Hadoop中的MapReduce

并发访问:多个客户端同时访问同一个服务器。

并行计算:多个计算机或者服务器同时执行同一个应用程序,但是所处理的数据有可能不同。和进程相关。MapReduce框架就是并行计算框架的一种。

什么样的数据适合使用并行程序处理
一般是将一个大的数据切分成若干个小块,每个小块之间是相互独立的,没有很强的联系,这样的数据才能被并行程序处理;但是当的数据被切分成小块之后,每个小块之间仍然存在着联系,此时需要根据实际需求来判断是否能够使用并行程序处理。

MapReduce框架 / MapReduce计算模型
1.MapReduce是计算框架,并不是hadoop特有
2.MapReduce的具体过程:
1.数据以(k1,v1)【键值对】的形式进入Map阶段,由Map阶段开始处理。
2.经过Map阶段处理的结果以(k2v2)的形式离开Map,作为中间临时结果存储。
3.临时处理结果数据经过MapReduce框架的作用【Shuffle过程】,形成(k2,【v2】),将所有的k2相同的v2 组成集合
4.数据以(k2,【v2】)进入Reduce处理,形成最终的结果(k3,v3)

	注意:

数据分块【HDFS】:将一个大的数据按照dfs.blocksize的配置进行切分,形成若干个数据块,数据块会被存储到不同的DN上。

数据分片【MR】:被一个Map任务所处理的所有数据称之为数据分片;一个数据分片有可能来自于多个数据块;一般近似认为一个数据块就是一个数据分片;也意味着有多少个数据块,就会有多少个Map任务。

洗牌过程[shuffle0]
分区:决定从map出来的每一组数据【(k2,v2)】进入哪一个reducer,默认是根据k2的哈希值确定
分组:将k2相同的v2形成集合
排序:决定reducer先处理哪一组数据

##day8

1.MR程序的调试:使用System.out.println()进行调试,该输出语句 会将程序的运行结果保存到MR程序的运行日志中;该输出结果可在Yarn集群的历史作业中看到

直接在idea中运行mapreduce程序

##day9
1.MR程序的调试:使用System.out.println()进行调试,该输出语句会将数据结果保存至MR程序的运行日志中;该输出信息可以在YARN集群的Web监控页面的作业历史日志中看到。

Map阶段>Map Task>Map Attempt

2.直接在Idea中运行MapReduce程序;

注意:如果将MR程序提交到YARN集群上执行,则执行的结果必须会保存到集群上。

设置执行Reduce任务的个数:
1.mapred-site.xml:

mapreduce.job.reduces
1

2.代码中配置:
job.setNumReduceTasks(5);
3.命令行参数中配置:
-Dmapreduce.job.reduces=5

Shuffle,洗牌:
1.分区:决定从Map端出来的数据进入哪个Reducer。
Reducer>1:
1.计算k2的哈希值;
2.使用该哈希值整除以Reducer的个数;
3.余数是x,就让该数据进入编号为x的Reducer。
2.分组:让K2相同的V2形成集合;在分组的时候,各个Map的执行结果数据要进行汇总处理。

3.排序:决定哪一组数据先让Reducer处理;
	1、Map同一时刻只能处理一行数据;处理一行数据,map方法被调用一次。
	2、Reduce同一时刻只能处理一组数据;处理一组数据,reduce方法被调用一次。

##day10

MR程序执行流程:
1.客户端提交作业给YARN集群,RM接受客户端所提交的作业。
2.RM根据作业所要处理的文件来决定Map任务在哪些节点上执行,然后确定Reduce任务在哪些节点【NN】上执行。
3.RM分配Map任务和Reduce任务到相应的节点上。
4.Map任务开始执行,将执行结果临时保存到本地【执行过Map任务的节点】。
5.当Map任务执行完成之后,Reduce任务开始执行,Reduce任务从远程节点上获取数据。
6.Reduce任务执行完成,得到最终的结果。

Hadoop高级编程之:Combiner,对MR程序进行优化。
1.Combiner的本质就是Reducer。
2.是执行在Map端的Reducer。
3.程序中是否使用Combiner不能影响正常的Map到Reduce的数据传输;其实就是Combiner数据输入的K和V的数据类型与其数据输出的K和V的数据类型一致。【数据从Map交给Reduce的时候,Map的输出K和V的数据类型与Reduce输入的K和V的数据类型一致。】
4.如果程序中的Reducer的数据输入的K和V的数据类型与数据输出的K和V的数据类型一致的时候,该Reducer可以直接作为Combiner来使用;一般情况下,Combiner的逻辑和Reducer的逻辑一般无二。
5.一般情况Combiner和Reducer的计算逻辑【过程】是一致的,但是Reducer不一定能直接作为Combiner来使用,跟需求有关,此时,只能自定义Combiner。

没有Reducer的MR程序:Map输出的结果直接存放至HDFS集群。
没有Mapper的MR程序:其实并不是没有Mapper,而是MR框架会使用默认的Mapper,因为Mapper阶段用于读取数据。

最小配置的MR程序:输出该行的偏移量\t该行内容

##day11

0.Combiner优化

1.没有Reducer的MR程序
2.没有Mapper的MR程序
3.最小的作业配置,没有Mapper和Reducer

1.MR程序中使用SequenceFile
2.使用DoubleWritable作为MR程序的Key

4.MR程序中使用SequenceFile:
1.将MR程序的输出格式定义为SequenceFileOutputFormat,此时MR程序的计算结果就会被保存为序列文件。【不需要设置序列文件的Key和Value的数据类型,job.setOutputKeyClass(),job.setOutputValueClass()】;

2.MR程序可以直接读取序列文件,但是需要知道序列文件的Key和Value的数据类型;将MR程序的输入格式定义为SequenceFileInputFormat,需要将Map的输入的Key的数据类型定义为序列文件中的Key的数据类型,将Map输入的Value的数据类型定义为序列文件中Value的数据类型;在map方法中的参数key就是序列文件中的key,value就是序列文件中的value。

例子:获取天气数据中的三列数据:year,sid,temp;根据传递的命令行参数的不同使用不同的输出格式控制。

1.生成的是文本格式,输出的Key的数据类型:IntWritable。
2.生成的是序列文件,输出的Key的数据类型:IntWritable。

3.设置多个Reducer,生成文本格式的数据;并不一定是所有的Reducer全部都工作:
	1.多少个Reducer工作跟产生的Map端输出的Key有关。
	2.跟Map端输出的Key的数据类型相关。
	注意:在编写MR程序的时候,尽量不要使用DW作为Key。

4.设置多个Reducer,生成序列文件格式。

5.使用DoubleWritable作为MR程序的Key。

MR框架提供的Mapper和Reducer:
Mapper:是所有自定义的Mapper父类;将输入进行原样输出。
ChainMapper:当程序中有多个Mapper的时候,进行链式Mapper调用。
InverseMapper:将输入的Key和Value进行互换输出。
LongWritable,Text Text,LongWritable
TokenCounterMapper:用于做统计。
RegexMapper:使用正则表达式。

Reducer:是所有自定义Reducer的父类;将输入进行原样输出。
	ChainReducer:方便于做Reduce端的链式调用,整个程序中只能有一个Reducer,在Reducer后面可以添加多个Mapper。
	IntSumReducer/LongSumReducer:对输入的Key所对应的Value进行求和。

例子:专利统计,计算每个专利被应引用的次数。
	Map:		输出:被引用的专利编号,1。
	Reduce:	输出:将Key相同的集合中的元素相加。

	专利统计:使用MR框架已经提供的Mapper和Reducer。
		原始数据:pid,cid
		TextInputFormat:<LongWritable,Text,X,Y>
		KeyValueTextInputFormat:<Text,Text,X,Y>
		
		0.指定Key和Value的分隔符为“,”,
			conf.set("mapreduce.input.keyvaluelinerecordreader.key.value.separator",",");
			-Dmapreduce.input.keyvaluelinerecordreader.key.value.separator=','

			Key:pid
			Value:cid

		1.InverseMapper:将Key和Value进行互换输出。
			Key:cid
			Value:pid

		2.使用TokenCounterMapper;
			Key:cid
			Value:1

		3.使用IntSumReducer求和:
			Key:cid
			Value:和

		4.使用ChainReducer添加InverseMapper:
			Key:和
			Value:cid

##day12

二次排序:对处理的数据生成的结果先按照某一个标准进行排序,如果该标准相同则按照另一个标准排序

连接:join,将多个数据集按照某一些相同的部分进行合并。
内连接:取交集
左外连接:左表全部和右表中有关系的数据
右外连接:

左表:
右表:

Map端连接:
	1.本质上在数据进入map端之前
	2.要求
		1.被连接的两个数据集不能再分片
		2.被连接的两个数据集的分块数相同
		3.被连接的两个数据集内部的每个数据块的内部要按照连接条件局部有序

Reduce连接:
	1.多输入:有多个map任务,每个map任务处理不同的数据,但是处理的结果需要进入同一个reduce,只跟作业配置有关。
	2.二次排序

##day13
reduce端连接
map端连接

实现:
	1.编写MR程序,按照上述三个条件对原始数据预处理
	2.编写MR程序,处理经过预处理的数据,实现map端连接

##day14
输入输出格式控制:
1.输入格式控制:控制原始文件进入map的格式;InputFormat.class
1.FileInputFormat:当MR程序的输入时来自于文件【文本文件、序列文件】时;
1.TextInputFormat<LongWritable,Text>
1.处理文本文件
2.数据分片近似是一个数据块
2.KeyValueTextInputFormat<Text,Text>
1.处理文本文件
2.数据分片近似是一个数据块
3.NLineInputFormat<LongWritable,Text>:
1.处理文本文件
2.数据分片是N行数据;【N是一个具体的数值,可以在程序中指定】
4.CombineFileInputFormat<LongWritable,Text>:针对于小文件 ,当处理N多小文件时,指定该输入格式控制,则会将多个小文件看成一个数据分片去处理
1.处理文本文件
2.整个处理过程只有一个数据分片
5.SequenceFileInputformat<LoongWritable,text>
1.处理序列文件
2.近似认为一个数据块是一个数据分片,但是当一个map处理的数据不完整时,一个数据块中包含不完整的同步标记时,
2.DNInputFormat<LongWritable,? extends DBWritable>:
LongWritable:表示数据库中每一条数据的序号
? extends DBWritable:用于表示数据库中的每一条记录

		注意:一般需要自定义数据类型,用于表示数据库中的一行数据。需要实现DBWritable接口:重写write()和readFields

2.输出格式控制
	1.FileOutputFormat:用于输出,在HDFS集群上生成文件
		1.
		2.
	2.DBOutputFormat<? extends DBWritable,V>:用于输出,输出结果保存在数据库中;该输出格式控制,只能讲Key写入到数据库中

项目:
作业流控制
当要处理某些数据集的时候,MR作业不止一个,而且有些作业之间可能存在着依赖关系,所以需要对作业使用作业流控制,让其进行自动提交作业。

JobControl:提交所有作业

ControilledJob:如果想让作业流控制功能来控制创建的Job,必须将Job对象转化成可被控制的作业,即ControlledJob对象

注意:
	1.
	2.

将作业转化成可被控制
添加作业之间的依赖关系
线程流

##day15

全分布式集群搭建

zookeeper:搭建在奇数个节点上,非主从式架构,只要集群的所有节点有一半以上的zk节点正常启动,则认为整个zk集群正常启动,就能正常工作。

一般Haodoop集群中不同的集群会由不同的用户管理
HDFS集群
YARN集群
MR程序

YARN集群:另一种资源协调者
MR框架:
1.运行程序
2.作业调度
3.资源管理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值