引用:Java操作HDFS - 玄同太子 - 博客園 (cnblogs.com) CentOS安裝Hadoop - 玄同太子 - 博客園 (cnblogs.com) HDFS完全分布式搭建過程_背着夢的幸存者-CSDN博客_hdfs搭建
一
CentOS安裝Hadoop(偽分布式)
Hadoop的核心由3個部分組成:
HDFS: Hadoop Distributed File System,分布式文件系統,hdfs還可以再細分為NameNode、SecondaryNameNode、DataNode。
YARN: Yet Another Resource Negotiator,資源管理調度系統
Mapreduce:分布式運算框架
1、軟件與環境
環境:CentOS-7-x86_64-Minimal-1810
hadoop版本:jdk-8u221-linux-x64.tar.gz,下載地址:https://www.apache.org/dist/hadoop/common/ Index of /hadoop (apache.org)
jdk版本:jdk-8u221-linux-x64.tar.gz,hadoop只支持jdk7和jdk8,不支持jdk11
2、解壓安裝文件
通過ftp等工具講安裝包上傳到服務器上,並解壓到/usr/local/目錄
cd /usr/local/ tar -zxvf /var/ftp/pub/jdk-8u221-linux-x64.tar.gz tar -zxvf /var/ftp/pub/hadoop-2.9.2.tar.gz
3、配置JDK
修改${HADOOP_HMOE}/etc/hadoop/hadoop-env.sh文件,修改JAVA_HOME配置(也可以修改/etc/profile文件,增加JAVA_HOME配置)。
vi etc/hadoop/hadoop-env.sh // 修改為 export JAVA_HOME=/usr/local/jdk1.8.0_221/
4、設置偽分布模式(Pseudo-Distributed Operation)
修改etc/hadoop/core-site.xml文件,增加配置(fs.defaultFS:默認文件系統名稱):
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
//不要端口沖突,9000是一個常用端口,建議 netstat -tnpl 查看端口占用,此外localhost要改為主機對外ip,不然外網可能無法訪問端口
</property>
</configuration>
修改etc/hadoop/hdfs-site.xml文件,增加配置(dfs.replication:文件副本數):
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
//不配置的話可能50070訪問不了
<property>
<name>dfs.namenode.http.address</name>
<value>slave1:50070</value>
</property>
</configuration>
5、設置主機允許無密碼SSH鏈接
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa // 創建公鑰私鑰對 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys // chmod 0600 ~/.ssh/authorized_keys // 設置權限,owner有讀寫權限,group和other無權限
6、格式化文件系統
bin/hdfs namenode -format
7、啟動NameNode和DataNode進程(啟動hdfs)
./sbin/start-dfs.sh // 啟動NameNode和DataNode進程 ./sbin/stop-dfs.sh // 關閉NameNode和DataNode進程
輸入地址:http://192.168.114.135:50070,可查看HDFS

8、 啟動YARN
./sbin/start-yarn.sh ./sbin/stop-yarn.sh
輸入地址:http://192.168.114.135:8088/,可查看YARN

輸入地址:http://192.168.0.25:50070/explorer.html,可查看hfds

二
HDFS完全分布式搭建
因為條件限制,HDFS安裝在多個安裝在同一系統內的centos7虛擬機上,為了方便(只是搭建用於測試一個api),並沒有改為靜態ip。
1 前期准備
四個安裝在同一機子上的虛擬機,互相可以ping通,我的IP地址依次是192.168.31.128 192.168.31.129 192.168.31.130 192.168.31.131
修改每一台機器的host,並安裝jdk,hdoop(hdfs,暫時不啟動),這里可以先在一台虛擬機上進行所有步驟,然后clone三個。
(1)關閉防火牆,修改host
vim /etc/hosts
在后面添加
192.168.31.128 node1 192.168.31.129 node2 192.168.31.130 node3 192.168.31.131 node4
(2) 安裝jdk,並配置
(3) 解壓hadoop壓縮包,並配置hdoop的path
我依舊吧jdk放在了 /usr/local/java 里,把hdoop解壓在了 /usr/local/hadoop-2.10.1 里,
然后修改 /etc/profile /root/.bashrc
在尾部插入下面的代碼並source
export HADOOP_HOME=/opt/hadoop/hadoop-2.7.5
export JAVA_HOME=/opt/java/jdk1.8.0_151
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
2 時間同步
在每一台機器上輸入
①各個節點安裝ntp命令 yum install ntp
②上網查找最新的時間服務器,這里使用阿里雲時間服務器 ntp1.aliyun.com(本步無需輸入命令)
③同步時間 ntpdate ntp1.aliyun.com
3 配置免密登錄
node01->node01 node01->node02 node01->node03 node01->node04
①所有節點均要執行 ssh-keygen -t rsa -P ‘’ -f ~/.ssh/id_rsa
②以下命令只在node01節點執行,將node01的公鑰加入到其他節點的白名單中
ssh-copy-id -i ~/.ssh/id_rsa.pub root@node01
ssh-copy-id -i ~/.ssh/id_rsa.pub root@node02
ssh-copy-id -i ~/.ssh/id_rsa.pub root@node03
ssh-copy-id -i ~/.ssh/id_rsa.pub root@node04
4 修改hdfs-site.xml配置文件(4、5、6、7步均在node01上操作)注意是在hdoop解壓的文件夾內的etc/hdoop 里
vim /usr/local/hadoop-2.10.1/etc/hdoop/hdfs-site.xml 插在兩個<configuration>中間
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node02:50090</value>
</property>
5 修改core-site.xml配置文件
與上面的配置文件在同一目錄 vim /usr/local/hadoop-2.10.1/etc/hdoop/core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://node01:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/abc/hadoop/cluster</value>
</property>
6 修改slaves配置文件
在同一目錄 ,修改,添加節點
vim /usr/local/hadoop-2.10.1/etc/hdoop/slaves
node02
node03
node04
7 將修改好的文件分發到其他節點所在虛擬機里
此處,只需要分發 /usr/local/hadoop-2.10.1/etc/hdoop 文件夾即可,終端路徑是/usr/local/hadoop-2.10.1/etc時
scp -r hadoop root@node02:/usr/local/hadoop-2.10.1/etc
scp -r hadoop root@node03:/usr/local/hadoop-2.10.1/etc
scp -r hadoop root@node04:/usr/local/hadoop-2.10.1/etc
可以查看一下其他虛擬機,達到同步即可,這一步可能要輸入密碼秘鑰
8 在node01里啟動hdfs
(1)將所有的HDFS相關的進程關閉
killall java
(2) 格式化NameNode(創建目錄以及文件)在node01節點執行()
bin/hdfs namenode -format
(3)啟動NameNode和DataNode進程(啟動hdfs)
./sbin/start-dfs.sh // 啟動NameNode和DataNode進程 ./sbin/stop-dfs.sh // 關閉NameNode和DataNode進程
訪問 192.168.31.128:50070/dfshealth.html#tab-overview

三
Java操作HDFS
◆下載winutils.exe和hadoop.dll
在windows平台下操作hadoop必須使用winutils.exe和hadoop.dll,下載地址:https://github.com/steveloughran/winutils,本文測試使用的是hadoop-2.8.3,雖然這個版本與服務器安裝的版本不一致 ,但經測試是有效的。
配置環境變量:

或者在Java代碼中設置:
System.setProperty("hadoop.home.dir", "D:\\hadoop-2.8.3");
◆修改core-site.xml配置
設置fs.defaultFS參數值為hdfs://主機IP:9000
<property>
<name>fs.defaultFS</name>
<value>hdfs://192.168.107.141:9000</value>
</property>
◆pom.xml,盡量讓hadoop-client版本與安裝的hadoop版本一致
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zhi.test</groupId>
<artifactId>hadoop-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>hadoop-test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hadoop.version>2.9.2</hadoop.version>
<!-- Logger -->
<lg4j2.version>2.12.1</lg4j2.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Logger(log4j2) -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${lg4j2.version}</version>
</dependency>
<!-- Log4j 1.x API Bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>${lg4j2.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
◆Java代碼
package com.zhi.test.hadoop;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* HDFS測試
*
* @author zhi
* @since 2019年9月10日18:28:24
*
*/
public class HadoopTest {
private Logger logger = LogManager.getLogger(this.getClass());
private FileSystem fileSystem = null;
@Before
public void before() throws Exception {
// System.setProperty("hadoop.home.dir", "D:\\hadoop-2.8.3");
Configuration configuration = new Configuration();
fileSystem = FileSystem.get(new URI("hdfs://192.168.107.141:9000"), configuration, "root");
}
@After
public void after() throws Exception {
if (fileSystem != null) {
fileSystem.close();
}
}
/**
* 創建文件夾
*/
@Test
public void mkdir() {
try {
boolean result = fileSystem.mkdirs(new Path("/test"));
logger.info("創建文件夾結果:{}", result);
} catch (IllegalArgumentException | IOException e) {
logger.error("創建文件夾出錯", e);
}
}
/**
* 上傳文件
*/
@Test
public void uploadFile() {
String fileName = "hadoop.txt";
InputStream input = null;
OutputStream output = null;
try {
input = new FileInputStream("F:\\" + fileName);
output = fileSystem.create(new Path("/test/" + fileName));
IOUtils.copyBytes(input, output, 4096, true);
logger.error("上傳文件成功");
} catch (IllegalArgumentException | IOException e) {
logger.error("上傳文件出錯", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
}
}
if (output != null) {
try {
output.close();
} catch (IOException e) {
}
}
}
}
/**
* 下載文件
*/
@Test
public void downFile() {
String fileName = "hadoop.txt";
InputStream input = null;
OutputStream output = null;
try {
input = fileSystem.open(new Path("/test/" + fileName));
output = new FileOutputStream("F:\\down\\" + fileName);
IOUtils.copyBytes(input, output, 4096, true);
logger.error("下載文件成功");
} catch (IllegalArgumentException | IOException e) {
logger.error("下載文件出錯", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
}
}
if (output != null) {
try {
output.close();
} catch (IOException e) {
}
}
}
}
/**
* 刪除文件
*/
@Test
public void deleteFile() {
String fileName = "hadoop.txt";
try {
boolean result = fileSystem.delete(new Path("/test/" + fileName), true);
logger.info("刪除文件結果:{}", result);
} catch (IllegalArgumentException | IOException e) {
logger.error("刪除文件出錯", e);
}
}
/**
* 遍歷文件
*/
@Test
public void listFiles() {
try {
FileStatus[] statuses = fileSystem.listStatus(new Path("/"));
for (FileStatus file : statuses) {
logger.info("掃描到文件或目錄,名稱:{},是否為文件:{}", file.getPath().getName(), file.isFile());
}
} catch (IllegalArgumentException | IOException e) {
logger.error("遍歷文件出錯", e);
}
}
}
訪問http://192.168.107.141:50070/explorer.html#,可查看上傳的文件:

end

