【Cloud Computing】Hadoop環境安裝、基本命令及MapReduce字數統計程序
- 2021 年 11 月 28 日
- 筆記
- Cloud Computing, CloudComputing, hadoop, HDFS, JAVA, MapReduce, 雲計算
【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地址。
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。
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
1.4 在hadoop136上安裝hadoop
1.4.1 上傳Hadoop
1.4.2 解壓Hadoop
1.4.3 配置Hadoop環境變量
1.4.3 測試Hadoop是否安裝成功
2.本地模式
2.1 Hadoop目錄結構
- 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 集群規劃
3.2 配置文件說明
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
4.2.3 在部署yarn節點上(hadoop135)啟動yarn
sbin/start-yarn.sh
4.2.4 web查看hdfs
//hadoop136:9870
查看存儲的數據信息
4.2.5 web查看YARN的ResourceManager
http:hadoop135:8088
查看yarn上運行的job信息
4.實驗1 HDFS Shell命令
4.1 命令
hadoop fs [命令選項]
4.2 常用命令實例
在HDFS文件系統上建立一個目錄,將本地文件系統上傳到該目錄。
-
hadoop fs -mkdir test
: 在HDFS創建test目錄 -
hadoop fs -ls /
:顯示HDFS目錄結構 -
echo "Hello Hadoop DengSchoo" > file.txt
: 創建一個文件 -
hadoop fs -put file.txt /test/
: 上傳該文件到/test/ -
hadoop fs -ls /test/
:顯示HDFS路徑 -
hadoop fs -cat /test/file.ext
:查看HDFS內容
5.實驗2 HDFS Java接口調用
5.0 Hadoop Win依賴Path配置
添加依賴:hadoop bin 到系統環境變量。
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();
}
}
輸出 成功通過測試
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();
}
}
輸出:
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();
}
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();
}
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作業執行的輸出路
}