实战HDFS
环境:全分布模式hadoop集群,eclipse
启动集群
先在仓库中拉取上一次配置好的镜像
sudo docker pull 3213777803/newuhadoop
然后就是DNS解析
sudo docker network create --driver=bridge hadoop
启动
第一条命令启动的是 h01
是做 master 节点的,所以暴露了端口,以供访问 web 页面
sudo docker run -it --network hadoop -h "h01" --name "h01" -p 9870:9870 -p 8088:8088 3213777803/newuhadoop /bin/bash
如果出现
Error response from daemon: Conflict. The container name "/h01" is already in use by container 0d1ae3a1611a6b5669daedb53f6dc8706e100d726004c218f1910873afd2377c. You have to remove (or rename) that container to be able to reuse that name..
See '/usr/bin/docker-current run --help'.
使用
docker rm 0d1ae3a1611a6b5669daedb53f6dc8706e100d726004c218f1910873afd2377c(这里的ID可能会变化)
然后重复
sudo docker run -it --network hadoop -h "h01" --name "h01" -p 9870:9870 -p 8088:8088 3213777803/newuhadoop /bin/bash
其余的四条命令就是几乎一样的了
sudo docker run -it --network hadoop -h "h02" --name "h02" 3213777803/newuhadoop /bin/bash
sudo docker run -it --network hadoop -h "h03" --name "h03" 3213777803/newuhadoop /bin/bash
sudo docker run -it --network hadoop -h "h04" --name "h04" 3213777803/newuhadoop /bin/bash
sudo docker run -it --network hadoop -h "h05" --name "h05" 3213777803/newuhadoop /bin/bash
接下来,在 h01
主机中,启动 Haddop 集群
先不登录
#不要登录
ssh h01
先进行格式化操作
root@h01:/usr/local/hadoop/bin# ./hadoop namenode -format
进入 hadoop 的 sbin 目录
root@h01:/# cd /usr/local/hadoop/sbin/
root@h01:/usr/local/hadoop/sbin#
启动
root@h01:/usr/local/hadoop/sbin# ./start-all.sh
这时候可以登录了
访问本机的 8088 与 9870 端口就可以看到监控信息了
127.0.0.1:8088

练习HDFS Shell的文件系统命令和系统管理命令
- 文件系统命令
#类似linux,命令入口是hadoop fs,全称是hadoop fs [generic options]
#或者是hdfs dfs [generic options]区别是前者可以操作任何文件系统,后者针对HDFS文件系统
#ls:显示
hadoop fs -ls <path>
#du 显示文件大小
hadoop fs -du <path>
#mv 移动
hadoop fs -mv <src><dst>
#cp 复制
hadoop fs -cp <src><dst>
#rm 删除
hadoop fs -rm <path>
#put 将本地文件推送到HDFS中
hadoop fs -put <localsrc> ...<dst>
#cat 输出
hadoop fs -cat <path>
#mkdir 建一个文件夹
hadoop fs -mkdir <path>
#touchz 创建一个文件
hadoop fs -touchz <path>
- 系统管理命令
#入口是hdfs dfsadmin
#进入安全模式
hdfs dfsadmin -safemode enter
#离开安全模式
hdfs dfsadmin -sfaemode leave
#关闭某个datanode节点
hdfs dfsadmin -decommission datanodename
#终结升级操作
hdfs dfsadmin -finalizeUpgrade
#查看升级操作状态
hdfs dfsadmin -upgradeProcess status
当你准备敲命令时不出意外的话会出现意外
WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete.
Exception in thread "main" java.lang.RuntimeException: core-site.xml not found
# 在/etc/profile文件中
#将HADOOP_CONF_DIR修改成自己的Hadoop目录,例如
export HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop
#如果有两个HADOOP_CONF_DIR,删除第二个,或者两个都修改
搭建eclipse
这里涉及到一个问题构建一个 UI 应用程序并将其部署为 Docker 容器中,怎么在 Docker 容器内运行应用程序时在本地计算机上显示用户界面。你需要将本地 Linux 机器的 X11 套接字转发到 Docker Container 以供其直接使用。 除此之外,还需要转发名为 display 的环境变量。
拿火狐来举个例子
1.创建dockerfile
FROM ubuntu:latest
RUN apt-get -y update
RUN apt-get -y install firefox
RUN apt-get -y install xauth
EXPOSE 8887
CMD firefox
上面的 dockerfile 包含创建 Ubuntu 基础映像、在其上运行 apt 更新、安装 Xauth 和 Firefox 的指令序列。 然后它会公开端口 8887 并运行 Firefox。 Xauth 只允许 Docker 容器访问显示服务器。
2.复制Cookie连接X Server Displays
在本地计算机上,使用以下命令获取 cookie 值。
xauth list
#复制一个像这样的
<username>/unix: MIT-MAGIC-COOKIE-1 f1fa006c1e51fa8386209f85c57947c4
- 构建 Docker 镜像
使用以下命令创建 Docker 映像。
docker build -t <image-name> .
- 运行 Docker 容器
使用 Docker run 命令运行 Docker 映像。
docker run -it --net=host -e DISPLAY -v /tmp/.X11-unix <image-name> bash
Docker 映像现在已构建并且容器已启动。 它会弹出一个交互式 Ubuntu bash。
5.需要使用以下命令添加在上一步中复制的 cookie。
xauth add <cookie>
xauth list
6.从 bash 运行 Firefox 实例
要运行 Firefox 实例,只需在 bash 中键入“firefox”。 会发现 Firefox 浏览器在您的本地计算机上弹出,即使它在 Docker 容器中运行。 使用类似的过程,可以在 Docker 容器中运行几乎任何用户界面应用程序并在本地计算机上访问它。
这里我已经搭建好了,链接放在下面
sudo docker pull 3213777803/eclipsehadoop:v1.0
sudo docker run -it -v /tmp/.x11-unix:/tmp/.x11-unix -e DISPLAY=unix$DISPLAY -e GDK_SCALE -e GDK_DPI_SCALE --net=host ID /bin/bash
然后就可以尽情的coding了
HDFS Java API编程
这里使用的环境需要说明一下,因为上面的镜像是把hadoop和eclipse安装到一起了。但是由于我机器的原因启动hadoop五个节点会很卡,所以我在云服务器上启动了hadoop,在本地启动了eclipse,然后使用eclipse连接到了hadoop上。镜像还使用那一个就行
安装eclipse插件
链接: https://pan.baidu.com/s/13cZVYYgzZLnG4hjwxOAU5Q 提取码: 6666 复制这段内容后打开百度网盘手机App,操作更方便哦
也可以直接拉取
docker pull 3213777803/eclipsehadoop:1.1
因为本人对eclipse不熟悉,这里我就使用了vscode,但是镜像里面有eclipse所以需要的可以自取,路径为/opt/eclipse
vscode连接hadoop
- 首先下载maven的插件
- 然后新建maven项目,选择maven-archetype-quickstart,版本随便选择,我选的是1.4
- 然后输入名称,比如com.hadoop
- 然后输入工程名称,比如hello_hadoop
- 然后一路回车就可
- 现在重点开始了,配置pom.xml
我们只需要在pom.xml添加依赖项就行。相关的依赖项的名称和版本号我们可以在Maven仓库的官网 https://mvnrepository.com/ 进行查询
一般来说,Hadoop项目需要引入hadoop-common、hadoop-hdfs、hadoop-client、hadoop-yarn-api这几个api,下面给出我的pox.xml,按照版本号修改即可
<?xml version="1.0" encoding="UTF-8"?>
<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.hadooptest</groupId>
<artifactId>hello_hadoop</artifactId>
<version>1.0-SNAPSHOT</version>
<name>hello_hadoop</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<hadoop.version>3.2.0</hadoop.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 导入hadoop依赖环境 -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-api</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
测试一下,
package com.hadooptest;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class readhdfs{
public static void main(String[] args) throws IOException, URISyntaxException {
Configuration configuration = new Configuration();
String hdfsPath = "hdfs://**IP**:9000";
FileSystem hdfs = FileSystem.get(new URI(hdfsPath), configuration);
String filePath = "/hdfstest/touchfile";
FSDataOutputStream create = hdfs.create(new Path(filePath));
System.out.println("Finish!");
}
}
常见的java api
// 创建目录
public void testMkdir() throws IOException {
fs.mkdirs(path("/path"));
fs.close();
}
// 移动,改名
public void testMvRename() throws IOException {
// 只是针对最后一级目录
fs.rename(path("/path/1"),new Path("/path1"));
fs.close();
}
//上传
public void testCopyFromLocal() throws IOException {
// 从本地复制到hdfs上,注意 一定要写完整目录
fs.copyFromLocalFile(path(temp+"copy.txt"),path("/copy.txt"));
fs.close();
}
// 下载
public void testCopyToLocal() throws IOException {
fs.copyToLocalFile(path("/copy.txt"),path(temp+"download_Hadoop_Windows.txt"));
fs.copyToLocalFile(false,path("/copy.txt"),path(temp+"download.txt"),true);
fs.close();
}