HDFS上路第二篇先上手编译部署新+旧版本的Hadoop-HDFS, 并了解基本的命令操作和配置项, 先学会使用, 文档方面优先参考官方文档, 再可以补充的看看其它博客
附: 从官方页面可以看到项目本身是
Hadoop,而不是直接称为HDFS的原因是因为Hadoop是包括”HDFS + Yarn”两个大模块的, 但是我们现在先不多研究调度任务的Yarn, 就直接说HDFS了.
0x00. 准备
HDFS可以用三种模式搭建(单机/伪分布式/分布式), 单机伪分布式版可以参考这篇文章. 这里我就直接上分布式的正式版了(版本分1.x和3.x两个), 准备和安装过程优先参考对应版本的官方文档, 有问题再单独搜索备注, 首先至少准备3个节点(1主2从), 并配置好主到从节点的SSH访问, 方便分发文件命令.
| 节点IP | 功能(进程) | 备注 |
|---|---|---|
| 10.162.94.85 | NameNode, ResourceManager(可选) | 主节点 |
| 10.162.94.86 | DataNode, NodeManager(可选) | 数据节点 |
| 10.162.94.87 | DataNode, NodeManager(可选) | 数据节点 |
基本配置+环境:
- CentOS7.5
- Hadoop 3.1.2
如果IP没有对应域名, 最好给每个节点取个别名比如hdfs01/02/03, 后续分发和操作会方便很多. 我这里简单起见都用ip了
1 | # 给3台节点配置hostname,并修改hosts使互相认识(已有则不需要,可选) |
很多文章上会说主节点还要启动secondaryNamenode, 但是这是0.x/1.x旧版无备用主才需要的, 实际在新版有HA功能之后, 这个是不需要也不应该启动的.
而HA作为核心的一个功能, 肯定是完整的分布式HDFS必须的, 加之HDFS的主节点状态信息很重, 所以HA结构还算比较复杂, 在集群基本可用之后再去单独构建, 最后理论上需要有7个节点为宜. (多出的4个用作HA相关)
0x01. 编译
1. 初次编译
HDFS跟大部分软件一样, 可以用两种方式获得最后的二进制包:
- 直接从官方下载编译好的
binary file(访问此地址, 如果服务器下载很慢, 建议PC下好传到服务器, 有300MB+) - Git下载
source file(源码), 自行编译(我这取的是3.1.2版本)
而为了加深一些C++ native依赖问题的理解, 以及后续可能对源码进行修改, 所以自己学会编译还是需要的, 之前记得确认准备工作做好了, 然后按照我总结好的版本步骤去执行, 基本就会顺畅很多(OS基于Cent7.5), 有些编译可能很耗时, 此时同时去做其他的准备操作.
1 | # 注意: 如果'\'后系统提示命令不存在, 注意是否有空格 |
然后为了加速仓库包下载, 强烈建议替换默认源, 如果有私有仓库更好, 那下载更快了: (修改/替换~/apache-maven-3.6.0/conf/setting.xml)
1 | <!--注意复制粘贴的空字符可能报错--> |
最后执行编译命令, 为了加快速度, 强烈建议跳过测试和文档生成. (编译主要耗时还是在下包上, 所以甚至可以直接把他人的~/.m2复制一份)
1 | # 编译普通源码, native库, 但跳过文档和测试. 最后打包 (30min+) |
如果是非native报错, 一般默认-e输出的信息已经可以排查, 如果是C++(native)的报错, 那么用-X 查看具体是编译什么地方出错了, 有具体的cmake报错日志和提示, 肯定是可以定位到问题所在的, 下包顺利的话半小时就能编译完成, 接着进入分布式版部署的阶段.
2. 二次编译 (修改后)
这里是说如果修改了HDFS的源码之后的编译, 普通情况无需参考, 因为Hadoop整个项目很大, 除了第一次熟悉环境和上手建议全量编译 + native库编译, 后面如果是少量的改动, 一般就是按需编译, 然后替换了, 比如如下场景:
线上运行了官方HDFS3.1.2的环境, 我在master的基础上创建了一个新分支修改了点代码, 希望看看修改后的运行效果, 我应该怎么做最高效?
- 切换分支, 到hdfs模块里, 只编译此模块
- 线上已有环境不重新搭建 ,而是替换一下相关
jar包 - 重启线上环境(NN/DN)
1 | # 只编译hdfs代码,同样别用默认源(编译环境建议统一在一台机器) |
0x02. 集群部署
A. 配置文件
这里关键就是配置HDFS的几个位于etc/hadoop/下的配置文件, 在configuration内添加属性项, 详细含义和默认端口参考官方最新文档: (自行创建对应的数据文件夹并确保读写权限正常)
-
1
2
3
4
5
6
7
8
9
10<property>
<!--指定默认HDFS访问路径-->
<name>fs.defaultFS</name>
<value>hdfs://10.162.94.85:9000</value>
</property>
<property>
<!--指定Hadoop文件存放根目录-->
<name>hadoop.tmp.dir</name>
<value>/data01/test_hdp_data</value>
</property> -
这里还有两个场景配置项设置Namenode和Datanode的数据存储位置, 默认值是继承
core-site的前缀file://${hadoop.tmp.dir}/dfs/name, 如果需要修改再配即可.1
2
3
4
5
6
7
8
9
10<property>
<!--指定HDFS的副本数,默认3副本,这里两数据节点,就设置2-->
<name>dfs.replication</name>
<value>2</value>
</property>
<!--允许使用纯IP设置,否则会报错-->
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property> mapred-site.xml (可选, 不启动yanr则3,4 可跳)
1
2
3
4
5<property>
<!--指定Yarn作为MR调度器, 默认local-->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>yarn-site.xml (可选)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<!--Yarn就基本配置一下,其他参考文档-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<!--注意这里不建议写localhost,如果有域名写域名-->
<name>yarn.resourcemanager.hostname</name>
<value>10.162.94.85</value>
</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>修改worker文件, 配置从节点地址, 建议写主机名/别名而不是IP (2.x旧版本是slaves文件)
1
210.162.94.86
10.162.94.97
B. 分发包文件
这里我参考常见写法, 整合写了个简单的shell, 避免重复分发和操作, 当然, ssh和scp的过程最好有免密, 不然不太友好:
1 |
|
当然, 远程分发命令可能没生效, 或者bash状态不好保持, 这个时候我建议使用Xshell 自带的多窗口发送命令更方便可靠 ,等于自带的分发, 也不用写shell了…
C. 启动运行
如果是第一次运行, 可以/建议先对NameNode就行格式化, 就像上一篇文章格式化的意义所说. 然后直接脚本启动 (目录结构如下)
1 | # 仅第一次需要格式化 |
- 启动HDFS之后, 就可以在默认的
masterIP:9870访问HDFS前端确认主节点Active, 并且Live Nodes是2而不是0 (否则说明DN连接失败) - 启动Yarn后, 就可以在默认的
masterIP:访问Yarn前端:
简单排错:
- 首先看日志, 看日志, 不瞎猜, 不管是数据节点还是Yarn没有正常启动/显示/工作, 先去
logs/下看对应的日志文件, 解决90%的问题 - 剩下10%一般是网络/配置问题, 比如发现HDFS或Yarn的前端无法在你的浏览器访问, 请首先服务器本地
curl masterIP:port, 或者wget看看是不是能获取正确内容, 如果能说明正常启动了, 但是没有正常暴露服务给外界, 自行排查包括IP设置/防火墙等, 肯定可以很快定位到问题.
0x03. HDFS客户端
HDFS部署好之后, 要从其他机器给集群发命令或者提交任务, 那就自然需要一个客户端, 这里也很简单, 直接使用就行了, 把之前Hadoop的包分发到需要当客户端的机器, 就能使用场景的HDFS命令操作了. (编译的时候可以看到, client已经被包含在了里面)
然后常见的HDFS命令使用在之前的文章说过, 也适合单独拆分方便查询, 参考Hadoop常用命令
待补 –> 旧版HDFS集群部署还没有单独说, 不过考虑到有特别的改动, 似乎也不适合通用的写..
