【Cloud Computing】Hadoop環境安裝、基本命令及MapReduce字數統計程式

DengSchoo發表於2021-11-28

【Cloud Computing】Hadoop環境安裝、基本命令及MapReduce字數統計程式

1.虛擬機器準備

1.1 模板機器配置

1.1.1 主機配置

  • IP地址:在學校校園網Wifi下連線下 VMWare自己DHCP分配的是 192.168.190.xxx
  • 記憶體:4G(根據自己機器確定 我需要三臺機器 我的記憶體是16G)
  • 硬碟:50G
  • OS:CentOS7 x64

1.1.2 環境工具安裝

  • ping www.baidu.com先檢視能否正常上網
  • yum install -y epel-release安裝額外的軟體包
  • yum install -y net-tools:如果是最小化安裝(只有命令列)需要安裝,包含ifconfig命令
  • yum install -y vim:vim編輯器

1.1.3 關閉防火牆

  • systemctl stop firewalld 關閉防火牆
  • systemctl disable firewalld.service 關閉防火牆開機自啟動

1.1.4 建立hadoop使用者 設定密碼

  • useradd hadoop
  • passwd hadoop

1.1.5 配置hadoop使用者具有root許可權

修改etc/sudoers檔案在%whell ALL=(ALL) ALL語句下增加:hadoop ALL=(ALL) NOPASSWD:ALL。實現免密功能。

1.1.6 在/opt下建立module和software兩個軟體 修改主和所屬組

  • mkdir /opt/module
  • mkdir /opt/software
  • chown hadoop:hadoop /opt/module
  • chown hadoop:hadoop /opt/software

1.1.7 解除安裝虛擬機器自帶的JDK

rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps

1.1.8 重啟虛擬機器

reboot

1.2 克隆三臺虛擬機器

通過VMWare克隆模板機器,此處可以不使用靜態IP, 但是要記得對應虛擬機器的IP地址。

image-20211128171458287

1.2.1 修改主機名

這裡因為我的IP是192.168.190.135所以我改為hadoop135

vim /etc/hostname -> hadoop135

1.2.2 增加主機對映

因為後續叢集部署是三個機器所以要新增域名對映

vim /etc/hosts

192.168.190.135 hadoop135
192.168.190.136 hadoop136
192.168.190.137 hadoop137

重啟即可。

reboot

1.3 在hadoop136上安裝JDK

1.3.1 上傳JDK Hadoop資原始檔

通過遠端連結軟體Xshell或者FinalShell連線到虛擬機器,上傳JDK檔案到/opt/software。

image-20211128172350946

1.3.2 解壓到/opt/module目錄下

tar -zxvf jdkxxxx.gz -C /opt/module

1.3.3 配置JDK環境變數

/etc/profile.d/新建jdk_path.sh檔案

寫入:

#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$PATH:$JAVA_HOME/bin

讓資原始檔生效:source /etc/profile

1.3.4 測試是否安裝成功

java -version

image-20211128173826359

1.4 在hadoop136上安裝hadoop

1.4.1 上傳Hadoop

image-20211128172350946

1.4.2 解壓Hadoop

1.4.3 配置Hadoop環境變數

1.4.3 測試Hadoop是否安裝成功

2.本地模式

2.1 Hadoop目錄結構

image-20211128174201648

  • bin目錄:存放對 Hadoop 相關服務(hdfs,yarn,mapred)進行操作的指令碼
  • etc目錄:Hadoop 的配置檔案目錄,存放 Hadoop 的配置檔案
  • lib目錄:存放 Hadoop 的本地庫(對資料進行壓縮解壓縮功能)
  • sbin目錄:存放啟動或停止 Hadoop 相關服務的指令碼
  • share目錄:存放 Hadoop 的依賴 jar 包、文件、和官方案例

2.2 本地執行模式(官方WordCount)

2.2.1 在hadoop-3.1.3 檔案下建立wcinput資料夾

mkdir wcinput

2.2.2 在同資料夾下建立wcoutput

mkdir wcoutput

2.2.3 在wcinput資料夾下建立word.txt

vim word.txt

hadoop yarn
hadoop mapreduce
dengschoo
deng schoo

2.2.4 執行程式

hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount wcinput wcoutput

deng    1
dengschoo       1
hadoop  2
mapreduce       1
schoo   1
yarn    1

3.叢集模式(完全分散式執行模式)

3.1 叢集規劃

image-20211128175516509

3.2 配置檔案說明

image-20211128175545220

3.3 配置叢集

cd $HADOOP_HOME/etc/hadoop

3.3.1 核心配置檔案

vim core-site.xml

<configuration>
 <!-- 指定 NameNode 的地址 -->
 <property>
 <name>fs.defaultFS</name>
 <value>hdfs://hadoop136:8020</value>
 </property>
 <!-- 指定 hadoop 資料的儲存目錄 -->
 <property>
 <name>hadoop.tmp.dir</name>
 <value>/opt/module/hadoop-3.1.3/data</value>
 </property>
 <!-- 配置 HDFS 網頁登入使用的靜態使用者為 atguigu -->
 <property>
 <name>hadoop.http.staticuser.user</name>
 <value>dengschoo</value>
 </property>
</configuration>

3.3.2 HDFS配置檔案

vim hdfs-site.xml

<configuration>
<!-- nn web 端訪問地址-->
<property>
 <name>dfs.namenode.http-address</name>
 <value>hadoop136:9870</value>
 </property>
<!-- 2nn web 端訪問地址-->
 <property>
 <name>dfs.namenode.secondary.http-address</name>
 <value>hadoop137:9868</value>
 </property>
</configuration>

3.3.3 YARN配置檔案

vim yarn-site.xml

<configuration>
 <!-- 指定 MR 走 shuffle -->
 <property>
 <name>yarn.nodemanager.aux-services</name>
 <value>mapreduce_shuffle</value>
 </property>
 <!-- 指定 ResourceManager 的地址-->
 <property>
 <name>yarn.resourcemanager.hostname</name>
 <value>hadoop135</value>
 </property>
 <!-- 環境變數的繼承 -->
 <property>
 <name>yarn.nodemanager.env-whitelist</name>
 
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CO
NF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAP
RED_HOME</value>
 </property>
</configuration>

3.3.4 MapReduce配置檔案

vim maored-site.xml

<configuration>
<!-- 指定 MapReduce 程式執行在 Yarn 上 -->
 <property>
 <name>mapreduce.framework.name</name>
 <value>yarn</value>
 </property>
</configuration>

3.3.5 分發配置檔案

將配置好的檔案下發到hadoop135,hadoop136, hadoop137

最好的效果是三個worker的配置檔案是一樣的。

4.4 啟動叢集

4.1 配置worker

vim etc/hadoop/workers

刪除localhost,文中不可以有空格 空行

hadoop135
hadoop136
hadoop137

4.2 啟動叢集

4.2.1 格式化節點

需要再hadoop136下格式化NameNode

hdfs namenode -format

4.2.2 啟動hdfs

啟動HDFS

sbin/start-dfs.sh

image-20211128191910907

4.2.3 在部署yarn節點上(hadoop135)啟動yarn

sbin/start-yarn.sh

image-20211128192308418

4.2.4 web檢視hdfs

http://hadoop136:9870

檢視儲存的資料資訊

image-20211128192014402

4.2.5 web檢視YARN的ResourceManager

http:hadoop135:8088

image-20211128192449922

檢視yarn上執行的job資訊

4.實驗1 HDFS Shell命令

4.1 命令

hadoop fs [命令選項]

image-20211128193330802

image-20211128193340676

image-20211128193400341

4.2 常用命令例項

在HDFS檔案系統上建立一個目錄,將本地檔案系統上傳到該目錄。

  1. hadoop fs -mkdir test : 在HDFS建立test目錄

    image-20211128194150365

  2. hadoop fs -ls /:顯示HDFS目錄結構

  3. echo "Hello Hadoop DengSchoo" > file.txt : 建立一個檔案

    image-20211128194236940

  4. hadoop fs -put file.txt /test/ : 上傳該檔案到/test/

    image-20211128194322004

  5. hadoop fs -ls /test/ :顯示HDFS路徑

    image-20211128194353616

  6. hadoop fs -cat /test/file.ext:檢視HDFS內容

image-20211128194426697

5.實驗2 HDFS Java介面呼叫

5.0 Hadoop Win依賴Path配置

新增依賴:hadoop bin 到系統環境變數。

image-20211128201752176

5.1 建立Maven工程匯入依賴

<dependencies>
 <dependency>
 <groupId>org.apache.hadoop</groupId>
 <artifactId>hadoop-client</artifactId>
 <version>3.1.3</version>
 </dependency>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.12</version>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.7.30</version>
 </dependency>
</dependencies>

5.2 API操作

5.2.1 建立資料夾

package com.dengschoo.hdfs;

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

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


/**
 * @author :Deng Schoo
 * @version :V1.0
 * @className :HdfsClient
 * @description :TODO
 * @date :2021/11/28 19:57
 */
public class HdfsClient {
    @Test
    public void testMkdirs() throws URISyntaxException, IOException, InterruptedException {
        // 1. 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"), configuration, "hadoop");
        // 2. 建立目錄
        fs.mkdirs(new Path("/javaAPI/test/"));

        // 3. 關閉資源
        fs.close();
    }
}

輸出 成功通過測試

image-20211128201931680

5.2.2 上傳檔案

package com.dengschoo.hdfs;

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

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


/**
 * @author :Deng Schoo
 * @version :V1.0
 * @className :HdfsClient
 * @description :TODO
 * @date :2021/11/28 19:57
 */
public class HdfsClient {
    @Test
    public void testMkdirs() throws URISyntaxException, IOException, InterruptedException {
        // 1. 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"), configuration, "hadoop");
        // 2. 建立目錄
        fs.mkdirs(new Path("/javaAPI/test/"));

        // 3. 關閉資源
        fs.close();
    }

    @Test
    public void testCopyFromLocalFile() throws URISyntaxException, IOException, InterruptedException {
        // 1. 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"), configuration, "hadoop");

        // 2. 上傳檔案
        fs.copyFromLocalFile(new Path("D:\\Study\\GradeFour\\Course\\CloudComputingProjects\\src\\main\\java\\com\\dengschoo\\hdfs\\file.txt"), new Path("/javaAPI/test/"));

        //3.關閉資源
        fs.close();
    }
}

輸出:

image-20211128202440327

5.2.3 檔案下載

 @Test
    public void testCopyToLocalFile() throws URISyntaxException, IOException, InterruptedException {
        // 1. 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"), configuration, "hadoop");
        // 指向檔案下載操作
        // boolean 是否刪除原始檔
        // src
        // des
        // 是否開啟檔案校驗
        fs.copyToLocalFile(false,new Path("/javaAPI/test/file.txt"), new Path("D:\\Environment\\TestEnv"), true);

        //3.關閉資源
        fs.close();
    }

5.2.4 檔案更名和移動

@Test
    public void testRename() throws IOException, InterruptedException, URISyntaxException{
        // 1 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"),
                configuration, "hadoop");
        // 2 修改檔名稱
        fs.rename(new Path("/javaAPI/test/file.txt"), new
                Path("/javaAPI/test/file——new.txt"));
        // 3 關閉資源
        fs.close();
    }

5.2.5 HDFS刪除檔案和目錄

@Test
    public void testDelete() throws IOException, InterruptedException,
            URISyntaxException{
        // 1 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"),
                configuration, "hadoop");
        // 2 執行刪除
        fs.delete(new Path("/javaAPI/test"), true);
        // 3 關閉資源
        fs.close();
    }

5.2.6 檔案詳情檢視

@Test
    public void testListFiles() throws IOException, InterruptedException,
            URISyntaxException {
        // 1 獲取檔案系統
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"),
                configuration, "hadoop");
        // 2 獲取檔案詳情
        RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"),
                true);
        while (listFiles.hasNext()) {
            LocatedFileStatus fileStatus = listFiles.next();
            System.out.println("========" + fileStatus.getPath() + "=========");
            System.out.println(fileStatus.getPermission());
            System.out.println(fileStatus.getOwner());
            System.out.println(fileStatus.getGroup());
            System.out.println(fileStatus.getLen());
            System.out.println(fileStatus.getModificationTime());
            System.out.println(fileStatus.getReplication());
            System.out.println(fileStatus.getBlockSize());
            System.out.println(fileStatus.getPath().getName());
            // 獲取塊資訊
            BlockLocation[] blockLocations = fileStatus.getBlockLocations();
            System.out.println(Arrays.toString(blockLocations));
        }
        // 3 關閉資源
        fs.close();
    }

image-20211128203853647

5.2.7 HDFS檔案和資料夾判斷

@Test
    public void testListStatus() throws IOException, InterruptedException,
            URISyntaxException{
        // 1 獲取檔案配置資訊
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://192.168.190.136:8020"),
                configuration, "hadoop");
        // 2 判斷是檔案還是資料夾
        FileStatus[] listStatus = fs.listStatus(new Path("/"));
        for (FileStatus fileStatus : listStatus) {
            // 如果是檔案
            if (fileStatus.isFile()) {
                System.out.println("f:"+fileStatus.getPath().getName());
            }else {
                System.out.println("d:"+fileStatus.getPath().getName());
            }
        }
        // 3 關閉資源
        fs.close();
    }

image-20211128203823578

6.實驗3 MapReduce應用程式

6.1 編寫Mapper類

public static class MyMapper
            extends Mapper<Object, Text, Text, IntWritable> {
        private final static IntWritable one = new IntWritable(1);//one表示單詞在該行 中的出現次數
        private final Text word = new Text(); //word存放一行中的單詞
        /*定義map方法,分割文字行中的單詞,將單詞及其在該行中的出現次數1寫入conte
        xt;形參value表示一行文字*/
        public void map(Object key, Text value, Context context
        ) throws IOException, InterruptedException {
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);//把word、one寫入到context中
            }
        }
    }

6.2 編寫Reducer類

public static class MyReducer
            extends Reducer<Text, IntWritable,Text,IntWritable> {
        private final IntWritable result = new IntWritable();//result表示單詞出現的總次數
        public void reduce(Text key, Iterable<IntWritable> values,
                           Context context
        ) throws IOException, InterruptedException {
            int sum = 0;//sum存放該單詞出現的總次數
            for (IntWritable val : values) {
                sum += val.get();
            }
            result.set(sum); //result表示單詞的總次數,是最後輸出的“值”
            context.write(key, result);
        }
    }

6.3 編寫主類

public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        Configuration conf = new Configuration();
        System.setProperty("HADOOP_USER_NAME","hadoop");
        Job job = Job.getInstance(conf, "wordcount"); //建立一個job物件
        job.setUser("hadoop");
        job.setJarByClass(MapReduceTest.class); //建立一個job物件
        job.setMapperClass(MyMapper.class); //設定自定義的Mapper類
        job.setCombinerClass(MyReducer.class);
        job.setReducerClass(MyReducer.class);//設定自定義的Reducer類
        job.setOutputKeyClass(Text.class);//設定map()方法輸出的key型別
        job.setOutputValueClass(IntWritable.class);//設定輸出的value的型別
        job.setUser("hadoop");
        FileInputFormat.addInputPath(job,
                new Path("hdfs://192.168.190.136:8020/javaAPI/test/input"));
//job作業執行時輸入檔案的路徑
        FileOutputFormat.setOutputPath(job,
                new Path("hdfs://192.168.190.136:8020/javaAPI/test/out"));
        System.exit(job.waitForCompletion(true) ? 0 : 1);//設定job作業執行的輸出路
    }

6.4 執行結果

image-20211128213121007

相關文章