高可用集群搭建
以下所有操作均在测试环境中执行
环境准备
于『VMWare』中安装『CentOS-6.8-x86_64』。注:尽量安装最新版VM,旧版会因一些操作导致虚拟机卡死,这将对我们接下来的操作产生严重影响
安装过程没什么可说的,唯一一点就是在创建磁盘分区的时候尽量选择『Create Custom Layout』(创建自定义布局)。
分区 | 大小(M) |
---|---|
/boot | 200 |
swap | 2048 |
/ | Fill to maximum allowable size(使用全部可用空间) |
配置静态『IP』。
vi /etc/sysconfig/network-scripts/ifcfg-eth0
参数 | 参数值 |
---|---|
HWADDR1 | 注释掉改行 |
ONBOOT | yes |
BOOTPROTO | static |
IPADDR2 | 虚拟网络编辑器-->VMnet8-->子网IP(替换第四组的0为100+) |
NETMASK | 虚拟网络编辑器-->VMnet8-->子网掩码 |
GATEWAY | NAT设置-->网关IP |
DNS1 | 114.114.114.114 |
DNS23 | 8.8.8.8 |
重新启动下网络。
service network restart
关闭防火墙4。
service iptables stop
禁用防火墙。
chkconfig iptables off
禁用安全模块5。
vi /etc/selinux/config
参数 | 参数值 |
---|---|
SELINUX | disabled |
此文件中会利用『eth0』和硬件地址做一个关联绑定。为方便后续克隆,保证克隆出的系统『eth0』接口可用,需要将此文件删除6,解除绑定关系。
rm -rf /etc/udev/rules.d/70-persistent-net.rules
poweroff
关机拍快照。
在快照管理器中选中快照,点击克隆,一路默认到设置虚拟机名称,输入自定义名称(PS:caroly01),选择克隆路径进行克隆。重复此操作克隆四台虚拟机(caroly01、caroly02、caroly03、caroly04)。
给四台克隆虚拟机分配『IP』,分别为『240.151』『240.152』『240.153』『240.154』,并重启网络。
service network restart
给四台克隆虚拟机重设主机名。
vi /etc/sysconfig/network
更改『HOSTNAME』的值分别为『caroly01』『caroly02』『caroly03』『caroly04』。注:主机名生效需要重启虚拟机
给四台克隆虚拟机配置『hosts』7。
vi /etc/hosts
本地物理机配置『hosts』
C:\Windows\System32\drivers\etc\hosts
IP地址 | 主机名 |
---|---|
192.168.240.151 | caroly01 |
192.168.240.152 | caroly02 |
192.168.240.153 | caroly03 |
192.168.240.154 | caroly04 |
poweroff
关机拍快照。
重新登陆虚拟机可以进行互通测试。
使用『MobaXterm』连接四台虚拟机,向四台虚拟机发送同步时间指令。
ntpdate 0.centos.pool.ntp.org
输入『date』可以查看系统当前时间。
注:点击菜单栏的『MultiExec』,可以同时向四台虚拟机发送相同指令
将『JDK』的『RPM』包上传到虚拟机,安装。
rpm -i jdk-7u67-linux-x64.rpm
配置环境变量,在最后新增两行8:
vi + /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
PATH=$PATH:$JAVA_HOME/bin
保存退出后重新执行该文件使之生效9。
. /etc/profile
检查一下是否可以在没有密码的情况下SSH到本虚拟机。
ssh localhost
如果需要输入密码才能SSH到本虚拟机,执行以下命令:
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
将『caroly01』的 .ssh/id_dsa.pub
分发给其他三台虚拟机10
scp id_dsa.pub caroly02:`pwd`/caroly02.pub scp id_dsa.pub caroly03:`pwd`/caroly03.pub scp id_dsa.pub caroly04:`pwd`/caroly04.pub
分发完毕后在被分发的虚拟机中追加此文件内容到 authorized_keys
文件
cat caroly02.pub >> authorized_keys cat caroly03.pub >> authorized_keys cat caroly04.pub >> authorized_keys
可以测试一下配置是否正确。
Hadoop配置
主机名 | NameNode | SecondaryNameNode | DataNode |
---|---|---|---|
caroly01 | √ | ||
caroly02 | √ | √ | |
caroly03 | √ | ||
caroly04 | √ |
- NameNode:是HDFS的管理节点,它存储了元数据(文件对应的数据块位置、文件大小、文件权限等)信息,同时负责读、写调度和存储分配。
- SecondaryNameNode:负责合并NameNode的edit logs到fsimage中。
- DataNode:该节点是真正的数据存储节点,用来存储数据。另外,在DataNode上的每个数据块会根据设置的副本数进行分级复制,保证同一个文件的每个数据块副本都不在同一个机器上。
解压『Hadoop』到目录 opt/caroly
tar xf hadoop-2.6.5.tar.gz -C /opt/caroly
配置环境变量,在最后新增两行:
vi + /etc/profile
export HADOOP_HOME=/opt/caroly/hadoop-2.6.5
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
修改以下可执行文件:cd /opt/caroly/hadoop-2.6.5/etc/hadoop
文件名 | 修改参数 |
---|---|
hadoop-env.sh | export JAVA_HOME=/usr/java/jdk1.7.0_67 |
mapred-env.sh | export JAVA_HOME=/usr/java/jdk1.7.0_67 |
yarn-env.sh | export JAVA_HOME=/usr/java/jdk1.7.0_67 |
修改以下配置文件:
vi /opt/caroly/hadoop-2.6.5/etc/hadoop/core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://caroly01:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/caroly/hadoop/full</value>
</property>
</configuration>
vi /opt/caroly/hadoop-2.6.5/etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>caroly02:50090</value>
</property>
</configuration>
vi /opt/caroly/hadoop-2.6.5/etc/hadoop/slaves
#localhost
caroly02
caroly03
caroly04
配置好后进入 opt
目录,将 caroly
目录分发11给其他三台虚拟机,并在其他三台虚拟机中配好『JDK』以及『Hadoop』的环境变量。
scp -r caroly/ caroly02:`pwd`
scp -r caroly/ caroly03:`pwd`
scp -r caroly/ caroly04:`pwd`
----------------------------------
scp /etc/profile caroly02:/etc/
scp /etc/profile caroly03:/etc/
scp /etc/profile caroly04:/etc/
在『caroly01』中进行格式化操作。
hdfs namenode -format
启动『Hadoop』。
start-dfs.sh
输入 jps
后,正常情况显示如下:
主机 | 进程名 |
---|---|
caroly01 | NameNode、Jps |
caroly02 | DataNode、SecondaryNameNode、Jps |
caroly03 | DataNode、Jps |
caroly04 | DataNode、Jps |
创建『Hadoop』的根目录 /user/root
12。
hdfs dfs -mkdir -p /user/root
在浏览器中输入 carolyo1:50070
可以看到相关信息。
Zookeeper配置
主机名 | NameNode-1 | NameNode-2 | DataNode | ZK | ZKFC | JN |
---|---|---|---|---|---|---|
caroly01 | √ | √ | √ | |||
caroly02 | √ | √ | √ | √ | √ | |
caroly03 | √ | √ | √ | |||
caroly04 | √ | √ |
- NameNode-1:主节点(active)。
- NameNode-2:备节点(standby)。
- DataNode:该节点是真正的数据存储节点,用来存储数据。另外,在DataNode上的每个数据块会根据设置的副本数进行分级复制,保证同一个文件的每个数据块副本都不在同一个机器上。
- ZK(ZooKeeper):ZooKeeper提供了一个Leader Election机制,利用这个机制你可以在集群中开启多个master并使它们都注册到ZooKeeper实例,ZooKeeper会管理使其中只有一个是Active的,其他的都是standby的。Active状态的master可以提供服务,standby状态的则不可以。ZooKeeper保存了集群的状态信息,该信息包括所有的Worker,Driver 和Application。当active的Master出现故障时,ZooKeeper会从其他standby的master中选举出一台,然后该新选举出来的master会恢复挂掉了的master的状态信息,之后该Master就可以正常提供调度服务。
- ZKFC(ZooKeeperFailoverController):是一个ZooKeeper客户端,监视和管理NameNode的状态。运行NameNode的每台机器也运行ZKFC,只有NameNode才有ZKFC进程,并且每个NameNode各一个。
- 健康检测:ZKFC会周期性的向它监控的NameNode发生健康探测命令,从而鉴定某个NameNode是否处于正常工作状态。如果机器宕机,心跳失败,那么ZKFC就会标记它处于不健康的状态。
- 会话管理:如果NameNode是健康的,ZKFC机会保持在Zookeeper中保持一个打开的会话,如果NameNode是active状态的,那么ZKFC还会在Zookeeper中占有一个类型为短暂类型的zNode,当这个NameNode挂掉时,这个zNode将会被删除。然后备用的NameNode得到这把锁,升级为主的NameNode,同时标记状态为active。当宕机的NameNode重新启动会再次注册Zookeeper,发现已经有zNode了,就自动变为standby状态。如此往复循环,保证高可靠性,但是目前仅支持最多配置两个NameNode。
- master选举:如上所述,通过在Zookeeper中维持一个短暂类型的zNode,来实现抢占式的锁机制,从而判断哪个NameNode为active状态。
- JN(JournalNode):NameNode之间共享数据,两个NameNode为了数据同步,会通过JournalNodes的独立进程进行相互通信。当active状态的NameNode的命名空间有任何修改时,会告知大部分的JournalNodes进程。standby状态的NameNode有能力读取JNs中的变更信息,并且一直监控edit log的变化,把变化应用于自己的命名空间。standby可以确保在集群出错时,命名空间状态已经完全同步了。
在『caroly01』中修改以下配置文件:
vi /opt/caroly/hadoop-2.6.5/etc/hadoop/core-site.xml
<configuration>
<!-- 指定在Hadoop中要使用的文件系统 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- Hadoop文件系统依赖的基础配置,很多路径都依赖它。默认路径在/tmp下,Linux重启后会删除,需更改位置。 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/var/caroly/hadoop/full</value>
</property>
<!-- 指定zookeeper地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>caroly02:2181,caroly03:2181,caroly04:2181</value>
</property>
</configuration>
vi /opt/caroly/hadoop-2.6.5/etc/hadoop/hdfs-site.xml
<configuration>
<!-- 默认块复制。创建文件时可以指定实际的复制数量。如果未在创建时指定复制,则使用默认值。 --> <property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 集群的逻辑名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 每个NameNode的唯一标识符,以下是两个 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1监听的RPC地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>caroly01:8020</value>
</property>
<!-- nn2监听的RPC地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>caroly02:8020</value>
</property>
<!-- nn1监听的HTTP地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>caroly01:50070</value>
</property>
<!-- nn2监听的HTTP地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>caroly02:50070</value>
</property>
<!-- 配置提供共享编辑存储的JournalNodes的地址,该地址由Active NameNode写入并由Standby NameNode读取,以与Active NameNode所做的所有文件系统更改保持最新。 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://caroly01:8485;caroly02:8485;caroly03:8485/mycluster</value>
</property>
<!-- 配置Java类的名称,DFS客户端将使用该Java类来确定哪个NameNode是当前的Active,从而确定哪个NameNode当前正在服务于客户端请求。 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 为了保证系统的正确性,在任何给定时间只有一个NameNode处于Active状态。重要的是,使用Quorum Journal Manager时,将只允许一个NameNode写入JournalNodes,因此不会因"脑裂"情况而损坏文件系统元数据。多个机制用换行分割。 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用sshfence隔离机制时需要ssh免登录 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_dsa</value>
</property>
<!-- 指定JournalNode在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/caroly/hadoop/ha/journalnode</value>
</property>
<!-- 启用故障转移机制 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
将修改的两个文件分发到其他三台虚拟机中13:
scp core-site.xml hdfs-site.xml caroly02:`pwd`
scp core-site.xml hdfs-site.xml caroly03:`pwd`
scp core-site.xml hdfs-site.xml caroly04:`pwd`
在『caroly02』『caroly03』『caroly04』中配置『ZooKeeper』。
tar xf zookeeper-3.4.6.tar.gz -C /opt/caroly/
cd /opt/caroly/zookeeper-3.4.6/
修改配置文件:
cd conf/
mv zoo_sample.cfg zoo.cfg
vi zoo.cfg
#修改以下内容
dataDir=/var/caroly/zookeeper
#新增以下内容
server.1=caroly02:2888:3888
server.2=caroly03:2888:3888
server.3=caroly04:2888:3888
配置好后将『zookeeper-3.4.6』目录14分发给『caroly03』『caroly04』。
scp -r zookeeper-3.4.6/ caroly03:`pwd`
scp -r zookeeper-3.4.6/ caroly04:`pwd`
在『caroly02』『caroly03』『caroly04』中创建目录:
mkdir -p /var/caroly/zookeeper
为『ZooKeeper』配置编号:
在『caroly02』中输入命令:
echo 1 > /var/caroly/zookeeper/myid
在『caroly03』中输入命令:
echo 2 > /var/caroly/zookeeper/myid
在『caroly04』中输入命令:
echo 3 > /var/caroly/zookeeper/myid
配置环境变量,在最后新增两行:
vi + /etc/profile
export ZOOKEEPER_HOME=/opt/caroly/zookeeper-3.4.6
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin
保存退出后将此文件分发给『caroly03』『caroly04』:
scp /etc/profile caroly03:/etc/
scp /etc/profile caroly04:/etc/
重新执行该文件使之生效。
. /etc/profile
启动『ZooKeeper』集群,在『caroly02』『caroly03』『caroly04』中输入以下命令:
zkServer.sh start
启动『JournalNode』,在『caroly01』『caroly02』『caroly03』中输入以下命令:
hadoop-daemon.sh start journalnode
格式化节点,『caroly01』和『caroly02』任选一个,在『caroly01』中输入以下命令:
hdfs namenode -format
启动格式化的主节点『caroly01』:
hadoop-daemon.sh start namenode
把主节点上的元数据信息拷贝到当前目录之下,在『caroly02』中输入以下命令:
hdfs namenode -bootstrapStandby
在『ZooKeeper』中初始化所需的状态,在『caroly01』中输入以下命令:
hdfs zkfc -formatZK
启动当前集群,在『caroly01』中输入以下命令:
start-dfs.sh
Hadoop MapReduce V2
ResourceManager(RM)负责跟踪集群中的资源,并调度应用程序(例如MapReduce作业)。
主机名 | NN-1 | NN-2 | DN | ZK | ZKFC | JN | RM | NM |
---|---|---|---|---|---|---|---|---|
caroly01 | √ | √ | √ | |||||
caroly02 | √ | √ | √ | √ | √ | √ | ||
caroly03 | √ | √ | √ | √ | √ | |||
caroly04 | √ | √ | √ | √ |
- RM(ResourceManager):当应用程序对集群资源需求时,RS是Yarn集群主控节点,负责协调和管理整个集群(所有NodeManager)的资源。
- NM(NodeManager):管理一个Yarn集群中的每一个节点。比如监视资源使用情况(CPU,内存,硬盘,网络),跟踪节点健康等。
- ApplicationMaster:用户向Yarn集群提交应用程序(包含ApplicationMaster程序,ApplicationMaster启动命令,用户自己的程序)时:ApplicationMaster向资源调度器申请执行任务的资源容器Container,运行用户自己的程序任务job(可以用浏览器看Yarn里的job进展),监控整个任务的执行,跟踪整个任务的状态,处理任务失败等异常情况。
- Container:资源分配的体现要用到一个抽象概念"容器"(Container)表示,Container将内存、CPU、磁盘、网络等资源封装在一起,这样可以起到限定资源边界的作用。比如给定一个Container的资源,里面包含3个G的内存,1G硬盘。当销毁Container时,连带的内存、硬盘都没有了。
在『caroly01』中修改以下配置文件:
cd /opt/caroly/hadoop-2.6.5/etc/hadoop
mv mapred-site.xml.template mapred-site.xml
vi mapred-site.xml
<configuration>
<!-- 配置Yarn框架执行map-reduce处理程序-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--日志监控服务的地址,一般填写为namenode机器地址,此处配置在caroly02上 -->
<property>
<name>mapreduce.jobhistroy.address</name>
<value>caroly02:10020</value>
</property>
</configuration>
vi yarn-site.xml
<configuration>
<!-- NodeManager上运行的附属服务。需配置成mapreduce_shuffle,才可运行MapReduce程序 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 开启高可用(RM HA)-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 集群标识,确保RM不会接管另一个集群(即不会成为其他集群的Active RM)-->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>
<!-- RM的逻辑ID,比如rm1,rm2-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 为每个rm-id声明一个对应的主机名,也可以声明RM的服务地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>caroly03</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>caroly04</value>
</property>
<!-- rm-zk的地址,同时用于状态存储和leader选举 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>caroly02:2181,caroly03:2181,caroly04:2181</value>
</property>
<!-- 启用日志聚合功能,日志聚合开启后保存到HDFS上 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
</configuration>
将这两个文件分发给『caroly02』『caroly03』『caroly04』:
scp mapred-site.xml yarn-site.xml caroly02:`pwd`
scp mapred-site.xml yarn-site.xml caroly03:`pwd`
scp mapred-site.xml yarn-site.xml caroly04:`pwd`
『caroly03』『caroly04』配置高可用切换,需要配置免密登陆:
# 在caroly03中执行以下命令
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat id_dsa.pub >> authorized_keys
scp id_dsa.pub caroly04:`pwd`/caroly03.pub
#测试配置是否成功
ssh caroly04
---------------------------------------------
# 在caroly04中执行以下命令
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat id_dsa.pub >> authorized_keys
scp id_dsa.pub caroly03:`pwd`/caroly04.pub
# 测试配置是否成功
ssh caroly03
启动集群:
# 在caroly02、caroly03、caroly04中输入启动zk的命令
zkServer.sh start
# 在caroly01中启动hdfs
start-dfs.sh
# 在caroly01中启动yarn
start-yarn.sh
# 在caroly03、caroly04中启动RM
yarn-daemon.sh start resourcemanager
# 在caroly03、caroly04中启动historyserver
mr-jobhistory-daemon.sh start historyserver
通过浏览器访问RM:
caroly03:8088
或
caroly04:8088
其中,『Active Nodes』的值为 3 表示搭建成功(从节点为3个)。
单词统计,在『caroly01』中执行:
cd /opt/caroly/hadoop-2.6.5/share/hadoop/mapreduce
# 此目录下有一个mapreduce的例子包,封装有一些写好的job任务
# 此处用到这个包的wordcount程序
hadoop jar hadoop-mapreduce-examples-2.6.5.jar wordcount /user/root/test.txt /wordcount
# 执行这个jar包下的wordcount程序,计算第一个路径下的test.txt文件,输出目录为第二个路径下的wordcount目录。
# /wordcount目录可以不存在,若是存在必须是空目录。
# 查看结果
hdfs dfs -cat /wordcount/part-r-00000
关闭集群:
# 在caroly03、caroly04中关闭RM
yarn-daemon.sh stop resourcemanager
# 在caroly03、caroly04中启动historyserver
mr-jobhistory-daemon.sh stop historyserver
# 在caroly01中关闭集群
stop-all.sh
# 在caroly02、caroly03、caroly04中关闭zk
zkServer.sh stop
Footnotes
-
仅在实验环境注释,这台虚拟机将会用来克隆其他四台虚拟机。如果没有注释掉,『VMWare』会将新克隆的虚拟机的网卡地址(硬件地址)换成与这台虚拟机不一样的,为保证全局唯一,需要注释掉。 ↩
-
第四组的数不要为0、1、2,除此之外小于255并且该局域网中没有其他相同IP,都可。 ↩
-
此处可不写。 ↩
-
此处关闭防火墙,再次重启虚拟机依旧会开启,若想永久关闭,需禁用。 ↩
-
会阻断使用某些功能模块,所以暂且禁用。 ↩
-
与上方『1』标注一样,仅在实验环境中删除。 ↩
-
此处在一台虚拟机中配置好,再通过『scp』命令分发到其他虚拟机,省事。 ↩
-
『+』是定位到该文件的最后一行,放在文件前面后者后面都可以。按『o』(小写)即可在该行下面插入。 ↩
-
『.』可以替换成『source』。 ↩
-
『pwd』是输出分发文件方的当前目录. ↩
-
目录分发需要加参数『-r』 ↩
-
默认的上传路径就是它。 ↩
-
pwd的当前目录是/opt/caroly/hadoop-2.6.5/etc/hadoop/ ↩
-
当前目录是/opt/caroly/ ↩