一、前言
过完年在外实习,实习中的一部分主要工作就是关于hadoop的搭建和维护。其实hadoop的搭建本身并不是什么难题,主要是当一些之前没怎么用过linux、没怎么用到java的可怜的孩纸们来搞hadoop的时候会相当的揪心,非常不巧我也是的。因此可以说,学hadoop的过程是一个很痛苦但是也很有成就感的过程。
先说一下我学习hadoop的过程,由于之前没有用过linux,java也就一知半解基本没用过,因此在学hadoop的前,我补了一段时间的基础知识,主要针对linux。hadoop的环境主要在linux上,在学hadoop之前最好具备一定的linux基础知识,大体上有这么一些(当然不止这么多,只能说如果这些都不具备,会相当痛苦的):基本的本件操作指令(mkdir、rm、scp、mv这一类),还有关于环境变量的配置、网络设置、权限、安装软件等等,不是很多,但是学起来也不少。由于hadoop是用java编写,因此最好自己写过一些java程序,不然在hadoop运行或者搭建的过程中报的java错误可能就会让你很迷惑。
啰嗦一点,顺便说一下自己学hadoop时的心情吧。最初学hadoop感觉相当的新奇,认为自己学了hadoop出来工作基本不愁,充满了自信。随着学习的深入,发现hadoop的水还是比较深的,这时候我就开始反思自己对hadoop的认识了,我不能确定hadoop就是一个非常适合自己的工作,或者说我是在接触更多知识后对自己的一种怀疑,因为很多大公司貌似已经不用hadoop了,而且有出现了很多的框架storm、spark等,这个时期我比较迷茫,而且在学习的时候也遇到了很多的困难,发现hadoop的运维也是相当的难熬的。现在的话,对待hadoop和之前又不相同了,我不知道对错,但是现在对hadoop的理解是一个工具,我没有太多的想法想钻研hadoop,仅仅作为一个工具使用,类似于mysql,Python这些工具和语言,知识适用于不同的环境而已。学hadoop最美好的回忆是在学习的时候我难以自拔地喜欢了一个女生,那段时间是我动力最大的时期,也是我最卖命度过hadoop最痛苦的一段时期。
二、集群搭建
我所搭建的hadoop平台是在十多台的服务器上,操作系统为scientific linux,按以下的操作步骤可以完成搭建,其中很多配置项是在运行程序出问题后经过调整后最终配置内容。
1.注意
1.所有使用root权限的操作必须慎重,hadoop所有的配置过程中必须谨慎!
2.所有软件的安装位置:Jdk在/usr/java/jdk1.8.0下;Hadoop在/home/hadoop/hadoop2.2.0下;Zookeeper3.4.5在/home/hadoop/hadoop-2.2.0/zookeeper-3.4.5下;hbase-0.98在/home/hadoop/hadoop-2.2.0/hbase-0.98下
3.Hadoop2.2官方提供32位,自己提供的64位版本。可以自己编译,可以下载。
2.准备工作
1.防火墙(所有机器)(root用户) /etc/init.d/iptables stop //关闭防火墙 chkconfig iptables off //关闭开机启动 2.时间(所有机器)(root用户) date -s "2014-5-13 09:56:33"//设置日期 3.用户(所有机器)(root用户) useradd hadoop //创建hadoop用户 passwd hadoop //密码 vim /etc/sudoers <span style="font-family: Arial, Helvetica, sans-serif;"> //加入sudoers:vim /etc/sudoers ,在root下一行写入 </span><span style="font-family: Arial, Helvetica, sans-serif;">hadoop ALL=(ALL) ALL</span>
4.主机名(所有机器)(root用户) hostname 192.168.80.19 //暂时修改主机名 vim /etc/sysconfig/network //永久修改 5.hosts文件(所有机器)(root用户) vim /etc/hosts //在hosts文件中写入整个集群的主机信息: 192.168.60.98 bigdata07.ihep.ac.cn bigdata07 192.168.60.97 bigdata06.ihep.ac.cn bigdata06
3.JDK1.8安装(所有机器)(root用户)
- 1.查看java状况:rpm -qa |grep java
- 2.查看jdk状况:rpm -qa |grep jdk
- 3.卸载上两步显示的程序:rpm -e --nodeps java-###
- 4.安装jdk:将jdk-8-linux-x64.rpm放入任意目录,执行rpm -ivh jdk-8-linux-x64.rpm
- 5.修改环境变量:vim /etc/profile,加入如下几行:
- export JAVA_HOME=/usr/java/jdk1.8.0
- export JRE_HOME=/usr/java/jdk1.8.0/jre
- export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
- export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
- 6.生效:source /etc/profile
- 7.验证:java –version、echo $JAVA_HOME
4.SSH无密码登录(所有机器)(root用户+hadoop用户)
- 1.修改配置文件:vim /etc/ssh/sshd_config,将以下三行去掉注释
- RSAAuthentication yes
- PubkeyAuthentication yes
- AuthorizedKeysFile .ssh/authorized_keys
- 2.重启ssh:service sshd restart
- 以下步骤全部在hadoop用户下操作,首先需要保证所有主机能够ping通
- 3.生成密钥:ssh-keygen –t dsa(然后一直按回车,会自动生成.ssh文件夹,内有两个文件)
- 4.生成authorized_keys:cat id_dsa.pub >> authorized_keys
- 5.赋权限:chmod 600 authorized_keys
- 6.生成公有的密钥,包括所有主机的信息:
- 6.1.将第一台主机的authorized_keys发送至第二台主机,替换掉之前的authorized_keys:
- scp authorized_keys hadoop@192.168.60.92:/home/hadoop/.ssh
- 6.2.将第二台主机的id_dsa.pub追加入authorized_keys(追加后的应有两台主机的信息)
- cat id_dsa.pub >> authorized_keys
- 6.3.重复前两步,直到把所有主机的id_dsa.pub追加入authorized_keys
- 6.4.将最后一个authorized_keys分发回给所有主机:
- scp authorized_keys hadoop@192.168.60.92:/home/hadoop/.ssh
- 7.验证登陆:ssh ip地址或者主机名
5.Zookeeper3.4.5搭建(部分主机)(hadoop用户)
- 1.注意事项:
- 1.1.Zookeeper分布的主机数必须是奇数,不用使用全部主机,挑选出部分即可
- 1.2.配置文件分发给所有主机后必须记得修改myid
- 2.配置文件:
- 2.1.zoo.cfg:
- dataDir=/home/hadoop/hadoop-2.2.0/zookeeper-3.4.5/data ##Zookeeper存放数据
- dataLogDir=/home/hadoop/hadoop-2.2.0/zookeeper-3.4.5/logs ##存放log日志
- server.1=192.168.60.92:2888:3888 ##所有安装Zookeeper的主机。server.ID,ID写入每台主机的/data/myid中
- server.2=192.168.60.93:2888:3888
- server.3=192.168.60.94:2888:3888
- 3.创建/data和/logs两个文件夹
6.hadoop2.2 HA(所有主机)(hadoop用户)
- 1.注意:
- 1.1.hadoop2.2 HA设置两个namenode,一个active,一个standby
- 2.配置文件(顺序从上往下)
- 2.1.core-site.xml文件
- <configuration>
- <property>
- <name>fs.defaultFS</name>
- <value>hdfs://cluster</value>
- <description>对应hdfs中的集群名称</description>
- </property>
- <property>
- <name>hadoop.tmp.dir</name>
- <value>/home/hadoop/hadoop-2.2.0/tmp</value>
- <description>自己设置tmp,默认位置会被定期清除</description>
- </property>
- <property>
- <name>ha.zookeeper.quorum</name>
- <value>192.168.60.92:2181,192.168.60.93:2181,192.168.60.94:2181,</value>
- </property>
- <description>这里是ZooKeeper集群的地址和端口。注意,数量一定是奇数,且不少于三个节点</description>
- </configuration>
- 2.2.hadoop-env.sh文件 //一般的教程中不设置这个文件,但是设置这些文件能让你更能理解hadoop一些原理
- export JAVA_HOME=/usr/java/jdk1.8.0
- export HADOOP_PID_DIR=/home/hadoop/hadoop-2.2.0/tmp
- export HADOOP_SECURE_DN_PID_DIR=/home/hadoop/hadoop-2.2.0/tmp
- 2.3.hdfs-site.xml文件
- <configuration>
- <property>
- <name>dfs.name.dir</name>
- <value>/hadoopnamenode/name</value>
- </property>
- <property>
- <name>dfs.data.dir</name>
- <value>/data/hadoop/data</value>
- </property>
- <property>
- <name>dfs.replication</name>
- <value>3</value>
- <description>dfs备份数量</description>
- </property>
- <property>
- <name>dfs.permissions.enabled</name>
- <value>false</value>
- <description>默认为true,但是还不知道具体功能,设为false</description>
- </property>
- <property>
- <name>dfs.nameservices</name>
- <value>cluster</value>
- <description>集群的逻辑名称,自己任意取</description>
- </property>
- <property>
- <name>dfs.ha.namenodes.cluster</name>
- <value>nn1,nn2</value>
- <description>两个namenode的逻辑名称,自己任意取</description>
- </property>
- <property>
- <name>dfs.namenode.rpc-address.cluster.nn1</name>
- <value>192.168.60.98:9000</value>
- </property>
- <property>
- <name>dfs.namenode.http-address.cluster.nn1</name>
- <value>192.168.60.98:50070</value>
- </property>
- <property>
- <name>dfs.namenode.rpc-address.cluster.nn2</name>
- <value>192.168.60.126:9000</value>
- </property>
- <property>
- <name>dfs.namenode.http-address.cluster.nn2</name>
- <value>192.168.60.126:50070</value>
- </property>
- <property>
- <name>dfs.namenode.servicerpc-address.cluster.nn1</name>
- <value>192.168.60.98:53310</value>
- </property>
- <property>
- <name>dfs.namenode.servicerpc-address.cluster.nn2</name>
- <value>192.168.60.126:53310</value>
- </property>
- <property>
- <name>dfs.ha.automatic-failover.enabled.cluster</name>
- <value>true</value>
- <description>指定cluster是否自动故障恢复,当NameNode出故障时,是否自动切换到另一台NameNode</description>
- </property>
- <!--指定JournalNode -->
- <property>
- <name>dfs.namenode.shared.edits.dir</name>
- <value>qjournal://192.168.60.92:8485;192.168.60.93:8485;192.168.60.94:8485;192.168.60.95:8485;192.168.60.96:8485;192.168.60.97:8485;192.168.60.98:8485;192.168.60.125:8485;192.168.60.126:8485;192.168.60.127:8485;192.168.60.128:8485/cluster</value>
- <description>指定cluster的两个NameNode共享edits文件目录时,使用的JournalNode集群信息</description>
- </property>
- <property>
- <name>dfs.client.failover.proxy.provider.cluster</name>
- <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
- <description>指定cluster1出故障时,哪个实现类负责执行故障切换</description>
- </property>
- <property>
- <name>dfs.journalnode.edits.dir</name>
- <value>/home/hadoop/hadoop-2.2.0/journal</value>
- </property>
- <property>
- <name>dfs.ha.fencing.methods</name>
- <value>sshfence</value>
- </property>
- <property>
- <name>dfs.ha.fencing.ssh.private-key-files</name>
- <value>/home/hadoop/.ssh/id_rsa</value>
- </property>
- <property>
- <name>dfs.ha.fencing.ssh.connect-timeout</name>
- <value>5000</value>
- </property>
- <property>
- <name>dfs.namenode.handler.count</name>
- <value>100</value>
- </property>
- </configuration>
- 2.4.mapred-env.sh文件
- export JAVA_HOME=/usr/java/jdk1.8.0
- export HADOOP_MAPRED_PID_DIR=/home/hadoop/hadoop-2.2.0/tmp
- 2.5.mapred-site.xml文件
- <configuration>
- <property>
- <name>mapreduce.framework.name</name>
- <value>yarn</value>
- </property>
- <property>
- <name>mapreduce.job.maps</name>
- <value>6</value>
- <description>每个job使用的map tasks个数</description>
- </property>
- <property>
- <name>mapreduce.job.reduces</name>
- <value>6</value>
- <description>每个job使用的reduce tasks个数</description>
- </property>
- <property>
- <name>mapreduce.tasktracker.map.tasks.maximum</name>
- <value>6</value>
- <description>一个task tracker能够同时运行的最多map task个数</description>
- </property>
- <property>
- <name>mapreduce.tasktracker.reduce.tasks.maximum</name>
- <value>6</value>
- <description>一个task tracker能够同时运行的最多reduce task个数</description>
- </property>
- <property>
- <name>mapred.child.java.opts</name>
- <value>-Xmx5000m</value>
- <descriptio>每个TT子进程所使用的虚拟机内存大小</descriptio>
- </property>
- <property>
- <name>mapreduce.tasktracker.http.threads</name>
- <value>40</value>
- <description>TT用来跟踪task任务的http server的线程数</description>
- </property>
- </configuration>
- 2.6.slaves文件
- 写入datanode的ip地址或者主机名即可
- 2.7.yarn-env.sh文件
- export JAVA_HOME=/usr/java/jdk1.8.0
- 2.8.yarn-site.xml文件
- <configuration>
- <property>
- <name>yarn.resourcemanager.hostname</name>
- <value>192.168.60.98</value>
- <description>resourcemanager只有一个,设置它的主机位置</description>
- </property>
- <property>
- <name>yarn.nodemanager.aux-services</name>
- <value>mapreduce_shuffle</value>
- </property>
- <property>
- <description>The class to use as the resource scheduler.</description>
- <name>yarn.resourcemanager.scheduler.class</name>
- <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
- <description>设置hadoop集群能够并行运行多个程序</description>
- </property>
- </configuration>
7.Hbase0.98(部分主机)(hadoop用户)
- 1.注意,Hbase常遇到的几种错误的解决方法:
- 1.1.确保几台主机日期相差不多
- 1.2.替换lib中的jar包
- hadoop-annotations-2.2.0.jar
- hadoop-auth-2.2.0.jar
- hadoop-common-2.2.0.jar
- hadoop-hdfs-2.2.0.jar
- hadoop-mapreduce-client-app-2.2.0.jar
- hadoop-mapreduce-client-common-2.2.0.jar
- hadoop-mapreduce-client-core-2.2.0.jar
- hadoop-mapreduce-client-jobclient-2.2.0.jar
- hadoop-mapreduce-client-shuffle-2.2.0.jar
- hadoop-yarn-api-2.2.0.jar
- hadoop-yarn-client-2.2.0.jar
- hadoop-yarn-common-2.2.0.jar
- hadoop-yarn-server-common-2.2.0.jar
- hadoop-yarn-server-nodemanager-2.2.0.jar
- 1.3.复制hadoop配置文件hdfs-site.xml到conf中
- 1.4.删除slf4j-log4j12-1.6.4.jar包
- rm -rf /home/hadoop/hadoop-2.2.0/hbase-0.98.0-hadoop2/lib/slf4j-log4j12-1.6.4.jar
- 1.5.如果hbase第一次启动失败,以后重新启动前,删除Zookeeper中的hbase目录
- zkCli.sh
- rmr hbase
- 2.配置文件
- 2.1.hbase-env.sh文件
- export JAVA_HOME=/usr/java/jdk1.8.0/
- export HBASE_MANAGES_ZK=false ##表示不使用自己的Zookeeper集群
- export HBASE_PID_DIR=/home/hadoop/hadoop-2.2.0/hbase-0.98/tmp
- 2.2.hbase-site.xml文件
- <configuration>
- <property>
- <name>hbase.rootdir</name>
- <value>hdfs://cluster/hbase</value>
- </property>
- <property>
- <name>hbase.cluster.distributed</name>
- <value>true</value>
- </property>
- <property>
- <name>hbase.zookeeper.quorum</name>
- <value>192.168.60.92:2181,192.168.60.93:2181,192.168.60.94:2181</value>
- </property>
- <property>
- <name>zookeeper.session.timeout</name>
- <value>60000</value>
- </property>
- <property>
- <name>hbase.zookeeper.property.clientPort</name>
- <value>2181</value>
- </property>
- <property>
- <name>hbase.tmp.dir</name>
- <value>/home/hadoop/hadoop-2.2.0/hbase-0.98/tmp</value>
- </property>
- <property>
- <name>hbase.master.maxclockskew</name>
- <value>200000</value>
- <description>Time difference of regionserver from master</description>
- </property>
- </configuration>
- 2.3.regionservers文件
- 写入相应的hbase主机,都是HRegionServer,HMaster是启动Hbase的那个节点。
三、启动集群
- 1.分发文件:
- 将一台机器上的hadoop目录发给其余所有主机:
- scp -r /home/hadoop/hadoop-2.2.0 hadoop@192.168.60.92:/home/hadoop/
- 2.启动Zookeeper集群
- 2.1.修改myid
- 2.2.启动Zookeeper集群(每台Zookeeper机器)
- zkServer.sh start
- 2.3.查看状态:
- zkServer.sh status
- 2.4.验证:
- 主节点:zkCli.sh
- ls /
- 2.5.格式化集群
- 在主节点:/home/hadoop/hadoop-2.2.0/bin/hdfs zkfc –formatZK
- 2.6.验证
- ls / ##是否出现了hadoop-ha
- 3.启动hadoop集群
- 3.1.启动journalnode(所有机器)
- 每台主机分别执行:hadoop-daemon.sh start journalnode
- 3.2.启动namenode(namennode)
- 3.2.1.格式化namenode
- 第一个namenode上执行:hdfs namenode -format
- 3.2.2.启动第一个namenode
- hadoop-daemon.sh start namenode
- 3.3.3.同步namenode数据:
- 第二个namenode上执行:hdfs namenode –bootstrapStandby
- 3.3.4.启动第二个namenode
- 在第二台namenode上:hadoop-daemon.sh start namenode
- 3.3.启动datanode(所有datanode)
- hadoop-daemons.sh start datanode
- 3.4.启动yarn
- 3.4.1.启动yarn(active namenode)
- start-yarn.sh
- 3.4.2.启动ZooKeeperFailoverController(两个namenode)
- hadoop-daemon.sh start zkfc
- 4.启动hbase(active namenode)
- start-hbase.sh
四、总结
这是一篇工作总结文档,不是教程,因为我没有实力和资格去写那些,我也仅仅是一个初学者。因此在写的时候我没有截图和加太多的说明,但是基本每步都会有注释和注意事项,这些全部是为我自己写的,等于是对自己工作的一个总结,同时告诉自己曾经学过这些东西。
这篇文章里面难免会有很多的遗漏和不足,比如说我没有写某个步骤运行出来什么结果才算正确,而且可能一些配置项根据不同的集群也需要更改,而且很多配置我也没有设置,但是作为一个基本的hadoop集群,上面的操作步骤是可以成功实现了,这些基本上是很长一段时间的工作成功,算是一个菜鸟的学习经历吧。