Hadoop其一,介绍本地模式,伪分布模式和全分布搭建

目录

一、Hadoop介绍

二、HDFS的本地模式

三、伪分布模式

四、Hdfs中的shell命令

五、全分布搭建

六、使用Java代码操作HDFS

1、环境准备

2、单元测试(Junit)​编辑


一、Hadoop介绍

复制代码
Hadoop 分为三部分 :  Common、HDFS 、Yarn、MapReduce(有点过时了)
Hadoop生态圈:除了hadoop技术以外,还有hive、zookeeper、flume、sqoop、datax、azkaban等一系列技术。

Hadoop 是 道格·卡丁  本身他是Lucene的创始人。
Lucene 其实是一个jar包。

检索现在主流的是Solr以及ES(Elastic Search)。
比如现在每一个网站,都有一个检索的输入框,底层技术: Solr (稍微有点过时了) ,  ES (正在流行中)

首先面临的问题是:海量数据如何存储?
根据谷歌推出的三篇论文:
BigTable    -- HBase
GFS         -- HDFS
MapReduce   -- MapReduce

并将这些技术统称为 Hadoop (Logo 大象)。

Hadoop的三个版本:
Apache 版本(开源版本)    3.3.1 非常的新了
Cloudera 版本--商⽤版(道格·卡丁) CDH
Hortonworks  --hadoop的代码贡献者在这家公司非常的多。
现在各个大公司都在推出自己的大数据平台--> 大数据平台开发工程师
DataLight  --> 国产的CDH平台

二、HDFS的本地模式

hdfs: 分布式文件管理系统

海量数据存储的终极解决方案:整出来一个平台,这个平台的服务器可以无限扩展。

HDFS : 解决海量数据的存储问题 1p = 1024 T

Yarn : 计算的资源基础,所有的MR任务需要运行在Yarn上。

MapReduce:解决计算问题,它是一个计算框架(需要写代码的)

思考一个问题:

淘宝平台:拥有海量商户,每一个商户都有很多商品,每一个商品需要上传很多照片,照片得高清,一张照片5M左右。淘宝如何解决海量图片的储存问题?-- 淘宝拥有一个技术 FastDFS,搭建一个图片集群,这个集群中的服务器,可以无限拓展。而且一张照片存3份。

人类的思想拓展非常快,数据存储在哪里是安全的?任何一家公司都不靠谱,政府不靠谱。全人类最靠谱,能不能将全人类的硬盘全部连起来,变成一个大硬盘。假如一个人贡献自己的硬盘,假如我在你的电脑上放了数据,我就会给你奖励。假如你使用了别人的硬盘,需要付费。 --国家定义为基础设施。

使用虚拟货币结算,而且只支持 fil 这个币。

HDFS三种模式:本地模式,伪分布模式,全分布模式

复制代码
HDFS-- 分布式文件存储系统
Fil币挖矿

FastDFS(阿里巴巴)
原理都是一样的。
都是将多台电脑,硬盘组合在一起,形成一个文件存储系统,任何人都可以上传下载文件到这个平台上,数据自动备份,自动容灾。
如果文件系统空间不够了,直接添加电脑即可,完美对接之前的服务器。
如果中间服务器坏掉了,也不影响数据的完整性。

配置:

使用一下hadoop这个软件(案例WordCount):

复制代码
词频统计就是我们大数据中的HelloWorld!

在 /home 下创建了一个文件 wc.txt   命令: touch wc.txt

需要统计的词如下:
hello world spark flink
hello cfxj 2202 laolv
hello suibian suibian hello

接着使用自动的wordCount工具进行统计:
hadoop jar /opt/installs/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar wordcount /home/wc.txt /home/output

hadoop jar   执行某个jar包(其实就是java代码)

/opt/installs/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar  这个是jar的地址

/home/wc.txt   要统计的文件
/home/output   统计结果放哪里

如果统计的结果文件夹已经存在,会报错。

上面总结一下:

复制代码
数据在本地磁盘上  /home/wc.txt
计算的结果也是在本地磁盘上 /home/ouput

案例二:PI的计算

复制代码
hadoop jar /opt/installs/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar pi 10 100

10 代表10个任务
100 代表的是100次/每个任务

三、伪分布模式

伪分布:按照分布式的步骤搭建,但是呢,服务器只有一台。

只能用于开发、和学习用。

复制代码
比如我想搭建一个集群,将集群中的所有磁盘连接在一起形成一个云端的hdfs.
但是公司就买了一台服务器。所以搭建出来的就是伪分布模式。
伪分布的意思:按照全分布的步骤搭建的集群,但是linux服务器只有一台。

进行搭建之前的一些准备工作:

配置开始:

位置: /opt/installs/hadoop/etc/hadoop

以下圈住的都是重要的文件:

复制代码
<configuration>
  <!-- 设置namenode节点 -->
  <!-- 注意: hadoop1.x时代默认端⼝9000 hadoop2.x时代默认端⼝8020 hadoop3.x时 代默认端⼝ 9820 -->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://bigdata01:9820</value>
  </property>
  
  <!-- hdfs的基础路径,被其他属性所依赖的⼀个基础路径 -->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/installs/hadoop/tmp</value>
  </property>
</configuration>

<configuration>
    <property>
        <!--备份数量-->
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <!--secondarynamenode守护进程的http地址:主机名和端⼝号。参考守护进程布局 -->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>bigdata01:9868</value>
    </property>
    <!-- namenode守护进程的http地址:主机名和端⼝号。参考守护进程布局 -->
    <property>
        <name>dfs.namenode.http-address</name>
        <value>bigdata01:9870</value>
    </property>
</configuration>

export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

export JAVA_HOME=/opt/installs/jdk

修改workers 文件:

复制代码
vi workers
修改里面的内容为: bigdata01 保存

对整个集群记性namenode格式化:

复制代码
hdfs namenode -format

格式化其实就是创建了一系列的文件夹:

这个文件夹的名字是 logs tmp

假如你想格式化第二次,需要先删除这两个文件夹,然后再格式化

启动集群:

复制代码
start-dfs.sh

通过网址访问hdfs集群:

http://192.168.233.128:9870/

如果访问不到:检查防火墙是否关闭。

测试一下这个hdfs的文件系统:

目前搭建的这个到底是hdfs的伪分布还是hadoop伪分布?

答案是 hdfs的伪分布,但是hdfs 也是hadoop的一部分。

真正的hadoop伪分布还需要配置yarn 才算真正的伪分布。

使用这个文件系统:

复制代码
1、将要统计的内容上传至hdfs文件系统
   hdfs dfs -mkdir /home
   hdfs dfs -put /home/wc.txt /home
2、使用wordcount统计wc.txt

hadoop jar /opt/installs/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar wordcount /home/wc.txt /home/ouput

3、查看统计结果
hdfs dfs -cat /ouput/*

假如你的环境是伪分布式模式,那么本地模式直接被替换了,回不去了。

复制代码
此模式跟本地模式有何区别?
这两种方式,首选统计的代码都在本地,但是本地模式,数据和统计的结果都在本地。
伪分布模式,它的数据来源在 hdfs 上,统计结果也放在 hdfs上。

如果此时再执行以前的workcount就会报错,原因是以前是本地模式,现在是伪分布模式,伪分布模式,只会获取hdfs上的数据,将来的结果也放入到hdfs上,不会获取本地数据:

四、Hdfs中的shell命令

假如你想通过web界面查看一个文件的内容,点击报错:

复制代码
Couldn't preview the file. NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://bigdata01:9864/webhdfs/v1/output/part-r-00000?op=OPEN&namenoderpcaddress=bigdata01:9820&offset=0&_=1692068863115'.

默认是要报错的,因为这是一种安全机制,可以修改一下:
在hdfs-site.xml 中添加如下配置:

<property>
    <name>dfs.webhdfs.enabled</name>
    <value>true</value>
</property>

在windows本机,修改hosts映射关系。
C:\Windows\System32\drivers\etc\hosts
修改内容如下:
192.168.233.128 bigdata01

关于hdfs文件系统,有三种操作方式:
1、图形化界面    比如 http://IP地址:9870
2、shell命令操作  比如 hdfs dfs -put 上传  -cat 查看
3、通过java代码操作

shell命令操作:东西特别的多,只学其中一些。

复制代码
hdfs dfs -moveFromLocal 本地文件  hdfs的路径   
跟put上传不一样的是,move结束后,本地文件会消失

hdfs dfs -get hdfs的路径 本地文件      此操作要谨慎

hdfs dfs -cp /log.txt /ouput  将hdfs上的一个文件拷贝到另一个文件夹
hdfs dfs -chmod 777 /wc.txt   hdfs上的文件也可以赋权限

五、全分布搭建

全分布模式:必须至少有三台以上的Linux。

前期准备工作:

1、准备三台服务器

目前有两台,克隆第二台(因为第二台没有安装mysql), 克隆结束后,进行修复操作

1) 修改IP 2) 修改主机名 3)修改映射文件hosts

检查是否满足条件:

环境准备⼯作:

1、安装了jdk

2、设置host映射

192.168.32.128 bigdata01

192.168.32.129 bigdata02

192.168.32.130 bigdata03

远程拷贝:

scp -r /etc/hosts root@bigdata02:/etc/

scp -r /etc/hosts root@bigdata03:/etc/

3、免密登录

bigdata01 免密登录到bigdata01 bigdata02 bigdata03

ssh-copy-id bigdata03

4、第一台安装了hadoop

5、关闭了防⽕墙

systemctl status firewalld

6、修改linux的⼀个安全机制

vi /etc/selinux/config

修改⾥⾯的 SELINUX=disabled

一定要确保三台电脑上的hosts文件都是:

复制代码
192.168.32.128 bigdata01
192.168.32.129 bigdata02
192.168.32.130 bigdata03

修改一台,长拷贝到其他两台:

复制代码
scp -r /etc/hosts root@bigdata01:/etc
scp -r /etc/hosts root@bigdata02:/etc

2、检查各项内容是否到位

如果以前安装的有伪分布模式,服务要关闭。 stop-dfs.sh

3、修改bigdata01配置文件

路径:/opt/installs/hadoop/etc/hadoop

跟伪分布一样:不需要修改

复制代码
<configuration>
    <!-- 设置namenode节点 -->
    <!-- 注意: hadoop1.x时代默认端⼝9000 hadoop2.x时代默认端⼝8020 hadoop3.x时 代默认端⼝ 9820 -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://bigdata01:9820</value>
    </property>
    
    <!-- hdfs的基础路径,被其他属性所依赖的⼀个基础路径 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/opt/installs/hadoop/tmp</value>
    </property>
</configuration>

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!--secondarynamenode守护进程的http地址:主机名和端⼝号。参考守护进程布局 -->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>bigdata02:9868</value>
    </property>
    <!-- namenode守护进程的http地址:主机名和端⼝号。参考守护进程布局 -->
    <property>
        <name>dfs.namenode.http-address</name>
        <value>bigdata01:9870</value>
    </property>
</configuration>

跟伪分布一样,不需要修改

复制代码
export JAVA_HOME=/opt/installs/jdk
# Hadoop3中,需要添加如下配置,设置启动集群⻆⾊的⽤户是谁
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

修改workers

复制代码
bigdata01
bigdata02
bigdata03

修改完了第一台的配置文件,开始分发到其他两台上去。

假如以前没有将bigdata01上的hadoop 拷贝给 02 和 03

那么就远程拷贝:

scp -r /opt/installs/hadoop/ bigdata02:/opt/installs/

scp -r /opt/installs/hadoop/ bigdata03:/opt/installs/

如果以前已经拷贝过了,只需要拷贝刚修改过的配置文件即可:

只需要复制配置文件即可

scp -r /opt/installs/hadoop/etc/hadoop/ bigdata02:/opt/installs/hadoop/etc/

scp -r /opt/installs/hadoop/etc/hadoop/ bigdata03:/opt/installs/hadoop/etc/

复制代码
拷贝环境变量:
scp -r /etc/profile root@bigdata02:/etc/
scp -r /etc/profile root@bigdata03:/etc/

在02 和 03 上刷新环境变量  source /etc/profile

4、格式化namenode

复制代码
hdfs namenode -format

5、启动hdfs

复制代码
只在第一台电脑上启动
start-dfs.sh

启动后jps,看到

|-----------|-------------------|-----------|
| bigdata01 | bigdata02 | bigdata03 |
| namenode | secondaryNameNode | x |
| datanode | datanode | datanode |

web访问:namenode 在哪一台,就访问哪一台。http://bigdata01:9870

总结:

1、start-dfs.sh 在第一台启动,不意味着只使用了第一台,而是启动了集群。

stop-dfs.sh 其实是关闭了集群

2、一台服务器关闭后再启动,上面的服务是需要重新启动的。

这个时候可以先停止集群,再启动即可。也可以使用单独的命令,启动某一个服务。

复制代码
hadoop-daemon.sh start namenode				# 只开启NameNode
hadoop-daemon.sh start secondarynamenode	# 只开启SecondaryNameNode
hadoop-daemon.sh start datanode				# 只开启DataNode

hadoop-daemon.sh stop namenode				# 只关闭NameNode
hadoop-daemon.sh stop secondarynamenode		# 只关闭SecondaryNameNode
hadoop-daemon.sh stop datanode				# 只关闭DataNode

3、namenode 格式化有啥用

相当于在整个集群中,进行了初始化,初始化其实就是创建文件夹。创建了什么文件夹:

复制代码
logs  tmp
你的hadoop安装目录下。

六、使用Java代码操作HDFS

上传文件,创建文件夹,删除文件,下载等等

1、环境准备

1)解压hadoop的安装包

2)配置环境变量

复制代码
;%HADOOP_HOME%\bin;%HADOOP_HOME%\sbin;

如果你出现了如下错误:

他的意思是你的java_home ,需要修改一个地方:

复制代码
在 /etc/hadoop 下的  hadoop-env.cmd 中大约25行

set JAVA_HOME=C:\PROGRA~1\Java\jdk1.8.0_144

一定确保你的jdk路径是正确的。  
Program Files  == PROGRA~1

黑窗口先关闭,再打开即可。

最后一项:

粘贴一个补丁文件:

另外,假如你的 java 版本有问题,也会报这个错误,比如我们需要 64 位的操作软件,你安装了一个 32 位的,请卸载 jdk,并重新安装和配置环境变量。

2、单元测试(Junit)

类似于Main方法。

首先需要导入Junit包:

Welcome to Apache Maven -- Maven

复制代码
<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

第二步:写单元测试代码

最好写在test 文件夹下(专门写测试的文件夹)

复制代码
单元测试方法:
1、方法上必须有@Test注解
2、方法必须是public void 开头
3、方法没有参数
4、不要将类名写成Test,后果自负



import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestUnit {
    
    @Before  // 每次单元测试方法执行前都会执行该方法  该方法一般存放一些初始化的代码
    public void init(){
        System.out.println("我是开始代码");
    }
    
    @After// 每次单元测试方法执行后都会执行该方法  该方法一般都是存放一些连接关闭等收尾工作
    public void destory(){
        System.out.println("我是结束代码");
    }
    
    @Test // 该方法即一个单元测试方法,这个方法是一个独立的方法,类似于Main方法。
    public void testA(){
        System.out.println("Hello World!");
    }
    
    
    @Test
    public void testB(){
        System.out.println("Hello World!");
    }
}

以下是通过chatgpt帮我生成的代码:

复制代码
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class MyUnitTest {

    @Before
    public void setUp() {
        // 在每个测试方法之前执行的准备工作
        System.out.println("setUp() method called");
    }

    @After
    public void tearDown() {
        // 在每个测试方法之后执行的清理工作
        System.out.println("tearDown() method called");
    }

    @Test
    public void testMethod1() {
        // 测试方法1
        System.out.println("testMethod1() called");
        // 添加测试逻辑和断言
    }

    @Test
    public void testMethod2() {
        // 测试方法2
        System.out.println("testMethod2() called");
        // 添加测试逻辑和断言
    }
}

第三步:使用java代码连接hdfs

获取hdfs连接的四种方法:

首先导入需要的jar包:

复制代码
      <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.3.1</version>
        </dependency>

代码演示:

复制代码
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.junit.Test;

import java.io.IOException;
import java.net.URI;


public class Demo01 {

    @Test
    public void test01() throws IOException {

        // 配置的意思
        Configuration configuration = new Configuration();
        // hdfs的连接地址
        configuration.set("fs.defaultFS","hdfs://192.168.32.128:9820");
        FileSystem fileSystem = FileSystem.get(configuration);
        System.out.println(fileSystem);
    }

    @Test
    public void test02() throws Exception {
        //  URL  和  URI
        //  URL  和  URI
        //  URL = 中华人民共和国
        // 指的是互联网上比较具体的第一个内容,地址
        //  URI = 共和国   员工的编号9527
        //  cookie  session
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.32.128:9820"), new Configuration());
        System.out.println(fileSystem);
    }

    @Test
    public void test03() throws Exception {
        // 配置的意思
        Configuration configuration = new Configuration();
        // hdfs的连接地址
        configuration.set("fs.defaultFS","hdfs://192.168.32.128:9820");
        FileSystem fileSystem = FileSystem.newInstance(configuration);
        System.out.println(fileSystem);
    }

    @Test
    public void test04() throws Exception {
        // 配置的意思
        Configuration configuration = new Configuration();

        FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://192.168.32.128:9820"),configuration);
        System.out.println(fileSystem);
    }
}

通过代码上传一个文件到hdfs上。

复制代码
public class Demo02 {

    @Test
    public void testUpload() throws Exception {
        System.setProperty("HADOOP_USER_NAME","root");
        Configuration configuration = new Configuration();
        configuration.set("fs.defaultFS","hdfs://192.168.32.128:9820");
        FileSystem fileSystem = FileSystem.get(configuration);
        Path localPath = new Path("D:\\a.txt");
        Path hdfsPath = new Path("/");
        fileSystem.copyFromLocalFile(localPath,hdfsPath);
        System.out.println("上传成功!");
    }
}

System.setProperty("HADOOP_USER_NAME","root");
复制代码
package com.bigdata;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

public class HdfsUtils {

    private FileSystem fileSystem;

    @Before
    public void setUp() throws IOException {
        System.setProperty("HADOOP_USER_NAME","root");
        // 在每个测试方法之前执行的准备工作
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://bigdata01:9820"); // 设置 HDFS 地址
        fileSystem = FileSystem.get(conf);

    }

    @After
    public void tearDown() throws IOException {
        // 在每个测试方法之后执行的清理工作
        fileSystem.close();
    }

    @Test
    public void testUploadFile() throws IOException {
        String localFilePath = "C:\\Users\\admin\\Desktop\\edip";
        String hdfsFilePath = "/";
        fileSystem.copyFromLocalFile(new Path(localFilePath), new Path(hdfsFilePath));

    }

    @Test
    public void testCreateFile() throws IOException {
        String hdfsFilePath = "/newfile.txt";
        fileSystem.createNewFile(new Path(hdfsFilePath));
    }

    @Test
    public void testDownloadFile() throws IOException {
        String hdfsFilePath = "/newfile.txt";
        String localFilePath = "C:\\Users\\admin\\Desktop\\file.txt";
        fileSystem.copyToLocalFile(new Path(hdfsFilePath), new Path(localFilePath));
    }

    @Test
    public void testDeleteFile() throws IOException {
        String hdfsFilePath = "/newfile.txt";
        fileSystem.delete(new Path(hdfsFilePath), false);
    }

    @Test
    public void testMkDir() throws IOException {
        fileSystem.mkdirs(new Path("/input"));
        System.out.println("创建文件夹成功");
    }

    @Test
    public void testRename() throws IOException {
        fileSystem.rename(new Path("/edip"),new Path("/aaa.txt"));

    }

    // 打印 一个目录下的所有文件,包含文件夹中的文件
    @Test
    public void testLs() throws Exception {
        // rm -r
        RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
        while(iterator.hasNext()){
            LocatedFileStatus locatedFileStatus = iterator.next();
            System.out.println(locatedFileStatus.getPath().getName());
        }
    }

    // 返回当前目录下的所有文件以及文件夹
    @Test
    public void testList2() throws Exception {
        FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/"));
        for (FileStatus fileStatus : fileStatuses) {
            System.out.println(fileStatus.getPath().getName());

        }
    }
}

下载中如果报错了:

需要将hadoop.dll 拷贝到 C:\windows\system32 这个文件夹下一份。

相关推荐
蓝莓味柯基4 分钟前
DevOps:概念与学习路径
运维·学习·devops
24k小善10 分钟前
FlinkSql入门与实践
java·大数据·flink·云计算
Leo.yuan11 分钟前
产销协同的作用是什么?又如何对各部门发挥作用?
大数据·信息可视化·数据分析·需求分析·企业数字化
帅帅的Python18 分钟前
2015-2023 各省 GDP 数据,用QuickBI 进行数据可视化——堆叠图!
大数据·人工智能
FJW02081419 分钟前
【Linux】web服务器的部署和优化
linux·运维·服务器·rhce
平生不喜凡桃李38 分钟前
Linux 进程控制
linux·运维·服务器
数据与人工智能律师1 小时前
正确应对监管部门的数据安全审查
大数据·网络·数据库·人工智能·区块链
鱼与宇1 小时前
Linux常用命令
linux·运维·服务器
小南家的青蛙1 小时前
lspci的资料
linux·运维·服务器
敖云岚1 小时前
【那些年踩过的坑】Docker换源加速详细教程(截至2025年4月)
运维·docker·容器