hadoop叢集搭建及程式設計實踐

prettyspider發表於2023-10-08

Hadoop叢集搭建

  1. 前期準備及JDK,hadoop安裝
  2. 設定主機名和新增主機對映
  3. 驗證連通性
  4. SSH無密碼登入
  5. 配置叢集/分散式環境
    1. 修改workers
    2. 修改檔案core-site.xml
    3. 修改hdfs-site.xml
    4. 修改mapred-site.xml
    5. 修改yarn-site.xml
  6. 分發到其他結點
  7. 格式化namenode
  8. 執行分散式例項
  9. java API與HDFS的程式設計
    1. 匯入Maven依賴
    2. 上傳本地檔案到HDFS檔案系統,將HDFS檔案系統中的檔案下載到本地並壓縮
    3. 根據HDFS檔案系統檢視學生是否提交作業
    4. 實現HDFS檔案系統指定資料夾內的檔案詞頻統計(手搓)

1.前期準備及JDK,hadoop安裝

1.1JDK的下載地址,hadoop下載地址

Java Downloads | Oracle 中國

選擇JDK8

清華映象源

選擇hadoop-3.3.5

注意點

檢視映象是32位還是64位

uname -m

當輸出為x86_64時,說明是64位,不是的就是32位,此時需要重新下載映象,32位不方便

1.2建立hadoop使用者

在安裝完linus映象之後,需要建立一個專門的"hadoop"使用者,這裡的使用者名稱為 “prettyspider"

首先按 ctrl+alt+t 開啟終端視窗,輸入如下命令建立新使用者 :

sudo useradd -m prettyspider -s /bin/bash

-m:將prettyspider作為使用者放入到使用者登入目錄

-s:指定使用者登入後使用的shell

為使用者設定登入密碼

sudo passwd prettyspider

為使用者新增管理員許可權

sudo adduser prettyspider sudo 

之後登出,登入"hadoop"使用者

1.3更新apt

sudo apt-get update

同步時間

sudo apt-get install ntpdata 
ntpdata -u time2.aliyun.com # 同步為阿里雲NTP伺服器

下載vim

sudo apt-get install vim

1.4安裝SSH、配置SSH無密碼登陸

sudo apt-get install openssh-server

安裝完之後,登入本機

ssh localhost

在下方提示中輸入yes,再根據提示輸入“hadoop"使用者的密碼

設定免密登入之前,一定要先用密碼登入一下

exit                           # 退出剛才的 ssh localhost
cd ~/.ssh/                     # 若沒有該目錄,請先執行一次ssh localhost
ssh-keygen -t rsa              # 會有提示,都按回車就可以
cat ./id_rsa.pub >> ./authorized_keys  # 加入授權

再使用ssh localhost登入

1.5配置遠端登入

遠端登入實現種類比較多,最輕便的是用vscode進行遠端登入,這裡使用的是MobaXterm軟體

可到官網中下載MobaXterm Xserver with SSH, telnet, RDP, VNC and X11 - Download (mobatek.net)

1.6JDK安裝

JDK版本為1.8.0_371

cd /usr/lib
sudo mkdir jvm #建立/usr/lib/jvm目錄用來存放JDK檔案
sudo tar -zxvf ~/jdk-8u371-linux-x64.tar.gz -C /usr/lib/jvm  #將

設定環境變數

cd ~
vim ~/.bashrc

在其中新增

export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_371  # 對應的版本號為jdk1.8.0_對應下載版本8u後面的數字
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

是配置檔案生效

source ~/.bashrc

檢視是否安裝成功

java -version

當出現下圖,表明安裝成功
image

1.7安裝hadoop

sudo tar -zxvf ~/hadoop-3.3.5.tar.gz -C /usr/local   # 解壓到/usr/local中
cd /usr/local/
sudo mv ./hadoop-3.3.5/ ./hadoop            # 將資料夾名改為hadoop
sudo chown -R prettyspider ./hadoop       # 修改檔案許可權,prettyspider為你的”hadoop"使用者名稱

檢視hadoop是否可用

cd /usr/local/hadoop
./bin/hadoop version

出現下圖,表示可用
image
依次配置3臺主機,對應的hadoop使用者名稱都為prettyspider

2.設定主機名和新增主機對映

2.1修改主機名

sudo vim /etc/hostname

3臺主機分別設定為 node01 node02 node03
重啟後,對應的主機名便會更改,如
image

2.2新增主機對映

在node01結點上

sudo vim /etc/hosts

新增主機的對映,設定成下圖
image
相應的其他結點也需要設定成上圖一樣

3.驗證連通性

用ping指令驗證連通性

ping node02 -c 3

連通成功的結果
image

4.SSH無密碼登入

在最開始配置的SSH是隻針對當前主機而言的SSH密匙,但是不利用叢集的操作,所以需要統一的配置SSH密匙

4.1在主節點上刪除原有SSH,並再建立一個統一的SSH密匙

cd ~/.ssh              # 如果沒有該目錄,先執行一次ssh localhost
rm ./id_rsa*           # 刪除之前生成的公匙(如果已經存在)
ssh-keygen -t rsa       # 執行該命令後,遇到提示資訊,一直按回車就可以

將生成的密匙新增到使用者的~/.ssh/authorized_keys,用於身份驗證

cat ./id_rsa.pub >> ./authorized_keys

將密匙傳入到對應的從結點上 傳輸到node02,node03

scp ~/.ssh/id_rsa.pub prettyspider@node02:/home/prettyspider/ # 此處@前後的名稱為自定義的使用者名稱和主機名 ,/home/後的為自定義的使用者名稱

在對應的結點上實現

mkdir ~/.ssh       # 如果不存在該資料夾需先建立,若已存在,則忽略本命令
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub    # 用完以後就可以刪掉

4.3檢視是否成功

ssh nod02

如下,表示成功
image

4.4為hadoop新增PATH

在~/.bashrc中新增

export PATH=$PATH:/usr/local/hadoop/bin:/usr/local/hadoop/sbin  # 指向對應hadoop路徑下的hadoop啟動資料夾的目錄

5.配置叢集/分散式環境

5.1進入/usr/local/hadoop/etc/hadoop

/usr/local/hadoop/etc/hadoop

5.2修改workers

workers的作用:配置為DateNode的主機名,如下,刪除localhost
image

5.3修改檔案core-site.xml

指定namenode的位置和設定hadoop檔案系統的基本配置image

5.4修改hdfs-site.xml

配置namenode和datanode存放檔案的基本路徑及配置副本的數量,最小值為3
image

5.5修改mapred-site.xml

image

5.6修改yarn-site.xml

設定resourceManager執行在哪臺機器上,設定NodeManager的通訊方式
image

6.分發到其他結點

6.1分發其他結點

cd /usr/local
sudo rm -r ./hadoop/tmp     # 刪除 Hadoop 臨時檔案
sudo rm -r ./hadoop/logs/*   # 刪除日誌檔案
tar -zcf ~/hadoop.master.tar.gz ./hadoop   # 先壓縮再複製
cd ~
scp ./hadoop.master.tar.gz node02:/home/prettyspider

其中
sudo rm -r ./hadoop/tmp # 刪除 Hadoop 臨時檔案
sudo rm -r ./hadoop/logs/* # 刪除日誌檔案
很重要,在後期配置hbase叢集時有用

6.2從節點解壓並設定使用者組

sudo rm -r /usr/local/hadoop    # 刪掉舊的(如果存在)
sudo tar -zxf ~/hadoop.master.tar.gz -C /usr/local
sudo chown -R prettyspider /usr/local/hadoop

7.格式化namenode

在從結點上完成了部署hadoop,在主節點上執行名稱結點的格式化

hdfs namenode -format

自此,hadoop叢集搭建完成,啟動叢集

start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver

image
hadoop叢集的規劃為
image

8.執行分散式例項

8.1建立HDFS上的使用者目錄

hdfs dfs -mkdir -p /user/prettyspider

hadoop使用者名稱是什麼,user後的使用者就是什麼

8.2建立input目錄

hdfs dfs -mkdir input # input資料夾預設在使用者目錄下,也就是prettyspider目錄下
hdfs dfs -put /usr/local/hadoop/etc/hadoop/*.xml input

8.3執行MapReduce作業

這個測試是用正規表示式獲取指定字首的任意長的欄位

hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.5.jar grep input output 'dfs[a-z.]+'

結果為
image

9.java API與HDFS的程式設計

1.匯入Maven依賴

<dependencies>
     <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.5</version>
    </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.7.5</version>
 </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.7.5</version>
 </dependency>
 <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.7.5</version>
 </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                    <!--   <verbal>true</verbal>-->
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <minimizeJar>true</minimizeJar>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

2.上傳本地檔案到HDFS檔案系統,將HDFS檔案系統中的檔案下載到本地並壓縮

1.建立ConnectionJavaBean類,用於登入HDFS

package com.prettyspider.hadoop;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;

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

/**
 * @author prettyspider
 * @ClassName Connection
 * @description: TODO
 * @date 2023/10/7 19:00
 * @Version V1.0
 */

public class Connection {
    // HDFS檔案系統web地址
    private String hdfsUrl;
    // hadoop使用者名稱
    private String hadoopHost;
    // 檔案系統物件
    private FileSystem fs;
    public Connection() {}

    public Connection(String hdfsUrl, String hadoopHost) {
        this.hdfsUrl = hdfsUrl;
        this.hadoopHost = hadoopHost;
    }

    public Connection(String hdfsUrl, String hadoopHost, FileSystem fs) {
        this.hdfsUrl = hdfsUrl;
        this.hadoopHost = hadoopHost;
        this.fs = fs;
    }

    public String getHadoopHost() {
        return hadoopHost;
    }

    /**
     * 將web地址和hadoop使用者名稱傳入,生成檔案系統物件
     * @return HDFS檔案系統物件
     * @throws Exception
     */
    public FileSystem init() {
        Configuration configuration = new Configuration();
        try {
            fs = FileSystem.newInstance(new URI(hdfsUrl), configuration, hadoopHost);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        return fs;
    }

    public void fsClose() {
        try {
            fs.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 獲取
     * @return hdfsUrl
     */
    public String getHdfsUrl() {
        return hdfsUrl;
    }

    /**
     * 設定
     * @param hdfsUrl
     */
    public void setHdfsUrl(String hdfsUrl) {
        this.hdfsUrl = hdfsUrl;
    }

    /**
     * 設定
     * @param hadoopHost
     */
    public void setHadoopHost(String hadoopHost) {
        this.hadoopHost = hadoopHost;
    }

    /**
     * 獲取
     * @return fs
     */
    public FileSystem getFs() {
        return fs;
    }

    /**
     * 設定
     * @param fs
     */
    public void setFs(FileSystem fs) {
        this.fs = fs;
    }

    public String toString() {
        return "Connection{hdfsUrl = " + hdfsUrl + ", hadoopHost = " + hadoopHost + ", fs = " + fs + "}";
    }
}

2.建立檔案轉化工具類FileTransferUtil,實現對資料夾的上傳和下載

package com.prettyspider.hadoop.updateanddownload;

import org.apache.hadoop.fs.*;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author prettyspider
 * @ClassName update
 * @description: TODO
 * @date 2023/10/7 19:23
 * @Version V1.0
 */

public class FileTransferUtil {

    private FileTransferUtil() {
    }

    /**
     * 將本地指定路徑下的檔案上傳到HDFS檔案系統上
     *
     * @param localPath 本地檔案路徑
     * @param hdfsPath  HDFS檔案系統路徑
     * @param fs        HDFS檔案系統物件
     */
    public static void update(String localPath, String hdfsPath, FileSystem fs) {
        /**
         * 細節:
         *      兩次getName()的意義不同,第一次是獲取資料夾或者檔案的名稱,第二次是獲取檔案的名稱,不能共用
         */
        String name1 = new File(localPath).getName();
        hdfsPath = hdfsPath + "/" + name1;
        // 獲取本地檔案的檔案集合
        File[] files = new File(localPath).listFiles();
        if (files != null) {
            for (File file : files) {
                // 當為檔案是便上傳
                if (file.isFile()) {
                    String absolutePath = file.getAbsolutePath();
                    String name = file.getName();
                    try {
                        System.out.println(hdfsPath + "/" + name);
                        fs.copyFromLocalFile(new Path("file:///" + absolutePath), new Path(hdfsPath + "/" + name));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    update(file.toString(), hdfsPath, fs);
                }
            }
        }
    }

    /**
     *
     * @param localPath 本地檔案路徑
     * @param hdfsPath HDFS檔案系統路徑
     * @param fs HDFS檔案系統物件
     * @param username 使用者名稱
     * @throws IOException
     */
    public static void download(String localPath, String hdfsPath, FileSystem fs,String username) throws IOException {
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = locatedFileStatusRemoteIterator = fs.listFiles(new Path(hdfsPath), true);
        while (locatedFileStatusRemoteIterator.hasNext()) {
            LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
            // 用使用者名稱做切分點,獲取從使用者名稱開始的檔案路徑
            String name = next.getPath().toString().split(username)[1];
            /**
             * 細節:
             *      將獲取的使用者名稱進行切分,再組合
             */
            String[] arr = name.split("/");
            String fileName = "";
            for (int i = 0; i < arr.length - 1; i++) {
                fileName += arr[i] + "/";
            }
            // 獲取HDFS檔案系統的路徑
            Path path = next.getPath();
            FSDataInputStream getMessage = fs.open(path);
            BufferedReader reader = new BufferedReader(new InputStreamReader(getMessage));
            /**
             * 細節:
             *      輸出時需要先建立檔案目錄
             */
            File file = new File(localPath, fileName);
            if (!file.exists()) {
                file.mkdirs();
            }
            BufferedWriter writer = new BufferedWriter(new FileWriter(new File(file, arr[arr.length - 1])));
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
            writer.close();
            reader.close();
        }

        // 壓縮
        ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(new File(localPath, hdfsPath + ".zip")));
        toZIp(new File(localPath,hdfsPath), zipOutputStream, hdfsPath);
    }

    /**
     *
     * @param src 資料夾物件
     * @param zipOutputStream 壓縮流
     * @param path 指定資料夾下的根目錄
     * @throws IOException
     */
    private static void toZIp(File src, ZipOutputStream zipOutputStream, String path) throws IOException {
        File[] files = src.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    ZipEntry zipEntry = new ZipEntry(path + "\\" + file.getName());
                    zipOutputStream.putNextEntry(zipEntry);
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
                    byte[] bytes = new byte[1024 * 1024 * 8];
                    int len;
                    while ((len = bufferedInputStream.read(bytes))!=-1) {
                        zipOutputStream.write(bytes, 0, len);
                    }
                    bufferedInputStream.close();
                } else {
                    toZIp(file, zipOutputStream, path + "\\" + file.getName());
                }
            }
            zipOutputStream.close();
        }
    }
}

測試類
FileTransferTest

import org.apache.hadoop.fs.FileSystem;
import org.junit.Test;

import java.io.IOException;

/**
 * @author prettyspider
 * @ClassName fileTransferTest
 * @description: TODO
 * @date 2023/10/7 19:47
 * @Version V1.0
 */

public class fileTransferTest {
    @Test
    public void testUpdate() throws IOException {
        Connection connection = new Connection("hdfs://node01:9000", "prettyspider");
        FileSystem fs = connection.init();
        FileTransferUtil.update("E:\\test\\wordcount","input",new ConnectionTest().testInit());
        // fileTransfer.download("E:\\test","input",fs,connection.getHadoopHost());
        connection.fsClose();
    }
}

結果
本地
image
HDFS檔案系統Web端
image

3.根據HDFS檔案系統檢視學生是否提交作業

假設用HDFS檔案系統管理學生作業,如何獲取學生是否提交作業
實現:
1.根據HDFS檔案系統獲取指定”班級"下的所有的已經提交作業的學生
2.與班級的學生名單進行比較,獲取沒有提交作業的學生

建立JobSunmissionUtil工具類,實現獲取沒有提交做的學生

package com.prettyspider.hadoop.jobsubmission;

import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.io.*;
import java.util.ArrayList;

/**
 * @author prettyspider
 * @ClassName Search
 * @description: TODO
 * @date 2023/10/8 11:23
 * @Version V1.0
 */

public class JobSubmissionUtil {
    private JobSubmissionUtil(){}
    public static void search(FileSystem fs) throws Exception {
        File file = new File(".\\src\\main\\java\\com\\prettyspider\\hadoop\\jobsubmission\\stu.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
        String line;
        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> nameList = new ArrayList<>();
        while ((line = reader.readLine()) != null) {
            list.add(line.split("-")[0]);
        }
        System.out.println(list);
        FileStatus[] fileStatuses = fs.listStatus(new Path("input/stu"));
        for (FileStatus fileStatus : fileStatuses) {
            String[] arr = fileStatus.getPath().toString().split("/");
            String s = arr[arr.length - 1].split("\\.")[0];
            nameList.add(s);
        }
        System.out.println(nameList);
        // 去重
        for (String name : nameList) {
            list.remove(name);
        }
        System.out.println("沒有交作業的是"+list);
    }


}

測試類
JobsubmissionTest

package com.prettyspider.hadoop.updateanddownload;

import com.prettyspider.hadoop.Connection;
import com.prettyspider.hadoop.jobsubmission.JobSubmissionUtil;
import org.apache.hadoop.fs.FileSystem;
import org.junit.Test;

/**
 * @author prettyspider
 * @ClassName SearchTest
 * @description: TODO
 * @date 2023/10/8 11:30
 * @Version V1.0
 */

public class JobSubmissionTest {
    @Test
    public void testsearch() throws Exception {
        Connection connection = new Connection("hdfs://node01:9000", "prettyspider");
        FileSystem fs = connection.init();
        JobSubmissionUtil.search(fs);
        connection.fsClose();
    }
}

測試資料

4.實現HDFS檔案系統指定資料夾內的檔案詞頻統計(手搓)

MapReduce是hadoop兩個核心之一,MapReduce框架由Map和Reduce組成。 Map ()負責把一個大的block塊進行切片並計算。 Reduce () 負責把Map ()切片的資料進行彙總、計算。
那麼可以透過簡化,實現切片和資料統計
實現步驟:
1.將HDFS檔案系統指定資料夾下的檔案合併到一個檔案中
2.對檔案進行切分
3.將切分之後的資料利用Map集合實現統計

建立WordCountUtil工具類

package com.prettyspider.hadoop.wordcount;

import org.apache.hadoop.fs.*;

import java.io.*;
import java.util.*;

/**
 * @author prettyspider
 * @ClassName wordcount
 * @description: TODO
 * @date 2023/10/8 12:46
 * @Version V1.0
 */

public class WordCountUtil {
    private WordCountUtil() {}

    /**
     * 將指定資料夾下的檔案合併到一個檔案中,再對檔案進行詞頻統計
     * @param fs HDFS檔案系統物件
     * @param hdfsPath 要統計詞頻的資料夾地址
     * @param mergePath 合併後的檔案地址
     * @throws IOException
     */
    public static void wordcount(FileSystem fs,String hdfsPath,String mergePath) throws IOException {
        merge(fs, hdfsPath, mergePath);
        wordcount(fs, mergePath);
    }

    /**
     * 利用Map對資料進行統計
     * @param fs HDFS檔案系統
     * @param mergePath 合併的檔案地址
     * @throws IOException
     */
    private static void wordcount(FileSystem fs, String mergePath) throws IOException {
        FSDataInputStream open = fs.open(new Path(mergePath));
        // 用集合獲取資料
        ArrayList<String> list = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(open));
        String line;
        while ((line = reader.readLine()) != null) {
            list.add(line);
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (String s : list) {
            stringBuilder.append(s);
        }
        String[] arr = stringBuilder.toString().split("\\W+");
        // 詞頻統計
        wordstatistic(arr);
    }

    /**
     *
     * @param arr 被拆分後的詞的陣列
     */
    private static void wordstatistic(String[] arr) {
        HashMap<String, Integer> map = new HashMap<>();
        for (int i = 0; i < arr.length; i++) {
            String s = arr[i];
            // map中不存在資料
            if (!map.containsKey(s)) {
                map.put(s, 1);
            } else {
                int count = map.get(s) + 1;
                map.put(s,count);
            }
        }
        // 輸出結果
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("key="+key+",value="+value);
        }
    }

    /**
     *
     * @param fs HDFS檔案系統物件
     * @param hdfsPath 要統計的資料夾地址
     * @param mergePath 合併後檔案地址
     * @throws IOException
     */
    private static void merge(FileSystem fs, String hdfsPath, String mergePath) throws IOException {
        FSDataOutputStream fsDataOutputStream = fs.create(new Path(mergePath));
        FileStatus[] fileStatuses = fs.listStatus(new Path(hdfsPath));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fsDataOutputStream));
        for (FileStatus fileStatus : fileStatuses) {
            FSDataInputStream open = fs.open(new Path(fileStatus.getPath().toUri()));
            BufferedReader reader = new BufferedReader(new InputStreamReader(open));
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
            reader.close();
            open.close();
        }
        writer.close();
        fsDataOutputStream.close();
    }

}

測試類
WordCountTest

package com.prettyspider.hadoop.updateanddownload;

import com.prettyspider.hadoop.Connection;
import com.prettyspider.hadoop.wordcount.WordCountUtil;
import org.apache.hadoop.fs.FileSystem;
import org.junit.Test;

import java.io.IOException;

/**
 * @author prettyspider
 * @ClassName WordCountTest
 * @description: TODO
 * @date 2023/10/8 13:15
 * @Version V1.0
 */

public class WordCountTest {
    @Test
    public void testwordcount() throws IOException {
        Connection connection = new Connection("hdfs://node01:9000", "prettyspider");
        FileSystem fs = connection.init();
        WordCountUtil.wordcount(fs,"input/wordcount","output/merge.txt");
		connection.fsClose();
    }
}

結果
image