手把手搭建大数据集群2:Hadoop集群搭建

在上一节里,我们使用VMware搭建了三台Linux服务器,并做时间同步。

在此基础上,我们将要搭建一套Hadoop集群。

 

那么这节的目标就很明确了:搭建一套Hadoop集群。

 

好吧,我们应该把目标说得详细一点:

集群包含3个设备,cube01,cube02,cube03,

其中namenode处于cube01,secondNamenode位于cube02;cube01,cube02,cube03各包含一个datanode。

yarn的SourceManager也处于cube01。(这个服务比较吃内存,实际运用中,如果主机对等的话,最好和namenode分开)

 

内容:1、创建hadoop用户和一些工作目录;2、JDK安装配置;3、hadoop安装配置;4、hadoop启动停止;5、验证hadoop集群,访问web界面。

 

那么 让我们愉快地开始吧:

 

1、创建hadoop用户:

为了方便管理,同时也出于安全考虑,我们专门创建一个hadoop用户,使用该用户来安装所有大数据组件。

创建用户并设置密码,实验环境建议把密码设置得简单一些:

useradd hadoop
passwd hadoop

给hadoop用户添加sudo权限:

visudo
#在打开的文件里添加如下信息:
hadoop  ALL=(ALL)       ALL

创建完hadoop用户后,以后的操作就都由hadoop完成了,至此我们宣布root光荣下岗。(鼓掌)

同样地,我们为3台机器的hadoop配置SSH免密登陆:

切换到hadoop用户:

su hadoop

生成密钥、公钥:

ssh-keygen -t rsa P ""

把公钥发送到远程主机(3台互相发):

ssh-copy-id cube01
ssh-copy-id cube02
ssh-copy-id cube03

 

接着我们创建几个常用工作目录:

先整理一下我们的需求:

1、我们需要1个目录来安装各种大数据组件;

2、需要一个目录来存放各种组件的安装包;

3、需要创建一个统一的目录来存放一些我们编写的自动化脚本;

4、需要一个目录来存放我们进行相关测试的数据文件;

 

暂时想到这些吧,再想可能要掉头发了,还是赶紧行动起来吧:

工作目录:

mkdir -p /cube/install

安装包目录:

这里需要说明一下,因为安装包都是重复的,放三份其实挺浪费的,特别块头都挺大,所以建议放在物理主机上,映射一个共享目录就好:

首先我们需要先在物理机上创建这个目录,然后关闭虚拟机,

接着我们打开虚拟机设置(快捷键CTRL+D),如图,开启共享文件夹 =》 添加目录 =》 确定。

 

那么挂载的目录在哪里呢?路径是/mnt/hgfs/shared,shared对应的是物理机上的目录名。

为了方便操作、统一管理,我们创建一个软连接到/cube

ln -s /mnt/hgfs/shared /cube/shared

棒啊!似乎有一丝美妙的感觉了。(滑稽)

接着创建脚本目录和数据目录:

mkdir /cube/bin /cube/data

就是这么朴实无华。

 

2、安装JDK。

因为目前主流的大数据架构整体都是基于Java来开发的,所以我们需要安装JDK。

首先下载JKD安装包(Linux x64版本),放到物理机共享目录:

https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html

(不要问我为什么是JDK8,问你们领导(捂脸))

解压安装包:

tar -zxf /cube/shared/jdk-8u202-linux-x64.tar.gz -C /cube/install/

 添加环境变量:

vi /etc/profile

添加如下信息:

export JAVA_HOME=/cube/install/jdk1.8.0_202
export CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar
export PATH=${JAVA_HOME}/bin:$PATH

验证配置信息:

#使配置立即生效
source /etc/profile (或者断开(CTRL+D)重连(CTRL+SHIFT+R)更佳)
echo $JAVA_HOME
java -version

 

 3、安装hadoop

忙活了大半天,咱们终于进入正题了。

安装包可以从Apache网站上获取到,这个网站大家可以保留一下,各个版本的Apache软件都可以快速地在这里找到。

http://archive.apache.org/dist/hadoop/common/hadoop-3.1.4/

同样地把下载的hadoop-3.1.4.tar.gz文件放在物理机共享目录。

安装和配置工作只需要在cube01操作,完成后scp到其余两台机器即可,以后安装其他组件同。

解压安装包:

tar -zxf /cube/shared/hadoop-3.1.4.tar.gz -C /cube/install/

解压之后来熟悉一下目录:

bin是客户端脚本;sbin是服务端脚本;

share是文档和hadoop各个组件编译后的jar包;lib是运行时需要的类库,运行时会被加入到classpath中;

libexec是一些参数配置的脚本:日志输出、启动参数、JVM参数等;

include是一些对外部程序(C++)提供的头文件,实际的库文件在lib中;

etc是hadoop的配置文件目录,也是我们今天关注的重点。

 

 让我们来瞅一瞅,里面都有啥吧:

 

OLD My GOD(我的老天),看起来似乎好像过于丰盛了。。。。

不过没有关系,豆芽长三米高,它也是一根菜,详细的内容有待大家进一步探索,

今天我们只需要关心以下几个文件即可:

1、hadoop-env.sh:hadoop的环境变量信息,如JAVA_HOME;

2、workers:指定集群有多少个worker(存储和计算节点);

3、core-site.xml:hadoop的司令员namenode的配置;

4、hdfs-site.xml:hdfs的配置;

5、mapred-site.xml:mapreduce的运行配置;

6、yarn-site.xml:yarn(hadoop资源管理器)的配置;

 介绍完毕,让我们再一次愉快地出发吧:

①hadoop-env.sh

添加如下语句即可:

export JAVA_HOME=/cube/install/jdk1.8.0_202

 ②workers

这个更简单,把三台主机名加上即可。(注意要先配置hosts文件,参见上一节)

cube01
cube02
cube03

③core-site.xml

英文注释是官方说明

<configuration>
    <!-- NameNode URI -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://cube01:8020</value>
    </property>
    
    <!-- 这是NameNode的临时目录,*-default.xml里有很多依赖它的配置,默认在/tmp/${USER},这样如果意外断电或者手动重启会导致很严重的问题 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/cube/install/hadoop-3.1.4/hadoopDatas/tmp</value>
    </property>

    <!-- Size of read/write buffer used in SequenceFiles 缓冲区大小,默认值4096 -->
    <property>
        <name>io.file.buffer.size</name>
        <value>4096</value>
    </property>

    <!-- 开启hdfs回收站,单位分钟,默认值0 -->
    <property>
        <name>fs.trash.interval</name>
        <value>10080</value>
    </property>

</configuration>

 ④hdfs-site.xml

</configuration>
    <!-- nn web 端访问地址-->
    <property>
        <name>dfs.namenode.http-address</name>
        <value>cube01:9870</value>
    </property>
    <!-- snn web 端访问地址-->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>cube02:9868</value>
    </property>
    <!-- namenode保存fsimage的路径 -->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///cube/install/hadoop-3.1.4/hadoopDatas/dfs/name</value>
    </property>
    <!-- namenode保存editslog的目录 -->
    <property>
        <name>dfs.namenode.edits.dir</name>
        <value>file:///cube/install/hadoop-3.1.4/hadoopDatas/dfs/name/edits</value>
    </property>
    <!-- secondarynamenode保存待合并的fsimage -->
    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>file:///cube/install/hadoop-3.1.4/hadoopDatas/dfs/sname</value>
    </property>
    <!-- secondarynamenode保存待合并的editslog -->
    <property>
        <name>dfs.namenode.checkpoint.edits.dir</name>
        <value>file:///cube/install/hadoop-3.1.4/hadoopDatas/dfs/sname/edits</value>
    </property>
    <!-- 定义dataNode数据存储的节点位置,实际工作中,一般先确定磁盘的挂载目录,然后多个目录用,进行分割  -->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///cube/install/hadoop-3.1.4/hadoopDatas/dfs/data</value>
    </property>
    <!-- 文件副本数量,集群是3台机器,如果是20台呢?推荐还是3 -->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- If "true", enable permission checking in HDFS. If "false", permission checking is turned off -->
    <!-- 注意:false才是关闭权限检查,这会导致普通用户具备超级用户的读写权限,生产环境应设为true -->
    <property>
       <name>dfs.permissions.enabled</name>
       <value>false</value>
    </property>
    <!-- 块大小,根据磁盘每秒写入速度而定,这里是128M -->
        <property>
        <name>dfs.blocksize</name>
        <value>134217728</value>
    </property>
    
</configuration>

⑤mapred-site.xml

<configuration>
    <!-- 指定 MapReduce 程序运行在 Yarn 上 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <!-- 开启小任务模式,如果用Job足够小,则串行在的一个JVM完成该JOB,即MRAppMaster进程中,这样比为每一个任务>分配Container性能更好。-->
    <!-- Whether to enable the small-jobs "ubertask" optimization, which runs "sufficiently small" jobs sequentially within a single JVM. -->
    <property>
        <name>mapreduce.job.ubertask.enable</name>
        <value>true</value>
    </property>
    <!-- 历史服务器端地址 -->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>cube01:10020</value>
    </property>
    <!-- 历史服务器端Web地址 -->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>cube01:19888</value>
    </property>
    <!-- 下面三个变量针对运行时的错误:Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaste -->
    <!-- User added environment variables for the MR App Master processes -->
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>
    <property>
        <name>mapreduce.map.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>
    <property>
        <name>mapreduce.reduce.env</name>
        <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
    </property>
</configuration>

⑥yarn-site.xml,这个配置有点多,做实验嫌麻烦的话,只配前3项也可以。

<configuration>
    <!-- The hostname of the RM -->
    <property>
       <name>yarn.resourcemanager.hostname</name>
        <value>cube01</value>
    </property>
    <!-- The http address of the RM web application -->
    <property>
       <name>yarn.resourcemanager.webapp.address</name>
        <value>${yarn.resourcemanager.hostname}:8088</value>
    </property>
    <!-- NodeManager上运行的附属服务。需添加mapreduce_shuffle,才可运行MapReduce程序 -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
   <!-- nodemanager本地文件存储目录 -->
    <property>
        <name>yarn.nodemanager.local-dirs</name>
        <value>/cube/install/hadoop-3.1.4/hadoopDatas/yarn/local</value>
    </property>
    <!-- resourceManager保存完成任务的最大个数 -->
    <property>
        <name>yarn.resourcemanager.max-completed-applications</name>
        <value>1000</value>
    </property>
    
    <!-- 开启日志聚合功能,将application运行时,每个container的日志聚合到一起,保存到文件系统,一般是HDFS -->
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <!-- 多长时间删除一次聚合产生的日志,这里是30天 -->
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>2592000</value>
    </property>
    <!-- 指向日志聚合服务器的URL,Yarn管理界面上任务后有个logs链接,指定才能跳转 -->
    <property>
        <name>yarn.log.server.url</name>
        <value>http://master:19888/jobhistory/logs</value>
    </property>
    <!-- 日志聚合WEB服务器的URL -->
    <!--property>
        <name>yarn.log.server.web-service.url</name>
        <value>http://master:8188/ws/v1/applicationhistory</value>
    </property-->
    <!-- 指定聚合产生的日志的压缩算法 -->
    <property>
        <name>yarn.nodemanager.log-aggregation.compression-type</name>
        <value>gz</value>
    </property>
    <!-- 保留用户日志多少秒。只有日志聚合功能yarn.log-aggregation-enable没有开启时才有效;现已开启 
    <property>
        <name>yarn.nodemanager.log.retain-seconds</name>
        <value>604800</value>
    </property>
   -->
 
    <!-- 指定我们的任务调度使用fairScheduler调度器,可用的有FIFO、CapacityScheduler和FairScheduler -->
    <property>
        <name>yarn.resourcemanager.scheduler.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
    </property>

    <!-- 指定我们的任务调度的配置文件路径 -->
    <property>
        <name>yarn.scheduler.fair.allocation.file</name>
        <value>/cube/install/hadoop-3.1.4/etc/hadoop/fair-scheduler.xml</value>
    </property>

    <!-- 是否启用资源抢占,如果启用,那么当该队列资源使用
     yarn.scheduler.fair.preemption.cluster-utilization-threshold 这么多比例的时候,就从其他空闲队列抢占资源
 -->
    <property>
        <name>yarn.scheduler.fair.preemption</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.scheduler.fair.preemption.cluster-utilization-threshold</name>
        <value>0.8f</value>
    </property>
    <!-- 设置为true,且没有指定队列名,提交应用到用户名同名的队列;如果设置为false或没设置,默认提交到default>队列;如果在allocation文件中指定了队列提交策略,忽略此属性 -->
    <property>
        <name>yarn.scheduler.fair.user-as-default-queue</name>
        <value>true</value>
        <description>default is True</description>
    </property>

    <!-- 是否允许创建未定义的资源池。如果设置成true,yarn将会自动创建任务中指定的未定义过的资源池。设置成false之后,任务中指定的未定义的资源池将无效,该任务会被分配到default资源池中。如果在allocation文件中指定了队列提交>策略,忽略此属性 -->
    <property>
        <name>yarn.scheduler.fair.allow-undeclared-pools</name>
        <value>false</value>
        <description>default is True</description>
    </property>

    <!-- 取消物理内存检查 -->
    <property>
        <name>yarn.nodemanager.pmem-check-enabled</name>
        <value>false</value>
    </property>
    <!-- 取消虚拟内存检查 -->
    <property>
        <name>yarn.nodemanager.vmem-check-enabled</name>
        <value>false</value>
    </property>
    <!-- 每使用1M内存最多可以使用多少虚拟内存 -->
    <property>
        <name>yarn.nodemanager.vmem-pmem-ratio</name>
        <value>4</value>
        <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
    </property>

</configuration>

 

4、实例化和启动hadoop

①首先,初始化namenode,使用如下命令:

hdfs namenode -format

或者

hadoop namenode -format

看关键字successfully,name和edits都被初始化,就表示成功了。

 

②启动集群

1、hdfs

start-dfs.sh

2、启动yarn

start-yarn.sh

3、启动历史服务器

mapred --daemon start historyserver

或 

mr-jobhistory-daemon.sh start historyserver

(如果namenode和resourcemanager不在一台机器,则需要分别于所在服务器运行start-dfs.sh和start-yarn.sh启动)

 

③检查结果

运行jps查看进程,三台机器分别存在以下进程说明运行成功。

第一台:

第二台:

 

第三台:

 

同时可以在/cube/install/hadoop-3.1.4/hadoopDatas目录查看生成的目录是否和配置文件相一致。

我们也可以到yarn的管理界面 http://cube01:8088 和hdfs的管理页 http://cube01:9870去看看。

 

 ④第一个任务

一切准备就绪了,我们可以来跑一把MR。

hadoop jar /cube/install/hadoop-3.1.4/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.4.jar pi 3 7

这是官方提供的一个MR样例包,我们用它来计算pi值。3代表有3个map,7代表每个map的采样数量。

ps:猜测这里可能是用到了一种类似抛硬币求概率,再取平均值的算法。

 

看到黄色字,说明成功了。看到uber mode : true了吗?随意我们设置的小任务聚合功能生效了。

中间打印了一些资源信息被我省略了,直接来看结果。

 

可以看到,任务运行了8秒多,得到的Pi值因为样本太少,3*7=21次实验,所以不是很精确。

PS:如果把实验次数提升到2亿次,可以把精度提高到小数点后7位,对此我只想说——祖冲之牛比。

我们可以复制上面白字链接,到historyserver(就是最后启动的那个服务)上看看运行结果。3个map,一个reduce。和控制台看到的是一致的。

同时我们发现我们的页面地址跳转到了 http://cube01:19888/jobhistory/job/job_1650011361925_0001,这实际是我们配置的日志聚合服务器地址。

 

⑤关闭集群

stop-dfs.sh

stop-yarn.sh
mapred --daemon stop historyserver

除此之外,我们也可以用start-all.sh 和 stop-all.sh来启动和关闭集群。

(如果resourcemanager和namenode不在一台机器,则不能使用start-all.sh和stop-all.sh来启停集群,需要分别于所在服务器启动和关闭)

 

至此我们把hadoop集群搭建好了,并且跑了一个小任务,证明了1、我们的环境是可用的,2、祖冲之牛比。

接下来,我们将继续搭建其他大数据组件。

欢乐的时光总是短暂,我们下次见。

posted on 2021-09-21 00:50  追随的风  阅读(427)  评论(0)    收藏  举报