Hadoop能够说是大数据的代名词。
其实准确来讲是Hadoop家族是大数据的代名词,家族成员有:Hadoop、Hive、Pig、HBase、Sqoop、Zookeeper、Avro、Chukwa等。家族成员每一个基本均可以独挡一面,但结合他们,就能够架构出一个大数据平台。成员太多了,只能一个个的学,能够先学习Zookeeper,再到Hadoop,再到Hive等。
Hadoop又包含两部分:分别是HDFS和YARN。这篇文章将着重讲解Hadoop的搭建和HDFS。java
使用Hadoop版本是hadoop-2.7.3.tar.gz
假设有6台机器,分别是(角色以逗号分开):node
s1.jevoncode.com,zookeeper,namenode,zkfc, s2.jevoncode.com,zookeeper,namenode,zkfc, s3.jevoncode.com,zookeeper, s4.jevoncode.com,datanode,journalnode, s5.jevoncode.com,datanode,journalnode, s6.jevoncode.com,datanode,journalnode,
它们之间需免密钥登陆,这里就略,可自行百度。我这里提供关键命令:
1.在s1建立sshkeyshell
ssh-keygen
2.复制公钥到s2apache
ssh-copy-id root@s2.jevoncode.com
只要涉及多台机器协调服务,这就不得不安装ZooKeeper了。
安装过程出门左转《2018年第16周-ZooKeeper基本概念(配搭建过程和Master-Workers例子)》
现假设咱们在s1,s2和s3安装了ZooKeeper。编程
Hadoop的全部配置都在目录:
1.配置hadoop-env.sh,设置JDK目录和Hadoop目录bootstrap
export JAVA_HOME=/opt/jdk1.8.0_172 export HADOOP_CONF_DIR=/usr/local/hadoop-2.7.3/etc/hadoops
2.配置core-site.xml,指定逻辑主机名、hadoop的数据目录和ZooKeeper的地址segmentfault
<configuration> <!--用来指定hdfs的老大,ns为固定属性名,表示两个namenode--> <property> <name>fs.defaultFS</name> <value>hdfs://ns</value> </property> <!--用来指定hadoop运行时产生文件的存放目录--> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoopDataDir/tmp</value> </property> <!--执行zookeeper地址--> <property> <name>ha.zookeeper.quorum</name> <value>s1.jevoncode.com:2181,s2.c7.local.jevoncode.com:2181,s3.jevoncode.com:2181</value> </property> </configuration>
3.配置hdfs-site.xml,配置逻辑主机名,namenode节点地址,journalnode节点地址,journalnode的数据目录,指定故障转移控制器,配置fencing,指定namenode和datanode的数据目录,副本的个数,权限和节点之间的带宽设置,安全
<configuration> <!--执行hdfs的nameservice为ns,和core-site.xml保持一致--> <property> <name>dfs.nameservices</name> <value>ns</value> </property> <!--定义ns下有两个namenode,分别是nn1,nn2,而后再具体定义n1和n2--> <property> <name>dfs.ha.namenodes.ns</name> <value>nn1,nn2</value> </property> <!--nn1的RPC通讯地址--> <property> <name>dfs.namenode.rpc-address.ns.nn1</name> <value>s1.jevoncode.com:9000</value> </property> <!--nn1的http通讯地址--> <property> <name>dfs.namenode.http-address.ns.nn1</name> <value>s1.jevoncode.com:50070</value> </property> <!--nn2的RPC通讯地址--> <property> <name>dfs.namenode.rpc-address.ns.nn2</name> <value>s2.jevoncode.com:9000</value> </property> <!--nn2的http通讯地址--> <property> <name>dfs.namenode.http-address.ns.nn2</name> <value>s2.jevoncode.com:50070</value> </property> <!--指定namenode的元数据在JournalNode上的存放位置,这样,namenode2能够从jn集群里获取 最新的namenode的信息,达到热备的效果 格式:qjournal://host1:port1;host2:port2;host3:port3/journalId 其中,journalId 是该命名空间的惟一 ID --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://s4.jevoncode.com:8485;s5.jevoncode.com:8485;s6.jevoncode.com:8485/ns</value> </property> <!--指定JournalNode存放数据的位置--> <property> <name>dfs.journalnode.edits.dir</name> <value>/usr/local/hadoopDataDir/journal</value> </property> <!--开启namenode故障时自动切换--> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!--配置切换的实现方式--> <property> <name>dfs.client.failover.proxy.provider.ns</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!--配置规避机制--> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <!--配置规避机制的ssh登陆秘钥所在的位置,其余用户就指定用户的sshkey,如/homg/jevoncode/.ssh/id_rsa--> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <!--配置namenode数据存放的位置,能够不配置,若是不配置,默认用的是core-site.xml里配置的hadoop.tmp.dir的路径--> <property> <name>dfs.namenode.name.dir</name> <value>file:///usr/local/hadoopDataDir/namenode</value> </property> <!--配置datanode数据存放的位置,能够不配置,若是不配置,默认用的是core-site.xml里配置的hadoop.tmp.dir的路径--> <property> <name>dfs.datanode.data.dir</name> <value>file:///usr/local/hadoopDataDir/datanode</value> </property> <!--配置block副本数量--> <property> <name>dfs.replication</name> <value>3</value> </property> <!--设置hdfs的操做权限,false表示任何用户均可以在hdfs上操做文件--> <property> <name>dfs.permissions</name> <value>false</value> </property> <!-- 修改内网带宽限制为100MB,默认是10MB--> <property> <name>dfs.balance.bandwidthPerSec</name> <value>104857600</value> </property> </configuration>
4.建立目录/usr/local/hadoopDataDirbash
mkdir -p /usr/local/hadoopDataDir
5.配置/etc/profile网络
export HADOOP_HOME=/usr/local/hadoop-2.7.3 export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
6.在ZooKeeper建立高可用(HA)用的数据结点
hdfs zkfc -formatZK,这个指令的做用是在zookeeper集群上生成ha
7.启动journalnode服务,在s4,s5,s6节点执行命令:
hadoop-daemons.sh start journalnode
8.格式化namenode,在s1节点执行命令:
hadoop namenode -format
9.在s1启动namenode:
hadoop-daemon.sh start namenode
10.在s2设置namenode状态并启动namenode
hdfs namenode -bootstrapStandby hadoop-daemon.sh start namenode
11.在s4,s5,s6节点启动datanode服务:
hadoop-daemon.sh start datanode
12.在namenode节点s1,s2启动故障转移控制器
hadoop-daemon.sh start zkfc
13.现能够查看node结点的启动状况
http://s1.jevoncode.com:50070/
因为故障转移控制器也只是将standby状态的namenode替换为active状态,但以前的active namenode仍是会被kiil掉,而不是重启,因此在两个namenode节点都须要shell脚原本监听进程,当进程关闭时自动拉起:
文件名: hdfs-monitor.sh
#!/bin/bash while true; do beginTime=`date +%Y%m%d%H%M%S` echo $beginTime "monitor namenode" procnum=`ps -ef|grep "namenode"|grep -v grep|wc -l` if [ $procnum -eq 0 ]; then echo "namenode is crash, restart up..." hadoop-daemon.sh start namenode echo "finish" fi sleep 30 done
此脚本会每30秒检查namenode进程是否还存在,不存在则自动拉起。
为了保存这shell脚本的日志,咱们建立目录
mkdir /usr/local/monitor/namenode/ cp hdfs-monitor.sh /usr/local/monitor/namenode/
后台执行hdfs-monitor.sh
nohup ./hdfs-monitor.sh &
HDFS(Hadoop distributed filesystem),Hadoop分布式文件系统。
熟悉操做系统,特别是须要熟悉Linux系统,搭建大数据平台也是须要不少Linux知识的,能够看鸟哥私房菜,个人基本都是从他那学的。熟悉操做系统都知道,操做系统有一块是文件系统,文件系统封装了操做磁盘的细节,每一个磁盘都有默认的数据块大小,这是磁盘进行读/写的最小单位。因而咱们操做文件,就由文件系统映射到磁盘上对应的块,这对用户来讲是无感知的。
一样的,在大数据里,一个机器是不可能装下全部数据,哪怕能装满你的业务等数据,但磁盘的读写是个硬伤,1T硬盘,假设读的数据传输速度为100MB/s,读完正磁盘的数据至少得花2.5个小时。因此假设咱们有个100个机器,每部机器存储1%的数据,并行读写(都是顺序读),不到两分钟就能够读完全部数据。但仅使用1%的磁盘容量有点浪费,因而咱们能够存储多个数据集。因而经过网络管理多台机器存储的文件的系统,称为分布式文件系统(DFS)。
因此若是你熟悉Linux的文件系统,学起这个分布式文件系统会没那么吃力。
此系统架构于网络之上,势必也引入网络编程的复杂性。如文件系统的可以容忍节点故障且不丢失任何数据。为了不数据丢失,最多见的作法是复制(replication) :系统保存数据的副本(replica),一旦系统发生故障,就可使用另外保存的副本。
HDFS以流式访问数据的形式来存储超大文件,运行于商业硬件集群上。
HDFS集群上的机子都运行两个服务,分别是namenode和datanode,运行namnode服务的为管理节点,运行datanode的是工做节点。通常是有一个active状态的namenode、一个standby状态的namenode和多个datanode。
namenode管理文件系统的命名空间。它维护这文件系统树及整颗树内全部的文件和目录。这些信息以两个文件形式永久保存在磁盘上:命名空间镜像文件和编辑日志文件。namnode也记录着每一个文件中各个块所在的数据节点信息,但它并不永久保存块的位置信息,由于这些信息会在系统启动时根据datanode给的信息重建。
datanode是文件系统的工做结点。它们提供存储并检索数据块的功能(受客户端或namenode调度),而且按期向namenode发送它们所存储的块的列表。
客户端(client)表明用户经过namenode和datanode交互来访问整个文件系统。客户端提供一个类型POSIX(可移植操做系统节目)的文件系统接口,所以用户在编程时无需知道namenode和datanode也可实现其功能。
若是namenode失效了(就是没有Active状态的namenode),那么全部的客户端,包括MapReduce做业,均没法读写文件,由于namenode时惟一存储原数据与文件到数据块映射的地方。知道有新的namenode上线,Hadoop才能继续往外提供服务。
若是想要从一个失效的namenode恢复,系统管理员得启动一个拥有文件系统原数据副本的新的namenode,并配置datanode和客户端以便使用这个新的namenode,这个新的namenode只有知足如下情形才能响应服务:
1.将命名空间的映像导入内存中;
2.重演编辑日志;
3.接收到足够多的来自datanode1数据块报告并退出安全模式。
对于一个大型,并拥有大量文件和数据块的集群,namenode的冷启动须要30分钟,甚至更长时间。
Hadoop2针对上述问题,增长了对HDFS高可用用(HA)的支持。在这一个视线中,引入了一对活动-备用(active-standby)的namenode。架构上作了如下修改:
高可用共享存储有两种选择:NFS过滤器或群体日志管理器(QJM,quorum journal manager)。
QJM是一个专用的HDFS实现,为提供一个高可用的编辑日志而设计,被推荐用于大多数据HDFS部署中。
QJM以一组日志节点(journalnode)的形式运行,每一次编辑必须写入多数journalnode中。在本篇文章中的部署,就是使用三个journalnode,因此系统可以容忍其中任何一个的损失。这种安排与ZooKeeper的工做方式相似,但并无用Zookeeper。
QJM在同一时间仅容许一个namenode向编辑日志中写入数据。
首先,Hadoop不是只有namenode和datanode,做为商用,就必须高可用,因而有了QJM。
其次,QJM虽然没有用Zookeeper实现,但QJM也只Hadoop高可用实现的一部分(高可用共享存储的一个选择),还要有选取新的namenode做为active namenode这个实现,也就是后续要将的zkfc,它是基于Zookeeper的实现。
除了上述描述的QJM,做为高可用,还须要可以选取新的namenode做为active namenode。这个选取过程称为故障转移。Hadoop有一个称为故障转移控制器(failover controller),管理着将namenode之间的active和standby状态,在两个都是standby状态的namenode时,failover controller会将其中一个namenode状态为active,因此若是你没有启动故障转移控制,会发现两个namenode都是standby,整个HDFS都没法使用。
转移控制器有不少实现方式,但默认一种是使用了ZooKeeper来确保有且仅有一个active namenode。每一个namenode节点都运行着一个轻量级的故障转移控制器,其工做做用就是监视宿主namenode是否失效(经过一个简单的心跳机制实现)并在namenode失效时进行故障切换。
在本篇文章中的部署过程,hadoop-daemon.sh start zkfc 就是启动故障转移控制器。用jps命令就能看到java进程名为DFSZKFailoverController。
因为没法确切知道失效的namenode是否已经中止运行。Hadoop提供了方法“规避(fencing)”来确保先前active namenode不会执行危害系统并致使系统崩溃的操做。这个fencing是这样配置的:
<property> <name>dfs.ha.fencing.methods</name> <value>sshfence(jevoncode:10034)</value> </property>
当active namenode崩溃时,standby namenode会先根据上面的配置,经过ssh确认active namenode已经关闭(强制关闭,kill),而后再将自己状态至为active。
客户端的故障转移经过客户端类库实现透明处理。HDFS URI使用一个逻辑主机名,该逻辑主机名映射到一对namenode地址,客户端类库会根据这个配置访问每个naemnode,直到完成请求。这配置是dfs.nameservices,以下:
<!--执行hdfs的nameservice为ns,和core-site.xml保持一致--> <property> <name>dfs.nameservices</name> <value>ns</value> </property> <!--定义ns下有两个namenode,分别是nn1,nn2,而后再具体定义n1和n2--> <property> <name>dfs.ha.namenodes.ns</name> <value>nn1,nn2</value> </property> <!--nn1的RPC通讯地址--> <property> <name>dfs.namenode.rpc-address.ns.nn1</name> <value>s1.jevoncode.com:9000</value> </property> <!--nn1的http通讯地址--> <property> <name>dfs.namenode.http-address.ns.nn1</name> <value>s1.jevoncode.com:50070</value> </property> <!--nn2的RPC通讯地址--> <property> <name>dfs.namenode.rpc-address.ns.nn2</name> <value>s2.jevoncode.com:9000</value> </property> <!--nn2的http通讯地址--> <property> <name>dfs.namenode.http-address.ns.nn2</name> <value>s2.jevoncode.com:50070</value> </property>