一. HDFS简介

全称 Hadoop Distributed File System, Hadoop分布式文件系统。 根据Google的GFS论文,由Doug Cutting使用JAVA开发的开源项目。HDFS是Hadoop项目的一部分。为Hadoop提供底层的数据存储,满足上次各种实际应用使用(如Map/Reduce)。HDFS是典型的的Master/Slave集群架构,由一个NameNode和多个DateNode组成,NameName只能有一个,扮演Master角色,负责对具体的存储块的元数据进行保存,比如控制某个存储块具体保存在哪个DataNode上;DataNode可以为多个,扮演着Slave的角色,负责对具体的存储块进行保存,一个相同的存储块根据配置可以保存到多个DataNode上,以保持数据的高可用性。

二. 环境介绍

三台主机,一台NameNode, 2台DataNode
Role IP Type System
NameNode 192.168.144.121 Master CentOS
DataNode 192.168.144.119 Slave CentOS
DataNode 192.168.144.120 Slave CentOS

三. 配置流程

原则:三台机器的配置保持一致就可以,下面具体描述NameNode主机的过程。

1. 安装JDK1.6 (略)

2. 下载Hadoop软件包,官方下载地址

http://hadoop.apache.org/releases.html#Download
解压至/export/servers/hadoop

特别注意:hadoop2.7版本以上不支持jdk1.6。
如果版本错误,启动运行时会发生java.lang.UnsupportedClassVersionError错误。
本文用jdk1.7.0_71这个版本。

3. 配置环境变量

打开配置文件:vim ~/.bash_profile

JAVA_HOME=/export/servers/jdk1.7.0_71/
HADOOP_HOME=/export/servers/hadoop/hadoop-2.6.5
export  PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin

生效配置文件:
source ~/.bash_profile

执行echo $HADOOP_HOME得到hadoop的目录,执行hadoop命令会有一系列的提示。

4. 在NameNode上修改hadoop配置文件

主要修改/export/servers/hadoop/hadoop-2.6.5/etc/hadoop目录下的配置文件。

4.1 NameNode IP和端口设置,配置core-site.xml

<property>
  <name>fs.default.name</name>
  <value>hdfs://192.168.144.121:9000/</value>
</property>

4.2 HDFS数据块副本等参数设置,配置hdfs-site.xml

<property>
  <name>dfs.name.dir</name>
  <value>/export/servers/hadoop/data/dfs.name.dir</value>
</property>

<property>
  <name>dfs.data.dir</name>
  <value>/export/servers/hadoop/data/dfs.data.dir</value>
</property>

<property>
  <name>dfs.permissions</name>
  <value>false</value>
</property>

<property>
  <name>dfs.replication</name>
  <value>2</value>
</property>

4.3 MapReduce 完成JobTracker IP和端口设置,配置 mapred-site.xml

<property>
  <name>mapred.job.tracker</name>
  <value>Master:9001</value>
</property>

4.4 Hadoop环境变量设置,配置hadoop-env.sh
将JAVA_HOME的值修改为真实有效的地址,如果不知道,请执行echo $JAVA_HOME 查看。

export JAVA_HOME=/export/servers/jdk1.7.0_71

4.5 完成datanode节点IP设置,配置 slaves
不存在slaves文件需要创建:vim slaves
192.168.144.119
192.168.144.120

5. 格式化NameNode

执行如下命令做格式化操作,每次如果有修改conf,最好做一次格式化命令。
进入hadoop的bin目录,运行如下命令
./hadoop namenode -format
如果格式化成功,会返回一堆有关NameNode的启动信息,其中会有一句“…. has been successfully formatted”。

6. 复制hadoop系统到所有DataNode节点

将主NameNode节点安装好的Hadoop系统目录复制到每一个从DataNode节点上。
cd /export/servers/hadoop
scp -r hadoop-2.6.5 192.168.144.119:/export/servers/hadoop
scp -r hadoop-2.6.5 192.168.144.120:/export/servers/hadoop

7. 启动HDFS

进入sbin目录
./start-dfs.sh
如果启动遇到问题,请对NameNode或DataNode的日志进行查看,路径为/ export/servers/hadoop/ hadoop-2.6.5/logs,看看是否有Exception抛出。

这里提示需要输入密码,Hadoop的进程之间同信使用ssh方式,需要每次都要输入密码。为了实现自动化操作,需要配置ssh免密码登陆方式。

配置ssh免密码登陆方式:

通常Centos系统都默认安装SSH, 如果没有安装,请单独安装,yum install ssh
进入目录:cd ~/.ssh

生成一个密钥:ssh-keygen -t rsa
一路回车,不需要输入密码
执行该操作将在~/.ssh下生成id_rsa, id_rsa.pub文件,其中id_rsa.pub是公钥。

将该密钥追加写入到authorized_keys文件:cat id_rsa.pub >> authorized_keys

可以尝试用ssh登录本机,如果无需输入密码则配置成功。

如果想要免密访问其他机器,则需要将公钥id_rsa.pub追加到其他机器的authorized_keys中。
比较简单的方法是直接拷贝authorized_keys文件到其他机器的~/.ssh/目录上,注意文件权限必须是600.
然后就可以免密码登录其他机器了。

可能出现的错误:The authenticity of host ‘git (192.168.144.121)’ can’t be established.
修改/etc/ssh/ssh_config文件的配置,以后则不会再出现此问题
最后面添加:
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

8. 简单对HDFS进行试用

命令行方式:
用jps命令检查一下是否正常启动。
创建新目录:hadoop fs -mkdir /loginflow
列出文件目录:hadoop fs -ls /

可能会产生WARN信息:
util.NativeCodeLoader: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable
到lib/native目录下
ldd libhadoop.so
version `GLIBC_2.14’ not found (required by ./libhadoop.so),需要升级glibc。

浏览器方式:
在WEB页面下查看Hadoop工作情况:输入部署Hadoop服务器的IP:
NameNode web管理端: http://192.168.144.121:50070

附上hdfs常用端口号:
参数 描述 默认 配置文件 例子值
fs.default.name namenode namenode RPC交互端口 8020 core-site.xml hdfs://master:8020/
dfs.http.address NameNode web管理端口 50070 hdfs- site.xml 0.0.0.0:50070
dfs.datanode.address datanode 控制端口 50010 hdfs -site.xml 0.0.0.0:50010
dfs.datanode.ipc.address datanode的RPC服务器地址和端口 50020 hdfs-site.xml 0.0.0.0:50020
dfs.datanode.http.address datanode的HTTP服务器和端口 50075 hdfs-site.xml 0.0.0.0:50075

四. Java和C程序读写hdfs

1. Java代码:


2. C代码:

由于hadoop是用Java语言实现的,因此对于C语言,hadoop提供了基于jni的C语言API。它提供了libhdfs.so动态库,在 $HADOOP_HOME/lib/native/libhdfs.so中,libhdfs是线程安全的。
头文件是/include/hdfs.h。

#include <stdio.h>
#include <string.h>
#include "hdfs.h"

int main(int argc, char **argv) {
    hdfsFS fs = hdfsConnect("192.168.144.121", 9000); //default是连本地文件
    const char* writePath = "/export/wjloginflow/loginflow/20170807";
    hdfsFile writeFile = hdfsOpenFile(fs, writePath, O_WRONLY |O_CREAT, 0, 0, 0);
    if(!writeFile) {
        printf("Failed to open for writing!\n");
        return -1;
    }
    const char* buffer = "Hello, World!";
    tSize num_written_bytes = hdfsWrite(fs, writeFile, (void*)buffer, strlen(buffer)+1);
    if (hdfsFlush(fs, writeFile)) {
        printf("Failed to flush to hdfs\n");
        return -1;
    }
    printf("success to flush to hdfs\n");
    hdfsCloseFile(fs, writeFile);
}

Makefile文件:

OPT := -O0
DEBUG := -ggdb -DDEBUG -DENABLE_TRACE_LOG
CFLAGS := -Wno-non-virtual-dtor -W -Wall -Wno-unused-parameter -Wno-unused-variable -shared -fPIC $(DEBUG) $(OPT)

HADOOP_HOME = /export/servers/hadoop/hadoop-2.6.5
JRE_SO_HOME = /export/servers/jdk1.7.0_71/jre/lib/amd64/server

all:
    g++ $(CFLAGS) sample.cpp -o sample -I$(HADOOP_HOME)/include -L$(HADOOP_HOME)/lib/native -L$(JRE_SO_HOME) -lhdfs -ljvm

clean:
    rm -rf sample

然后可以登录192.168.144.120机器上查看文件是否写入,

bin/hadoop fs -ls /export/wjloginflow/loginflow/