集群规划:
注意:
1、在hadoop2.0中通常由两个NameNode组成,一个处于active状态,另一个处于standby状态。Active NameNode对外提供服务,而Standby NameNode则不对外提供服务,仅同步active namenode的状态,以便能够在它失败时快速进行切换。
2、hadoop2.0官方提供了两种HDFS HA的解决方案,一种是NFS,另一种是QJM。这里我们使用简单的QJM。在该方案中,主备NameNode之间通过一组JournalNode同步元数据信息,一条数据只要成功写入多数JournalNode即认为写入成功。通常配置奇数个JournalNode。这里还配置了一个zookeeper集群,用于ZKFC(DFSZKFailoverController)故障转移,当Active NameNode挂掉了,会自动切换Standby NameNode为active状态。
一、准备工作
1、为各个节点设置主机名、IP:
vi /etc/hostname #编辑配置文件,修改主机名 注意:主机名不能有下划线。
vi /etc/hosts #编辑配置文件,修改IP和主机名的映射关系
#127.0.0.1 localhost 主机名 #修改localhost.localdomain为主机名
192.168.1.250 hadoop-master1
192.168.1.251 hadoop-master2
192.168.1.252 hadoop-slave1
最后重启电脑。
2、免密码登录
1、在每个节点都执行如下操作:
cd 回车
ssh-keygen -t rsa
cd .ssh
cp id_rsa.pub authorized_keys
2、在192.168.1.250和192.168.1.251(即两个NN)的/root/.ssh目录下执行:
ssh-copy-id root@192.168.1.252
ssh-copy-id root@xxx.xxx.xxx.xxx(如果还有其他节点)
3、将192.168.1.252(其他数据节点)的authorized_keys拷贝到192.168.1.250和192.168.1.251(即两个NN)上:
scp authorized_keys root@192.168.1.250:/root/.ssh
scp authorized_keys root@192.168.1.251:/root/.ssh
3、安装jdk
下载jdk-7u79-linux-x64.tar并上传到Linux服务器上
解压到/opt/app目录下
重命名为jdk7
vi /etc/profile文件,在文件末尾加上如下代码:
export JAVA_HOME=/opt/app/jdk7
export CLASS_PATH=$JAVA_HOME/lib
export HADOOP_HOME=/opt/app/hadoop
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin
执行source /etc/profile使修改生效。
执行Java -version,看输出的结果中是否是刚才安装的jdk,如果不是,则执行如下步骤。
进入/usr/bin,执行如下指令:
ln -s -f /opt/app/jdk7/bin/java
ln -s -f /opt/app/jdk7/bin/javac
ln -s -f /opt/app/jdk7/bin/javaws
最后执行Java -version 验证。
4、安装zookeeper。请参考其他资料,这里不做说明。
二、安装配置hadoop集群 (在192.168.1.250上操作)
1、解压Hadoop包:
tar -zxvf hadoop-2.6.0-cdh5.4.4.tar.gz
mv hadoop-2.6.0-cdh5.4.4 hadoop
rm -rf hadoop-2.6.0-cdh5.4.4.tar.gz
2、配置Hadoop相关配置文件
core-site.xml、hdfs-site.xml、yarn-site.xml、slaves。这里配置文件的路径在hadoop/etc/hadoop下。
core-site.xml文件:
<configuration>
<!-- 必须和hdfs-site.xml中dfs.nameservices一致,如果直接写成hdfs://192.168.1.250:8020,则不能通过zookeeper自动切换 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop-test</value>
</property>
<!-- 指定hadoop临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/app/hadoop/tmp</value>
</property>
<!-- 指定zookeeper地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>192.168.1.250:2181,192.168.1.251:2181,192.168.1.252:2181</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<!--指定hdfs的nameservice,名称可以任意取,但需要和core-site.xml中的fs.defaultFS保持一致 -->
<property>
<name>dfs.nameservices</name>
<value>hadoop-test</value>
</property>
<!--指定Hadoop-test集群的namenode有那些,这里是逻辑名称,可以随便取名-->
<property>
<name>dfs.ha.namenodes.hadoop-test</name>
<value>nn1,nn2</value>
</property>
<!--hadoop-test的namenode的XXX地址,格式为dfs.namenode.XXX-address.{nameservices}.{namenode逻辑名}-->
<!-- Master的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.hadoop-test.nn1</name>
<value>192.168.1.250:60020</value>
</property>
<!-- Master的http通信地址 -->
<property>
<name>dfs.namenode.http-address.hadoop-test.nn1</name>
<value>192.168.1.250:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.hadoop-test.nn2</name>
<value>192.168.1.251:60020</value>
</property>
<property>
<name>dfs.namenode.http-address.hadoop-test.nn2</name>
<value>192.168.1.251:50070</value>
</property>
<!--(指定NameNode的fsimage存放地址)-->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///opt/app/hadoop/data/hdfs/name</value>
</property>
<!-- 指定NameNode的元数据在JournalNode上的存放位置,namenode的元数据分为fsimage和editlog,fsimage类似oracle数据库的数据文件,而editlog类似于oracle的redo日志文件 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://192.168.1.250:8485;192.168.1.251:8485;192.168.1.252:8485/masters</value>
</property>
<!--(指定dfs数据存储地址)-->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///opt/app/hadoop/data/hdfs/data</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/app/hadoop/data/hdfs/journal</value>
</property>
<!-- 开启NameNode失败自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!--指定 hadoop-test 出故障时,哪个实现类负责执行故障切换-->
<property>
<name>dfs.client.failover.proxy.provider.hadoop-test</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!--一旦需要 NameNode 切换,使用 ssh 方式进行操作-->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!--如果使用 ssh 进行故障切换,使用 ssh 通信时用的密钥存储的位置-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/root/.ssh/id_rsa</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
</configuration>
mapred-site.xml
<configuration>
<!-- 指定mr框架为yarn方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- jobhistory properties -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>192.168.1.251:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>192.168.1.251:19888</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<!-- 开启RM高可靠 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>RM_HA_ID</value>
</property>
<!-- 指定RM的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>192.168.1.250</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>192.168.1.251</value>
</property>
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>192.168.1.250:2181,192.168.1.252:2181,192.168.1.251:2181</value>
</property>
<!--可用物理内存-->
<!--
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>30720</value>
</property>-->
<!--可用的CPU个数-->
<!--
<property>
<name>yarn.nodemanager.resource.cpu-vcores</name>
<value>12</value>
</property>-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--rm1相关端口配置-->
<property>
<name>yarn.resourcemanager.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8032</value>
</property>
<property>
<description>The address of the scheduler interface.</description>
<name>yarn.resourcemanager.scheduler.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8030</value>
</property>
<property>
<description>The http address of the RM web application.</description>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8088</value>
</property>
<property>
<description>The https adddress of the RM web application.</description>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8090</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8031</value>
</property>
<property>
<description>The address of the RM admin interface.</description>
<name>yarn.resourcemanager.admin.address</name>
<value>${yarn.resourcemanager.hostname.rm1}:8033</value>
</property>
<!--rm2相关端口配置-->
<property>
<name>yarn.resourcemanager.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8032</value>
</property>
<property>
<description>The address of the scheduler interface.</description>
<name>yarn.resourcemanager.scheduler.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8030</value>
</property>
<property>
<description>The http address of the RM web application.</description>
<name>yarn.resourcemanager.webapp.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8088</value>
</property>
<property>
<description>The https adddress of the RM web application.</description>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8090</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8031</value>
</property>
<property>
<description>The address of the RM admin interface.</description>
<name>yarn.resourcemanager.admin.address</name>
<value>${yarn.resourcemanager.hostname.rm2}:8033</value>
</property>
<property>
<description>List of directories to store localized files in. An
application's localized file directory will be found in:
${yarn.nodemanager.local-dirs}/usercache/${user}/appcache/application_${appid}.
Individual containers' work directories, called container_${contid}, will
be subdirectories of this.
</description>
<name>yarn.nodemanager.local-dirs</name>
<value>/hadoop-hbase-cdh/hadoop-2.6.0/yarn/local</value>
</property>
<property>
<description>Whether to enable log aggregation</description>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<property>
<description>Where to aggregate logs to.</description>
<name>yarn.nodemanager.remote-app-log-dir</name>
<value>/hadoop-hbase-cdh/hadoop-2.6.0/tmp/logs</value>
</property>
</configuration>
修改slaves(告诉namenode,哪些节点需要启动datanode)
192.168.1.250
192.168.1.252
192.168.1.251
修改hadoop-env.sh和yarn-env.sh
JAVA_HOME=/opt/app/jdk7
将下载的native解压,然后上传到/opt/app/hadoop/lib/native目录下。
将配置好的Hadoop发送到其他节点上
scp -r /opt/app/hadoop root@xxxx:/opt/app
三、启动hadoop集群(下述指令没有特别指明在那个节点执行的,则最好在active NN节点执行,当然在hadoop集群的任意节点执行理论上而言都可)
1、启动zookeeper集群(每个zookeeper节点都需要执行)
/opt/app/zk/bin/zkServer.sh start
/opt/app/zk/bin/zkServer.sh status //查看集群状态,可以看到那个节点是leader,那个节点是follower
2、启动zkfc服务(首次启动hadoop时需要)
/opt/app/hadoop/bin/hdfs zkfc -formatZK
3、格式化namenode (首次启动hadoop时需要,并且在执行这步之前必须在各个节点先执行/opt/app/hadoop/sbin/hadoop-daemon.sh start journalnode)
/opt/app/hadoop/bin/hdfs namenode -format (如果一次不成功多试几次,这个不成功后面都没法玩)
/opt/app/hadoop/sbin/hadoop-daemon.sh start namenode(首次启动hadoop时需要,active NN 执行)
/opt/app/hadoop/bin/hdfs namenode -bootstrapStandby(首次启动hadoop时需要,standby NN 执行)
4、启动hdfs其他服务
/opt/app/hadoop/sbin/start-dfs.sh
这条指令启动后,正常情况下,系统会有如下几个进程:
QuorumPeerMain:zookeeper进程
JournalNode:JournalNode进程,负责保存edite log(日志文件),standby NN从JournalNode进程读取日志文件
DFSZKFailoverController:zkfc进程,Zookeeper Failover Controller:
(1)zkfc是要和NN一一对应的,两个NN就要部署两个FC。它负责监控NN的状态,并及时的把状态信息写入ZK。它通过一个独立线程周期性的调用NN上的一个特定接口来获取NN的健康状态。
(2)zkfc进程启动后都会去连接zookeeper,并且都去抢占一个ephemeral锁,如果某个节点抢占成功,那个这个节点就是active,而失败的节点成为standby。
(3)当activeNN因为某些原因失效后,就会释放ephemeral锁,而zookeeper就会通知另外一个zkfc进程,而另外一个zkfc进程则会在zookeeper中建立一个ephemeral锁,然后把本节点的NN切换成active状态。
NameNode:nn进程
DataNode:
5、关闭hdfs集群
/opt/app/hadoop/sbin/stop-dfs.sh
6、启动yarn服务(在192.168.1.251 standby resourcemanager节点执行)
/opt/app/hadoop/sbin/start-yarn.sh
7、启动yarn的resourcemanager服务(在192.168.1.250 active resourcemanager节点执行)
/opt/app/hadoop/sbin/yarn-daemon.sh start resourcemanager
注意:
上述指令执行完成后,几个节点的进程如下所示:
250: NameNode、DFSZKFailoverController(zkfc)、ResourceManager、DataNode、NodeManager、JournalNode、QuorumPeerMain
251: NameNode、DFSZKFailoverController(zkfc)、ResourceManager、DataNode、NodeManager、JournalNode、QuorumPeerMain
252: DataNode、NodeManager、JournalNode、QuorumPeerMain
如果某个节点少了某些进程,可再次启动相应进程,如果还不行,则需要去看相应的日志。
四、验证Hadoop集群
1、查看namenode节点谁是active,谁是standby
http://192.168.1.250:50070
http://192.168.1.251:50070
2、验证指令操作
去active节点(比如192.168.1.250)执行指令:bin/hadoop dfs -ls / 如果能执行指令,说明集群OK
kill掉active节点(比如192.168.1.250)的namenode进程,让standby namenode(比如192.168.1.251)变成active,
然后再去active节点(即192.168.1.251节点)执行指令:bin/hadoop fs -ls / 如果能执行指令,说明HA集群OK.
启动被kill掉的namenode:/opt/app/hadoop/sbin/hadoop-daemon.sh start namenode
3、Hadoop常用命令
将本地文件拷贝到Hadoop上:bin/hadoop fs -copyFromLocal /local/data /hdfs/data
删除目录:bin/hadoop fs -rmr /hdfs/data
创建目录:bin/hadoop fs -mkdir /hdfs/data
五、新增DataNode和NodeManager
1、修改新增节点、NN1、NN2的/etc/hosts文件,在其中加上新节点IP和名称的对应关系。
2、配置免密码登录
在新增节点192.168.1.xxx执行如下操作:
cd 回车
ssh-keygen -t rsa
cd .ssh
cp id_rsa.pub authorized_keys
在192.168.1.250和192.168.1.251的/root/.ssh目录下执行:
ssh-copy-id root@192.168.1.xxx
将192.168.1.xxx的authorized_keys拷贝到192.168.1.250和192.168.1.251上:
scp authorized_keys root@192.168.1.250:/root/.ssh
scp authorized_keys root@192.168.1.251:/root/.ssh
3、将NN1节点的Hadoop拷贝到新增节点中,注意一定要删除数据目录
4、启动datanode:/opt/app/hadoop/sbin/hadoop-daemon.sh start datanode
5、启动nodemanager:/opt/app/hadoop/sbin/yarn-daemon.sh start nodemanager