什么是hadoop?
Hadoop无非就是:HDFS(文件系统),yarn(任务调配),mapReduce(编程模型,大数据并行运算),我们安装完hadoop就已经包括了以上;
Hadoop集群其实就是HDFS集群。
HDFS:其实就是个文件系统,和fastDFS类似,像百度云,阿里云等就是个文件存储系统,当然一般如果仅仅是为了用来存储文件的话直接fastDFS这个就已经够了,HDFS目的不单单是用来存储文件这么简单,它还涉及分布式计算等。
HDFS工作原理:
HDFS分有NameNode和DataNode,NameNode是整个文件系统目录,基于内存存储,存储的是一些文件的详细信息,比如文件名、文件大小、创建时间、文件位置等。Datanode是文件的数据信息,也就是文件本身,不过是分割后的小文件。上面图已经有做了介绍了,这里就不再赘述了。
Yarn:是一种新的 Hadoop资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。
MapReduce:MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)"和"Reduce(归约)",是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
集群搭建过程:
1.专有用户的创建
//创建hadoop用户
[root@Linux1 ~]# useradd hadoop
[root@Linux1 ~]# passwd hadoop
//新用户没有sudo权限
[hadoop@Linux1 ~]$ sudo cat /etc/sudoers
[sudo] hadoop 的密码:
hadoop 不在 sudoers 文件中。此事将被报告。
//为用户添加sudo权限
[hadoop@Linux1 ~]$ su root
[root@Linux1 hadoop]# vim /etc/sudoers
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
//此处添加
hadoop ALL=(ALL) ALL
//将sudoers发送到别的服务器
[hadoop@Linux1 ~]$ sudo scp /etc/sudoers linux2:/etc/sudoers
[hadoop@Linux1 ~]$ sudo scp /etc/sudoers linux3:/etc/sudoers
[hadoop@Linux1 ~]$ sudo scp /etc/sudoers linux4:/etc/sudoers
2.专有用户下添加文件夹apps,便于安装软件
[hadoop@Linux1 ~]$ mkdir apps
3.传输编译后的cenos-6.5-hadoop-2.6.4.tar.gz到用户目录下
[hadoop@Linux1 ~]$ ll
总用量 176580
drwxrwxr-x. 2 hadoop hadoop 4096 8月 26 07:31 apps
-rw-r--r--. 1 root root 180813065 8月 26 07:05 cenos-6.5-hadoop-2.6.4.tar.gz
//解压到apps文件夹下
[hadoop@Linux1 ~]$ tar -zxvf cenos-6.5-hadoop-2.6.4.tar.gz -C apps/
4.五处配置
//1.hadoop-env.sh 实际工作中,需要ssh远程启动hadoop,这时$JAVA_HOME不生效,所以需要直接配置
vi apps/hadoop-2.6.4/etc/hadoop/hadoop-env.sh
[hadoop@Linux1 ~]$ cd apps/hadoop-2.6.4/etc/hadoop/
[hadoop@Linux1 hadoop]$ echo $JAVA_HOME
/usr/local/jdk1.7.0_65
[hadoop@Linux1 hadoop]$ vi hadoop-env.sh
#export JAVA_HOME=${JAVA_HOME}
export JAVA_HOME=/usr/local/jdk1.7.0_65
export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_PREFIX}/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib"
//2.core-site.xml
vi apps/hadoop-2.6.4/etc/hadoop/core-site.xml
[hadoop@Linux1 hadoop]$ vi core-site.xml
<!-- 文件系统有hdfs,gfs,tfs,nfs 需要指定HADOOP所使用的文件系统schema(URI)-->
<property>
<name>fs.defaultFS</name>//选择默认hdfs
<value>hdfs://linux1:9000</value>//uri统一资源定位符,HDFS的老大(NameNode)的地址
</property>
<!-- 指定hadoop运行时产生文件的存储目录 -->//每一台服务器都有 进程数据目录
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/hdpdata</value>
</property>
//eg:
在/home/hadoop/hdpdata/dfs/中
data(启动datanode的服务器中有)
name(namenode的服务器中有)
namesecondary(secondnamenode的服务器中有)
如果在下个配置3中,如果配置了dfs.name.dir
则namenode的服务器中没有/home/hadoop/hdpdata/
如果没有配置,则走上面默认的配置
//3.hdfs-site.xml
vi apps/hadoop-2.6.4/etc/hadoop/hdfs-site.xml
[hadoop@Linux1 hadoop]$ vi hdfs-site.xml
<!-- 指定HDFS副本的数量 -->
<property>
<name>dfs.replication</name>
<value>2</value>//默认为3
</property>
//secondary namenode的ip,不配置的话,为0.0.0.0
<property>
<name>dfs.secondary.http.address</name>
<value>linux2:50090</value>
</property>
//元数据在内存中,每一个操作写入edits,edits放到多个磁盘下,如果不进行配置,则默认配置为2中core-site.xml的hadoop运行时产生文件的存储目录 /home/hadoop/hdpdata/dfs/name
<property>
<name>dfs.name.dir</name>
<value>/home/hadoop/name1,/home/hadoop/name2</value>
</property>
//4.mapred-site.xml (mv mapred-site.xml.template mapred-site.xml)
mv mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
<!-- 指定mr运行在yarn上 -->将mapreduce放在yarn资源调度平台上运行,yarn将mr分配给内存,cpu再启动程序(集群上分布运行)
<property>//不配置的话,默认为local,mapreduce会单机跑(单机)
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
//5.yarn-site.xml
<!-- 指定YARN的老大(ResourceManager)的地址 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>linux1</value>
</property>
<!-- reducer获取数据的方式 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
5.配置完成后,将文件夹apps发送到其余服务器
[hadoop@Linux1 ~]$ scp -r apps/ linux2:/home/hadoop/
[hadoop@Linux1 ~]$ scp -r apps/ linux3:/home/hadoop/
[hadoop@Linux1 ~]$ scp -r apps/ linux4:/home/hadoop/
6.配置环境变量--格式化--启动集群
将hadoop添加到环境变量
[hadoop@Linux1 ~]$ sudo vi /etc/profile
vim /etc/proflie
export JAVA_HOME=/usr/java/jdk1.7.0_65
export HADOOP_HOME=/home/hadoop/apps/hadoop-2.6.4/
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS=-Djava.library.path=$HADOOP_HOME/lib
//桌面版只能把$PATH放最后
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
source /etc/profile
格式化namenode(是对namenode进行初始化)生成初始目录初始账本
hdfs namenode -format (hadoop namenode -format)//两个命令相同
//配置slaves,启动datanode,方便自动化启动脚本的运行
vi apps/hadoop-2.6.4/etc/hadoop/slaves
[hadoop@Linux1 ~]$ cd apps/hadoop-2.6.4/etc/hadoop/
[hadoop@Linux1 hadoop]$
linux2
linux3
linux4
启动hadoop
先启动HDFS
sbin/start-dfs.sh
再启动YARN
sbin/start-yarn.sh
也可以一步启动
[hadoop@Linux1 ~]$ apps/hadoop-2.6.4/sbin/start-all.sh
start-all.sh
stop-all.sh
验证是否启动成功
使用jps命令验证
27408 NameNode
28218 Jps
27643 SecondaryNameNode
28066 NodeManager
27803 ResourceManager
27512 DataNode
http://linux1:50070 (HDFS管理界面)
http://linux1:8088 (MR管理界面)
hadoop完全初始化
//完全删除每一个服务器下的初始目录hdpdata文件夹
rm -rf /home/hadoop/hdpdata/
//格式化namenode(是对namenode进行初始化)生成初始目录
hadoop namenode -format
hdfs操作
//查看根目录
[hadoop@Linux1 ~]$ hadoop fs -ls /
//将文件放入HDFS根目录下,128mb为一块
[hadoop@Linux1 ~]$ hadoop fs -put cenos-6.5-hadoop-2.6.4.tar.gz /
//从HDFS中获取文件,自动拼接
[hadoop@Linux1 ~]$ hadoop fs -get /cenos-6.5-hadoop-2.6.4.tar.gz
//在hdfs上创建目录
[hadoop@Linux1 ~]$ hadoop fs -mkdir -p /aaa/bbb/cc/dd
//删除文件或文件夹(删除了bbb)
[hadoop@Linux1 ~]$ hadoop fs -rm -r /aaa/bbb/
常见问题
1/运行mr程序出错
connecting to resoucemanager
retrying ....
retrying .....
原因是没有启动yarn或者启动失败
2/初始化工作目录结构
hdfs namenode -format 只是初始化了namenode的工作目录
而datanode的工作目录是在datanode启动后自己初始化的
3/datanode不被namenode识别的问题
namenode在format初始化的时候会形成两个标识:
blockPoolId:
clusterId:
新的datanode加入时,会获取这两个标识作为自己工作目录中的标识
一旦namenode重新format后,namenode的身份标识已变,而datanode如果依然
持有原来的id,就不会被namenode识别
4/datanode下线后多久看到效果
datanode不是一下线就会被namenode认定为下线的,有一个超时时间
5/关于副本数量的问题
副本数由客户端的参数dfs.replication决定(优先级: conf.set > 自定义配置文件 > jar包中的hdfs-default.xml)
运行
//hdfs上创建原始文件所在目录
hadoop fs -mkdir -p /flowsum/input
vi flow.data
//将文件数据放入该目录
$ hadoop fs -put flow.data /flowsum/input
//导出 jar file ,需要指定运行类,两个目录参数
java -cp hadoop.jar cn.itcast.bigdata.mr.provinceflow.FlowCount /flowsum/input /flowsum/output
//java -cp 运行,会缺少jar包
//linux下,对于需要依赖的jar包使用-cp ,多个jar包之间使用冒号:java命令运行时注意.:
javac -cp .:httpcore-4.4.1.jar:httpclient-4.4.1.jar:commons-logging-1.2.jar TestIPMain.java
//hadoop jar .....会将hadoop环境中的jar包引入
hadoop jar hadoop.jar cn.itcast.bigdata.mr.provinceflow.FlowCount /flowsum/input /flowsum/output
//导出 runnable jar file ,不需要指定运行类
java -jar hadoop.jar /flowsum/input /flowsum/output
//hadoop jar .....会将hadoop环境中的jar包引入
hadoop jar hadoop.jar /flowsum/input /flowsum/output
关于大量小文件的优化策略:
1.默认情况下,textinputformat对任务的切片机制是按文件规则切片,不管文件大小,都会是一个单独切片,都会交给一个maptask
2.优化策略:
1.最好办法:将小文件先合并成大文件,再上传hdfs做后续分析
2.补救措施:如果已经是大量小文件再hdfs中了,可以使用另一种inputformat来做切片,它的切片逻辑和fileinputformat不同,它可以将多个小文件从逻辑上规划到一个切片中,这样,多个小文件就可以交给一个maptask