原生Hadoop3.X高可用配置方式

Hadoop3.X版本,在2017年左右就有了第一个alpha版本,但是那个时候刚出来,所以没有人使用,到2018年3.0.0版本作为第一个3,X正式发布,截止当前本文书写时间,3.X版本已经发展到了3.4,在Hadoop的顶层设计上最大的区别就是在2.X的时候,高可用机制只允许一个在工作中,一个在备用,但是3.X的hadoop允许最多存在五套高可用节点。当然,官方推荐最多三套,自带的MR计算框架也由原来的纯磁盘运算加入了内存运算的设计。

在给大家介绍3.X如何搭建集群之前,要先给大家说一些理论上的东西,当你要把Hadoop运行在商业硬件上。可以选择普通硬件供应商生产的标准化的、广泛有效的硬件来构建集群,无需使用特定供应商生产的昂贵、专有的硬件设备。但要注意商业硬件并不等同于低端硬件。低端机器常常使用便宜的零部件,其故障率远高于更贵一些,但仍是商业级别的机器。当管理几十台、上百台,甚至几千台机器时,选择便宜的零部件并不划算,因为更高的故障率推高了维护成本。也不推荐使用大型的数据库级别的机器,因为这类机器的性价比太低了。

在国内,很多互联网小作坊,可能会考虑使用少数几台数据库级别的机器来构建一个集群,使其性能达到一个中等规模的商业机器集群。然而,这会埋下很大的一个坑洞,当大比例的集群由于硬件故障无法使用,或者硬件规格过时后,会对整个集群产生更大的负面影响。

这里举例说明,在2010 年年中,运行Hadoop的datanode和tasktracker的典型机器具有以下规格:

处理器,两个四核2~2.5 GHz CPU
内存,16~24 GB ECC RAM  (使用ECC内存能够有效减少Hadoop的效验错误)
存储器,4x1TB SATA 硬盘
网络,千兆以太网

按照上面这种条件来说,在实际实施中,尽管各个集群采用的硬件规格肯定有所不同,但是就现在最新的服务器而言,肯定都比这个配置高,即使有的节点可能很垃,属于十多年以前的机子,但是Hadoop使用多CPU和多磁盘,分而治之的方法,可以充分利用硬件组成一个强大的集群功能。

在搭建的途中,有一点要注意的是,按照官方的说法,Hadoop本身尽管建议采用RAID作为 namenode的存储器以保护元数据,但是!不推荐直接使用RAID作为datanode的存储设备,因为它不会给HDFS带来其他益处。HDFS所提供的节点间数据复制技术已可满足数据备份需求,无需使用RAID的冗余机制。

尽管RAID条带化技术(RAID0)被广泛用于提升性能,但是其速度仍然比用在HDFS 里的JBOD(Just a Bunch Of Disks)技术慢。JBOD可以在所有磁盘之间循环调度HDFS数据块。而RAID0的读写操作受限于磁盘阵列中最慢盘片的速度,而JBOD的磁盘操作均独立,因而平均读写速度高于最慢盘片的读写速度。需要强调的是,各个磁盘的性能在实际使用中总存在相当大的差异,即使对于相同型号的磁盘。雅虎集群曾经有过一个评测报告(http://markmail.org/message/xmzc45zi25htr7ry)表明,在一个测试(Gridmix)中,JBOD 比RAID0快10%,在另一测试(HDFS写吞吐量)中,JBOD 比 RAID 0 快 30%。最后,若JBOD配置的某一磁盘出现故障,HDFS可以忽略该磁盘,继续工作。而 RAID 的某一盘片故障会导致整个磁盘阵列不可用,进而使相应节点失效。

此外,Hadoop 的主体由Java语言写成,能够在任意一个安装了JVM的平台上运行。但由于仍有部分代码(例如控制脚本)需在Unix环境下执行,因而Hadoop 并不适宜以最终产品的形态运行在非Unix平台上。

而至于一个 Hadoop 集群到底应该有多大?这个问题并无确切答案。但是,Hadoop的魅力在于用户可以在初始阶段构建一个小集群(大约10个节点),并随存储与计算需求增长持续扩充。从某种意义上讲,更恰当的问题是:你的集群需要增长得多快?通过以下一个关于存储的例子可以体会更深。

假如数据每周增长1TB。如果采用三路HDFS复制技术(就是数据块的备份数+本身),则每周需要增加3 TB 存储能力。再加上一些中间文件和日志文件(约占30%),基本上相当于每周添设一台机器(2010年的典型机器)。当然在实际上,一般不会每周去购买一台新机器并将其加入集群。类似这样的粗略计算意义在于了解集群的规模:既,在本例中,保存两年数据大致需要100台机器。

而对于一个小集群(几十个节点)而言,理论上最极端时,在一台master机器上同时运行 namenode 和jobtracker(这个组件是yarn的前身,但是很多外语文献任然会使用这个名称),一般没问题,但需确保至少一份namenode的元数据被另存在远程文件系统中,当然这是极端情况下,正儿八经使用中,没有谁会给自己找麻烦,老老实实的搭完全分布式就可以,就算自己本地的测试环境,搭建单节点也不要把namenode和yarn搭在一个节点上。

在2.x,甚至是更早的版本中hadoop存在着一个角色叫secondarynamenode,在1.x的时候它是用来作为备用namenode存在的一个角色,说白了就是一个暂时解决单namenode宕机的方案,以及辅助主namenode做一些日志聚合等操作。而在2.x的时候hadoop提供了namenode的ha,既高可用解决方案后,secondarynamenode就只剩下伪分布式或者单namenode搭建时为主namenode提供日志聚合之类的辅助能力,ha的时候集群中就没有使用它的必要。现在到了3.x,请大家彻底忘掉secondarynamenode这个角色,因为3.x最多允许集群存在5个namenode。

理论知识的最后,和大家说一个有意思的事情,在早期,人们通常这样认为,集群应该配备的是32位机器,以避免大指针引起的存储开销。Sun公司的Java 6 update 14的特色之一“压缩的普通对象指针”显著降低了这类开销,因而说白了现在在64位硬件上运行 Hadoop是会降低它的性能的,当然这里的降低是指有一些底层环境的能力是富裕的。

在这里插入图片描述

在网络策略上,Hadoop 集群架构通常包含两级网络拓扑,如上图所示。一般来说,各机架装配30~40个服务器,共享一个1GB的交换机(该图中各机架只画了3个服务器),各机架的交换机又通过上行链路与一个核心交换机或路由器(通常为1GB或更高)互联。该架构的突出特点是同一机架内部的节点之间的总带宽要远高于不同机架上的节点间的带宽。

在机架选择上,为了达到Hadoop的最佳性能,配置Hadoop系统以让其了解网络拓扑状况就极为关键。如果集群只包含一个机架,就无需做什么,因为这是默认配置。但是对于多机架的集群来说,描述清楚节点-机架间的映射关系就很有必要。这样的话,当Hadoop将MapReduce任务分配到各个节点时,会倾向于执行机架内的数据传输(拥有更多带宽),而非跨机架数据传输。HDFS将能够更加智能地放置复本(replica),以取得性能和弹性的平衡。

诸如节点和机架等的网络位置以树的形式来表示,从而能够体现出各个位置之间的网络“距离”。namenode使用网络位置来确定在哪里放置块的复本,MapReduce的调度器根据网络位置来查找最近的复本,将它作为map任务的输入。

在上面的网络拓扑图中,机架拓扑由两个网络位置来描述,即/switchl/rack1和/switchl/rack2。由于该集群只有一个顶层路由器,这两个位置可以简写为/rack1 和/rack2。

Hadoop 配置需要通过一个Java接口DNSToSwitchMapping来指定节点地址和网络位置之间的映射关系。该接口定义如下:

public interface DNSToSwitchMapping {
   
	public List<String> resolve(List<String> names);
}

resolve()函数的输入参数names 描述IP地址列表,返回相应的网络位置字符串列表。topology.node.switch.mapping.impl配置属性实现了 DNSToSwitchMapping接口,namenode和jobtracker均采用它来解析工作节点的网络位置。

在上例的网络拓扑中,可将node1、node2 和node3映射到/rack1,将 node4、node5 和node6 映射到/rack2 中。

但是,大多数安装并不需要额外实现新的接口,只需使用默认的 ScriptBasedMapping实现即可,它运行用户定义的脚本来描述映射关系。脚本的存放路径由属性topology.script.file.name控制。脚本接受一系列输入参数,描述带映射的主机名称或IP地址,再将相应的网络位置以空格分开,输出到标准输出。可以参考Hadoop wiki的一个例子,网址为http://wiki.apache.org/hadoop/topology_rack_awareness_scripts。如果没有指定脚本位置,默认情况下会将所有节点映射到单个网络位置,即/default-rack。


开始正式安装

注意:安装所需的服务器SSH免密互信、JavaJDK、时间同步、域名映射、静态IP、关闭防火墙、修改主机名称这些环境准备,这里就不演示了,有需要,去我主页找原生大数据集群搭建二里面看。

Hadoop自身搭建完是存储与计算磁盘级别分离,如果有存储和计算节点级别分离的特殊需求见–》https://blog.youkuaiyun.com/dudadudadd/article/details/141271409

当你要把hadoop放到window开发电脑上时,需要在https://github.com/cdarlint/winutils/tree/master/中下载对应版本的hadoop-win工具 ,其实就是把得到的bin下文件放到你的hadoop解压包下的bin李米娜如果重复则覆盖

搭建的时候要格外注意,本文档中用的是root用户,因此在后面的使用上不会有太大的问题,不过业内习惯把hadoop的集群文件默认交给一个叫hdfs的系统用户,后续不同用户使用也会有对应的用户,这种情况下就要确保所有集群中useradd了对应的用户,而且确保每个队列对用户设置了合适的访问权限。同时hadoop的配置文件有很多不知有默认值,而且默认是最终状态不允许覆盖,比如MR任务参数就有一些默认无法覆盖,你可以通过yarn-web界面集群整体配置中看到配置中是否携带了<final>true</final>,如果你需要使用时覆盖就把它重写在yarn-web中展示的默认配置位置文件中,并设置<final>false</final>

第一步:本次操作的版本是3.3.6,上传Hadoop安装包解压即可,这里有一个坑要注意,按照试错经验以及官网的一些资料,发现默认情况下3.x的hadoop是不允许root用户启动的,但是如果你用更改用户的方式搭建3.x就会发现在启动的时候,无论你关闭SELinux安全模块也好,还是用sudo也好,都无法越过Linux的线程优先级拦截,所以我们需要搭建的时候通过在配置文件里面追加新配置的方式,替换掉默认的用户启动限制。

cd /opt
tar -zxvf hadoop-3.3.6.tar.gz

第二步:进入配置文件所在的路径${HADOOP_HOME}/etc/hadoop,修改所有*-env.sh中存在的JAVA_HOEM值

第三步:打开hadoop-env.sh文件修改如下配置项,指定root用户为运行这些组件的用户,注意除了HDFS_NAMENODE_USER使原本就有的配置,其他的都是直接追加就行。

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

第四步:修改配置文件core-site.xml

<configuration>
   <!-- 在ha模式中指定hdfs集群的逻辑名称,把多个NameNode的地址组装成一个组序列,hdp是自定义的名字你可以改其他的 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hdp</value>
    </property>
    
     <!-- 声明hadoop运行时产生文件的所用到的默认本地存储目录,在3.x之后这个路径会被在hdfs上复用,用来存储yarn一些运行数据,知道就行,不需要太多的注意,不要看到hdfs上的同路径感到蒙圈 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/hadoop-3.1.3/hdpData/tmp</value>
    </property>
    
     <!-- 配置HDFS网页登录使用的静态用户:Root,你如果不设置这个那么你就需要把hdfs的所有文件全选改为777不然操作不了web页面-->
    <property>
        <name>hadoop.http.staticuser.user</name>
        <value>root</value>
    </property>
    
     <!-- 指定zookeeper集群的地址:zkfc要连接的zkServer地址,用于管理hdfs集群 -->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>node001:2181,node002:2181,node003:2181</value>
    </property>

    <!--修改ipc参数,防止出现连接journalnode服务ConnectException,默认10s-->
    <property>
        <name>ipc.client.connect.max.retries</name>
        <value>100</value>
    </property>
    <property>
        <name>ipc.client.connect.retry.interval</name>
        <value>10000</value>
    </property>
</configuration>

配置好上面的core文件之后,hdfs提供了一个回收站的能力,你可以选择是否在其中配置。之所以没有直接写在core文件里面,是因为一旦启用的这个能力,你想要越过回收站直接删除文件,需要使用命令hdfs dfs -rm -skipTrash 路径来删除文件,当然普通的删除命令在hdfs底层实现就变成了移动,使用hdfs dfs -expunge命令可以清空回收站中的所有文件,这些文件将被永久删除且无法恢复,想要恢复文件可以在/user/${USER}/.Trash/Current目录中找到对应的文件,移动会原来的位置即可,其中${USER}是执行删除操作的用户名。值得注意的是启动了回收站能力之后,重启集群namenode很容易直接进入安全模式。

<!-- 回收站保存文件的过期时间,默认为0,单位为分钟,1440为24小时 --> 
<property>
    <name>fs.trash.interval</name>
    <value>1440</value> 
</property>

<!-- hdfs每隔多长时间检查检查一次回收站,目的是将回收站中的数据状态同步给namenode,一般和过期时间保持一致 -->  
<property>
    <name>fs.trash.checkpoint.interval</name>
    <value>1440</value>
</property>

第五步:修改配置文件hdfs-site.xml配置的时候注意3.x允许最多存在5个namenode,但是官方建议3个位最佳,可以节省很多不必要的网络IO

<configuration>
    <!-- 这里是在core中设置的namenode逻辑组名称,自动寻找NameNode节点 -->
    <property>
        <name>dfs.nameservices</name>
        <value>hdp</value>
    </property>
    
    <!-- 把定义的逻辑名称指向各个namenode的别名,即集群中NameNode节点,3.x最多5个 -->
    <property>
        <name>dfs.ha.namenodes.hdp</name>
        <value>nn1,nn2</value>
    </property>
    
    <!-- NameNode RPC通信地址 -->
    <property>
        <name>dfs.namenode.rpc-address.hdp.nn1</name>
        <value>node001:8020</value>
    </property>
    
    <property>
        <name>dfs.namenode.rpc-address.hdp.nn2</name>
        <value>node002:8020</value>
    </property>
    
    <!-- NameNode的http通信地址-->
    <property>
        <name>dfs.namenode.http-address.hdp.nn1</name>
        <value>node001:9870</value>
    </property>
    
    <property>
        <name>dfs.namenode.http-address.hdp.nn2</name>
        <value>node002:9870</value>
    </property>
    
    <!-- 指定JournalNode服务节点,并同时指定NameNode的edits元数据在JournalNode上的存放位置,这个配置本质上的目的就是在zkfc服务保证NN高可用顺利切换的同时,让主副namenode对datanode中数据块信息有一个同步的位置,而这个位置的服务在哪里、怎么访问、又该访问服务中的那个路径,就在此配置,路径中保存的是集群数据的操作日志,注意配置的时候我这里的hdp5、hdp6、hdp7是JournalNode所在节点,不是zk所在节点,并且有的人以为JournalNode是跟随datanode启动的,并不是的,他们两个是不同的服务,这这个配置里你需要有多少个JournalNode就定义多少个就行,而不是datanode的节点,这种想法的一般都没搭建过商用化集群,一直用的本地测试,最终要的是路径中hdp1是你的集群ID,要和dfs.nameservices一致-->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://node001:8485;node002:8485;node003:8485/hdp</value>
    </property>
    
    <!-- 指定JouralNode节点存放编辑日志的本地存储路径 -->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/hadoop-3.1.3/hdpData/journaldata</value>
    </property>
    
    <!-- 开启自动故障转移功能 -->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值