CentOS 7.0 hadoop 安装与配置
蒋小超 2015.04.03
背景介绍
hadoop 是一种大数据分布式运算解决方案。
hadoop 是什么?
实际上 hadoop 就是 Google 的 MapReduce 核心算法的一个开源实现,主要用于海量数据的处理。
一般来说数据量超过 1T 就可以算海量数据了,当然如果只是一个简单的文件超过 1T 还是很容易的,但是这里说的是数据,就是一个一个小的数据记录的集合,比如淘宝这样的很多商品,比如 Google 这样的搜索引擎。
那么就有个疑问了,如果只是数据记录, hadoop 相比数据库有什么优势?数据库也是大量数据的集合啊?这就牵扯到了分布式计算, hadoop 在设计时就考虑过用大量性能不是那么强的节点合并在一起工作,而数据库往往有一个主数据库,能力往往取决于主要设备的性能。实际上 hadoop 还有一个 hive 分支用来做和数据库差不多的事情。
hadoop 能做什么?
就像上面说的, hadoop 主要目的就是海量数据处理,根据它的设计可以做:
大量数据的保存。这个其实不是主要功能,不过 hadoop 可以在保存文件的时候保存几个备份,而且还会把他们放到不同的节点里面,所以当做 RAID 也是可以的。
数据仓库/数据挖掘。比如大量日志的分析等等
搜索引擎。这是设计初衷了,就是想快速索引和查询
云计算。收集用户方方面面的信息然后从中间获取信息(看起来像数据挖掘?)
研究。分布式计算什么的挺前沿的,可以研究一下咯。而且云计算的本质也就是海量数据的存储和并行处理
这里是hadoop 主页
大数据集群中不同主机扮演不同角色,主要分为下面几种:
Master
NameNode
NameNode 用于管理文件系统 HDFS ,维护文件系统树结构和文件元数据。当有新文件要写入系统时客户端会先向 NameNode 查询当前文件系统的状态,然后得知自己可以往哪里写入,最后实际写入文件系统,这中间 NameNode 就是管理主要信息的核心设备。ResourceManager
ResourceManager 用于管理和分配工作,它是所有工作的总调度程序。
Slave
DataNode
DataNode 提供文件存储,它将自己的存储空间分块,然后向 NameNode 报告自己的存储状态并负责真正保存文件NodeManager
NodeManager 用于接受 ResourceManager 分配的工作并实际工作,是所有工作的实际执行者。
这篇文档实际上是参考 这里 加上自己的实际试验写出来了,原文没有使用 CentOS 7,而且版本稍微有点老,我仅仅是更新了一下。
安装和配置步骤
安装环境
我这里的安装环境基于虚拟机,有3个 CentOS 7.0 虚拟机,IP地址分别为:
- 192.168.110.10 Master.hadoop
- 192.168.110.11 Slave_1.hadoop
- 192.168.110.12 Slave_2.hadoop
因为 hadoop 要求所有参与设备的环境都相同,包括有相同用户,相同安装目录等,所以可以先把准备工作做好。
准备工作
创建用户 ‘hadoop’,用户密码和用户名相同。这个用户用于实际工作,root 用户仅用于配置环境
useradd hadoop passwd hadoop
主机命名和注册
首先修改每台主机的 /etc/hostname 文件,确定主机名然后修改每台主机的 /etc/hosts 文件,将主机名和 IP 地址对应关系都写进去
开启不需要密码的 ssh 登录
hadoop 对其他 DataNode 的操作都用的是 ssh 连接,频繁操作肯定不能不停的输入密码。理论上每个设备都应该创建密钥并在其他设备上注册,但其实在 NameNode 上做下面的操作也可以,因为一般情况下都是 NameNode 操作 DataNode.# 创建用户密钥,root 用户和 hadoop 用户都要创建 ssh-keygen -t rsa # 将密钥在 DataNode 上注册,注意要切换用户 ssh-copy-id root@Master.hadoop ssh-copy-id hadoop@Master.hadoop
上面的动作都完成后应该可以用下面的命令测试:
```bash
# 必须获得响应
ping Slave_1.hadoop
# 不需要输入密码即可登录其他设备
ssh Slave_1.hadoop
```
- 在每个 slave 上面用 ssh-copy-id 将自己的私钥在 Master 上注册,slave 之间就不需要注册了
下载和安装
对于 hadoop 来说有 2 个必要组件,分别是:
hadoop
下载站点Java 运行环境
CentOS 自带 Java 环境,只要用 yum 安装就可以了yum install openjdk
环境变量最好加入 /etc/profile 文件里,在文件里加入下面的内容:
export JAVA_HOME=/usr/lib/jvm/java-openjdk export JRE_HOME=/usr/lib/jvm/java-openjdk/jre export CLASSPATH=.:${CLASSPATH}:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${PATH}:${JAVA_HOME}/bin:${JRE_HOME}/bin
然后让配置生效:
source /etc/profile
将配置文件复制到其他客户端:
scp /etc/profile root@slave_1:/etc
如果没有意外的话 java 应该就可用了,可以用下面的命令检查:
[root@Master etc]# java -version java version "1.7.0_51" OpenJDK Runtime Environment (rhel-2.4.5.5.el7-x86_64 u51-b31) OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)
配置 hadoop
我这里下载的是 hadoop-2.6.0.tar.gz 文件,将它复制到 /usr 目录下,然后用下面的命令解压并把它交给 hadoop 用户:
```bash
cd /usr
tar zxvf hadoop-2.6.0.tar.gz
mv hadoop-2.6.0 hadoop
chown -R hadoop:hadoop hadoop
```
从现在开始就要切换到 hadoop 用户了,之后的命令中如果有需要 root 权限的都会专门说明。
先在 hadoop 安装目录中创建一个 tmp 目录,未来的查询都可以在这个目录下进行
cd /usr/hadoop mkdir tmp
将 hadoop 需要的环境变量加入 /etc/profile 文件中去,这个步骤需要 root 权限
在文件最后加上下面的内容,然后拷贝到其他主机中去:
# Set hadoop environment export HADOOP_HOME=/usr/hadoop export PATH=$PATH:$HADOOP_HOME/bin
现在开始真正配置 hadoop 了,下面的文件都在 hadoop 安装目录的 etc/hadoop 目录下,注意先备份。
最开始的时候 hadoop 配置文件很少,不过随着项目越来越大配置文件也开始增加了,到现在为止 hadoop 的代码大致分为了 core , hdfs 和 map/reduce 三部分,配置文件也被分成了三个。不过 mapred-site.xml 其实可以不配置 :
- core- site.xml
- hdfs-site.xml
- mapred-site.xml
其中 core-site.xml 和 hdfs-site.xml 是站在 HDFS 角度上配置文件; core-site.xml 和 mapred-site.xml 是站在 MapReduce 角度上配置文件。
配置 hadoop-env.sh
这里真正要配置的其实就是 JAVA_HOME 这个参数,不过其实不配置也可以在上面步骤中的环境变量中得到
export JAVA_HOME=/usr/lib/jvm/java-openjdk
配置 core-site.xml
按照下面的内容配置 Master (NameNode/ResourceManager) 的地址和端口号,进行下面的配置前一定要创建 /usr/hadoop/tmp 目录。
fs.defaultFS 用来指定 ResourceManager 设备
<configuration> <property> <name>hadoop.tmp.dir</name> <value>/usr/hadoop/tmp</value> <description>A base for other temporary directories.</description> </property> <property> <name>fs.defaultFS</name> <value>hdfs://Master.hadoop</value> </property> <!-- file system properties --> <property> <name>fs.default.name</name> <value>hdfs://Master.hadoop:9000</value> </property> </configuration>
上面的 hadoop.tmp.dir 如果不配置的话默认就会用临时目录 /tmp/hadoo-hadoop 。这个目录每次重启后都会被删掉,必须重新执行format才行,否则会出错。
配置 hdfs-site.xml
下面配置中的 dfs.replication 参数用来指定每个文件保存多少份,对于普通使用来说 1 份就可以,但这种没有备份的情况可能一个 DataNode 损坏就丢失文件了,如果文件比较重要最好还是多备份一份,这里设置为 2 是因为我们有 2 台 DataNode 正好每个上面备份一个,如果配置的 DataNode 数量不够会报警。如果不配置这个参数那么默认是 3
<configuration> <property> <name>dfs.replication</name> <value>2</value> </property> </configuration>
配置 mapred-site.xml
hadoop 2.6 不需要配置这个文件
主机配置
修改 /usr/hadoop/etc/hadoop/masters 文件,默认如果没有那么就得新建一个,在里面加上一行:
192.168.110.11
或者名称也可以Master.hadoop
修改 /usr/hadoop/etc/hadoop/slaves 文件,在里面把其他 DataNode 加进来
Slave_1.hadoop Slave_2.hadoop
好了,到这里 Master 上的配置就完成了,之后需要将配置好的目录用 scp 拷贝到其他 slave 机器上。理论上来说 slave 上面应该单独配置,不过直接复制其实也是可以的。复制完成了一定记得到 slave 主机上把 hadoop 目录的权限交给 hadoop:
```bash
scp -r /usr/hadoop root@192.168.110.12:/usr
chown -R hadoop:hadoop /usr/hadoop
```
记得把 /etc/profile 文件也复制到客户机上去,主要是那几个系统变量:
`scp /etc/profile root@192.168.110.12:/etc`
启动和功能验证
下面的操作都是用 hadoop 用户在 Master 上进行的。
格式化 HDFS 系统
在 NameNode 上要格式化 HDFS 系统,这个动作只需要做一次就可以了:
`hadoop namenode -format`
我这里执行后的输出如下,看到 Exiting with status 0 吗?
```bash
[hadoop@Master hadoop]$ hadoop namenode -format
DEPRECATED: Use of this script to execute hdfs command is deprecated.
Instead use the hdfs command for it.
15/04/07 18:15:30 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG: host = Master.hadoop/192.168.110.11
STARTUP_MSG: args = [-format]
STARTUP_MSG: version = 2.6.0
STARTUP_MSG: classpath = ...
STARTUP_MSG: build = https://git-wip-us.apache.org/repos/asf/hadoop.git -r e3496499ecb8d220fba99dc5ed4c99c8f9e33bb1; compiled by 'jenkins' on 2014-11-13T21:10Z
STARTUP_MSG: java = 1.7.0_51
************************************************************/
15/04/07 18:15:30 INFO namenode.NameNode: registered UNIX signal handlers for [TERM, HUP, INT]
15/04/07 18:15:30 INFO namenode.NameNode: createNameNode [-format]
Formatting using clusterid: CID-8762898e-f67e-4cc9-b9ff-199c054c3051
15/04/07 18:15:31 INFO namenode.FSNamesystem: No KeyProvider found.
15/04/07 18:15:31 INFO namenode.FSNamesystem: fsLock is fair:true
15/04/07 18:15:31 INFO blockmanagement.DatanodeManager: dfs.block.invalidate.limit=1000
15/04/07 18:15:31 INFO blockmanagement.DatanodeManager: dfs.namenode.datanode.registration.ip-hostname-check=true
15/04/07 18:15:31 INFO blockmanagement.BlockManager: dfs.namenode.startup.delay.block.deletion.sec is set to 000:00:00:00.000
15/04/07 18:15:31 INFO blockmanagement.BlockManager: The block deletion will start around 2015 Apr 07 18:15:31
15/04/07 18:15:31 INFO util.GSet: Computing capacity for map BlocksMap
15/04/07 18:15:31 INFO util.GSet: VM type = 64-bit
15/04/07 18:15:32 INFO util.GSet: 2.0% max memory 889 MB = 17.8 MB
15/04/07 18:15:32 INFO util.GSet: capacity = 2^21 = 2097152 entries
15/04/07 18:15:32 INFO blockmanagement.BlockManager: dfs.block.access.token.enable=false
15/04/07 18:15:32 INFO blockmanagement.BlockManager: defaultReplication = 2
15/04/07 18:15:32 INFO blockmanagement.BlockManager: maxReplication = 512
15/04/07 18:15:32 INFO blockmanagement.BlockManager: minReplication = 1
15/04/07 18:15:32 INFO blockmanagement.BlockManager: maxReplicationStreams = 2
15/04/07 18:15:32 INFO blockmanagement.BlockManager: shouldCheckForEnoughRacks = false
15/04/07 18:15:32 INFO blockmanagement.BlockManager: replicationRecheckInterval = 3000
15/04/07 18:15:32 INFO blockmanagement.BlockManager: encryptDataTransfer = false
15/04/07 18:15:32 INFO blockmanagement.BlockManager: maxNumBlocksToLog = 1000
15/04/07 18:15:32 INFO namenode.FSNamesystem: fsOwner = hadoop (auth:SIMPLE)
15/04/07 18:15:32 INFO namenode.FSNamesystem: supergroup = supergroup
15/04/07 18:15:32 INFO namenode.FSNamesystem: isPermissionEnabled = true
15/04/07 18:15:32 INFO namenode.FSNamesystem: HA Enabled: false
15/04/07 18:15:32 INFO namenode.FSNamesystem: Append Enabled: true
15/04/07 18:15:32 INFO util.GSet: Computing capacity for map INodeMap
15/04/07 18:15:32 INFO util.GSet: VM type = 64-bit
15/04/07 18:15:32 INFO util.GSet: 1.0% max memory 889 MB = 8.9 MB
15/04/07 18:15:32 INFO util.GSet: capacity = 2^20 = 1048576 entries
15/04/07 18:15:32 INFO namenode.NameNode: Caching file names occuring more than 10 times
15/04/07 18:15:32 INFO util.GSet: Computing capacity for map cachedBlocks
15/04/07 18:15:32 INFO util.GSet: VM type = 64-bit
15/04/07 18:15:32 INFO util.GSet: 0.25% max memory 889 MB = 2.2 MB
15/04/07 18:15:32 INFO util.GSet: capacity = 2^18 = 262144 entries
15/04/07 18:15:32 INFO namenode.FSNamesystem: dfs.namenode.safemode.threshold-pct = 0.9990000128746033
15/04/07 18:15:32 INFO namenode.FSNamesystem: dfs.namenode.safemode.min.datanodes = 0
15/04/07 18:15:32 INFO namenode.FSNamesystem: dfs.namenode.safemode.extension = 30000
15/04/07 18:15:32 INFO namenode.FSNamesystem: Retry cache on namenode is enabled
15/04/07 18:15:32 INFO namenode.FSNamesystem: Retry cache will use 0.03 of total heap and retry cache entry expiry time is 600000 millis
15/04/07 18:15:32 INFO util.GSet: Computing capacity for map NameNodeRetryCache
15/04/07 18:15:32 INFO util.GSet: VM type = 64-bit
15/04/07 18:15:32 INFO util.GSet: 0.029999999329447746% max memory 889 MB = 273.1 KB
15/04/07 18:15:32 INFO util.GSet: capacity = 2^15 = 32768 entries
15/04/07 18:15:32 INFO namenode.NNConf: ACLs enabled? false
15/04/07 18:15:32 INFO namenode.NNConf: XAttrs enabled? true
15/04/07 18:15:32 INFO namenode.NNConf: Maximum size of an xattr: 16384
15/04/07 18:15:32 INFO namenode.FSImage: Allocated new BlockPoolId: BP-1017743206-192.168.110.11-1428401732358
15/04/07 18:15:32 INFO common.Storage: Storage directory /usr/hadoop/tmp/dfs/name has been successfully formatted.
15/04/07 18:15:32 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
15/04/07 18:15:32 INFO util.ExitUtil: Exiting with status 0
15/04/07 18:15:32 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at Master.hadoop/192.168.110.11
************************************************************/
```
启动 hadoop
以前的时候都是用 sbin/start-all.sh 脚本启动,不过现在已经不建议这么做了,建议的方式是分别执行下面 2 个脚本:
```bash
./sbin/start-dfs.sh
./sbin/start-yarn.sh
```
执行上面命令之前最好关闭集群中其他设备的防火墙,有可能会被奇怪的挡住……另外只需要在 Master 上执行即可,不需要找 Slave
我这里的输出是这样的:
```bash
[hadoop@Master hadoop]$ ./sbin/start-dfs.sh
Starting namenodes on [localhost]
localhost: starting namenode, logging to /usr/hadoop/logs/hadoop-hadoop-namenode-Master.hadoop.out
Slave_1.hadoop: starting datanode, logging to /usr/hadoop/logs/hadoop-hadoop-datanode-Slave_1.hadoop.out
Slave_2.hadoop: starting datanode, logging to /usr/hadoop/logs/hadoop-hadoop-datanode-Slave_2.hadoop.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: secondarynamenode running as process 32261. Stop it first.
```
```bash
[hadoop@Master hadoop]$ ./sbin/start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /usr/hadoop/logs/yarn-hadoop-resourcemanager-Master.hadoop.out
Slave_1.hadoop: starting nodemanager, logging to /usr/hadoop/logs/yarn-hadoop-nodemanager-Slave_1.hadoop.out
Slave_2.hadoop: starting nodemanager, logging to /usr/hadoop/logs/yarn-hadoop-nodemanager-Slave_2.hadoop.out
```
如果都正确启动的话可以在 slave 主机上去看看 /usr/hadoop/tmp 目录,里面应该有这 2 个目录的,都是自动创建的:
```bash
[root@Salve_1 hadoop]# ll tmp/
total 0
drwxrwxr-x 3 hadoop hadoop 17 Apr 7 18:34 dfs
drwxr-xr-x 5 hadoop hadoop 54 Apr 7 18:37 nm-local-dir
```
验证是否启动
下面的方法都可以验证:
使用 java 的 jps 小工具可以看到 ResourceManager , NameNode 都启动了:
# On Master [hadoop@Master hadoop]$ jps 29011 ResourceManager 21836 NameNode 2159 Jps 32261 SecondaryNameNode # On Slave [root@Salve_1 hadoop]# jps 4799 DataNode 20182 Jps 11010 NodeManager
用
./bin/hdfs dfsadmin -report
查看状态# On Master [hadoop@Master hadoop]$ ./bin/hdfs dfsadmin -report Configured Capacity: 107321753600 (99.95 GB) Present Capacity: 95001157632 (88.48 GB) DFS Remaining: 95001149440 (88.48 GB) DFS Used: 8192 (8 KB) DFS Used%: 0.00% Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 ------------------------------------------------- Live datanodes (2): Name: 192.168.110.12:50010 (Slave_1.hadoop) Hostname: Slave_1.hadoop Decommission Status : Normal Configured Capacity: 53660876800 (49.98 GB) DFS Used: 4096 (4 KB) Non DFS Used: 6159425536 (5.74 GB) DFS Remaining: 47501447168 (44.24 GB) DFS Used%: 0.00% DFS Remaining%: 88.52% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Thu Apr 09 10:49:27 CST 2015 Name: 192.168.110.13:50010 (Slave_2.hadoop) Hostname: Slave_2.hadoop Decommission Status : Normal Configured Capacity: 53660876800 (49.98 GB) DFS Used: 4096 (4 KB) Non DFS Used: 6161170432 (5.74 GB) DFS Remaining: 47499702272 (44.24 GB) DFS Used%: 0.00% DFS Remaining%: 88.52% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Thu Apr 09 10:49:27 CST 2015
如果都运行了,就可以用浏览器查看了。在系统中使用下面的命令可以看到 hadoop 使用的端口:
[hadoop@Master hadoop]$ netstat -tnulp | grep java (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 21836/java tcp 0 0 0.0.0.0:50090 0.0.0.0:* LISTEN 32261/java tcp 0 0 0.0.0.0:50070 0.0.0.0:* LISTEN 21836/java tcp6 0 0 :::8030 :::* LISTEN 29011/java tcp6 0 0 :::8031 :::* LISTEN 29011/java tcp6 0 0 :::8032 :::* LISTEN 29011/java tcp6 0 0 :::8033 :::* LISTEN 29011/java tcp6 0 0 :::8088 :::* LISTEN 29011/java
hadoop 在进程中的表现就是 java 程序, IPv6 的几个端口用于内部通讯, IPv4 的 3 个端口分别是数据通讯RPC端口(9000)、DFS 状态查看(50070)和整体状态查询(50090)
附录
正常情况下各个进程情况
Master
Master 有 3 个主要进程就可以了,以前还有 JobTracker ,不过现在这个进程会在每次开始工作时自动启动,完成后退出[hadoop@Master hadoop]$ jps 15336 SecondaryNameNode 23851 Jps 16195 ResourceManager 14081 NameNode
Slave
Slave 有 2 个即可, TaskTracker 也是需要时启动[hadoop@Slave_1 logs]$ jps 9683 NodeManager 18383 Jps 8749 DataNode