大數據Hadoop入門篇——Hadoop僞分佈模式安裝 & WordCount 詞頻統計實現

本文主要記錄Mac下如何進行Hadoop僞分佈模式安裝,並經過詞頻統計Demo程序(WordCount)理解MapReduce的原理。html

學習資料彙總

參考資料

《Hadoop權威指南》隨書資料

Hadoop基礎

Hadoop和Spark

Hadoop和Spark是兩種不一樣的大數據處理框架,以下圖所示。java

  • 上圖中的藍色部分是Hadoop生態系統組件,黃色部分是Spark生態組件。
  • 雖然它們是兩種不一樣的大數據處理框架,但它們不是互斥的。Spark與Hadoop 中的 MapReduce 是一種相互共生的關係。
  • Hadoop 提供了 Spark 許多沒有的功能,好比分佈式文件系統,而 Spark 提供了實時內存計算,速度很是快。

Hadoop 一般包括2個部分:存儲和處理。存儲部分就是Hadoop的分佈式文件系統(HDFS),處理指的是MapReduce(MP)。node

Hadoop 安裝和配置

Hadoop 安裝模式

Hadoop 安裝模式分爲3種,分別是單機模式,僞分佈模式和全分佈模式。默認安裝是單機模式。能夠經過配置文件 core-site.xml,將默認的單機模式更改成僞分佈模式。git

關於Hadoop 3種安裝模式和如何使用虛擬機進行分佈式安裝,能夠參考《Hadoop應用技術詳解》書籍的第2章節——Hadoop安裝。github

Hadoop 的運行方式是由配置文件決定的,所以若是須要從僞分佈式模式切換回非分佈式模式,須要刪除 core-site.xml 中的配置項。算法

下面簡單記錄,如何經過修改配置文件,在 Mac 上搭建僞分佈模式 Hadoop 環境。shell

Hadoop 安裝步驟

Hadoop的安裝和配置步驟以下(具體細節參考上述參考連接)數據庫

  1. 安裝Java。
  2. Mac設置中,進入「共享」設置頁面,容許遠程登陸,使用 ssh localhost 進行驗證。
  3. 下載Hadoop源碼,在 Hadoop官網 可下載,此處選擇下載 hadoop 2.10.0。將下載的 .tar.gz 壓縮包解壓並放置到 /Library/hadoop-2.10.0 路徑。
  4. 設置Hadoop環境變量

(1) 打開配置文件apache

vim ~/.bash_profile
複製代碼

(2) 設置環境變量vim

HADOOP_HOME=/Library/hadoop-2.10.0
PATH=$PATH:${HADOOP_HOME}/bin

HADOOP_CONF_DIR=/Library/hadoop-2.10.0/etc/hadoop

HADOOP_COMMON_LIB_NATIVE_DIR=/Library/hadoop-2.10.0/lib/native

export HADOOP_HOME
export PATH

export HADOOP_CONF_DIR

export HADOOP_COMMON_LIB_NATIVE_DIR
複製代碼

(3) 使配置文件生效,並驗證Hadoop版本號

source ~/.bash_profile

hadoop version  
複製代碼
  1. 修改 Hadoop 的配置文件

須要修改的 Hadoop 配置文件都在目錄 etc/hadoop 下,包括

  • hadoop-env.sh
  • core-site.xml
  • hdfs-site.xml
  • mapred-site.xml
  • yarn-site.xml

下面逐步進行修改

(1) 修改 hadoop-env.sh 文件

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home
export HADOOP_HOME=/Library/hadoop-2.10.0
export HADOOP_CONF_DIR=/Library/hadoop-2.10.0/etc/hadoop
複製代碼

(2) 修改 core-site.xml 文件

設置 Hadoop 的臨時目錄和文件系統,localhost:9000 表示本地主機。若是使用遠程主機,要用相應的 IP 地址來代替,填寫遠程主機的域名,則須要到 /etc/hosts 文件中作 DNS 映射。

<configuration>
  <!--localhost:9000 表示本地主機-->>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>

  <!--用來指定hadoop運行時產生文件的存放目錄  本身建立-->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/Users/lbs/devfiles/hadoop/hadoop-2.10.0/tmp</value>
    <description>Directories for software develop and save temporary files.</description>
  </property>
</configuration>
複製代碼

(3) 修改 hdfs-site.xml 文件

hdfs-site.xml 指定了 HDFS 的默認參數副本數,由於僅運行在一個節點上(僞分佈模式),因此這裏的副本數爲1。

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>1</value>    
  </property>

	<!--不是root用戶也能夠寫文件到hdfs-->
	<property>
		<name>dfs.permissions</name>
		<value>false</value>    <!--關閉防火牆-->
	</property>
  
  <!--把路徑換成本地的name位置-->
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>/Users/lbs/devfiles/hadoop/hadoop-2.10.0/tmp/dfs/name</value>
  </property>
        
  <!--在本地新建一個存放hadoop數據的文件夾,而後將路徑在這裏配置一下-->
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>/Users/lbs/devfiles/hadoop/hadoop-2.10.0/tmp/dfs/data</value>
  </property>
</configuration>
複製代碼

(4) 修改 mapred-site.xml 文件

複製 mapred-site.xml.template 模板文件,並修改成 mapred-site.xml 文件,而後將 yarn 設置成數據處理框架,並設置 JobTracker 的主機名與端口。

<configuration>
  <property>
    <!--指定mapreduce運行在yarn上-->
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>
</configuration>
複製代碼

(5) 修改 yarn-site.xml 文件

配置數據的處理框架 yarn

<configuration>
  <!-- Site specific YARN configuration properties -->
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
  </property>
  <property>
    <name>yarn.resourcemanager.address</name>
    <value>localhost:9000</value>
  </property>
</configuration>
複製代碼

啓動Hadoop

(1) 第一次啓動Hadoop,須要對 NameNode 進行格式化,後續啓動再也不須要執行此步驟。

hadoop namenode -format
複製代碼

(2) 啓動 HDFS:進入Hadoop 安裝目錄下的 sbin 目錄,並啓動HDFS(須要設置Mac容許遠程登陸,過程當中共須要3次輸入密碼)

Tip: 初次安裝和啓動時,能夠執行 ./start-all.sh,進行必要的初始化安裝

cd /Library/hadoop-2.10.0/sbin

./start-dfs.sh
複製代碼

若出現下述信息,表示啓動成功

lbsMacBook-Pro:sbin lbs$ ./start-dfs.sh
Starting namenodes on [localhost]
Password:
localhost: namenode running as process 12993. Stop it first.
Password:
localhost: datanode running as process 32400. Stop it first.
Starting secondary namenodes [0.0.0.0]
Password:
0.0.0.0: Connection closed by 127.0.0.1 port 22
複製代碼

須要注意的是,在log中會顯示警告

WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicabled的
複製代碼

上述提醒是關於 Hadoop 本地庫的——Hadoop本地庫是爲了提升效率或者某些不能用Java實現的功能組件庫。能夠參考 Mac OSX 下 Hadoop 使用本地庫提升效率 瞭解詳情。

中止 Hadoop 方法以下

cd /Library/hadoop-2.10.0/sbin

./sbin/stop-dfs.sh
複製代碼

(3) 在終端執行 jps,若看到以下信息,證實 Hadoop 能夠成功啓動。看到 DataNodeNameNodeSecondaryNameNode 信息,代表啓動的是一個僞分佈模式Hadoop。

lbsMacBook-Pro:sbin lbs$ jps

32400 DataNode
12993 NameNode
30065 BootLanguagServerBootApp
13266 SecondaryNameNode
30039 org.eclipse.equinox.launcher_1.5.700.v20200207-2156.jar
35019 ResourceManager
35117 NodeManager
32926 RunJar
35199 Jps
複製代碼

也能夠訪問 http://localhost:50070/dfshealth.html#tab-overview 來查看 Hadoop的啓動狀況。看到 Live Node 參數,證實僞分佈模式 Hadoop 啓動成功。

(4) 啓動 yarn:進入Hadoop 安裝目錄下的 sbin 目錄,並啓動 yarn

cd /Library/hadoop-2.10.0/sbin

./start-yarn.sh
複製代碼

至此,Hadoop的安裝,配置和啓動就完成啦!接下來能夠經過一些 shell 命令來操做 Hadoop 下的文件了,例如

hadoop fs -ls /&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp; 查看根目錄下的文件及文件夾
hadoop fs -mkdir /test      在根目錄下建立一個文件夾 testdata
hadoop fs -rm /.../...      移除某個文件
hadoop fs -rmr /...         移除某個空的文件夾
複製代碼

FAQ

Unable to load native-hadoop library for your platform

在啓動 HDFS時,若看到以下警告

./start-dfs.sh
複製代碼
lbsMacBook-Pro:~ lbs$ cd /Library/hadoop-2.10.0/sbin

lbsMacBook-Pro:sbin lbs$ ./start-dfs.sh

20/03/23 08:46:43 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Starting namenodes on [localhost]
Password:
localhost: namenode running as process 93155. Stop it first.
Password:
localhost: datanode running as process 93262. Stop it first.
Starting secondary namenodes [0.0.0.0]
Password:
0.0.0.0: secondarynamenode running as process 93404. Stop it first.
複製代碼

上述提醒是關於 Hadoop 本地庫的——Hadoop本地庫是爲了提升效率或者某些不能用Java實現的功能組件庫。能夠參考 Mac OSX 下 Hadoop 使用本地庫提升效率 瞭解詳情。

《Hadoop 應用開發技術詳解》 學習筆記

MapReduce快速入門-WordCount

工程建立

  1. 使用IDEA建立一個基於Maven的工程——WordCount
  2. pom.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>org.lbs0912</groupId>
    <artifactId>wordcount</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--添加 apache 鏡像源-->
    <repositories>
        <repository>
            <id>apache</id>
            <url>http://maven.apache.org</url>
        </repository>
    </repositories>


    <!--添加以下依賴-->
    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-core</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.7.2</version>
        </dependency>
    </dependencies>

</project>
複製代碼
  1. 建立 WordMapper
package wordcount;

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class WordMapper extends Mapper<Object, Text, Text, IntWritable> {
    IntWritable one = new IntWritable(1);
    Text word = new Text();


    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);
        }
    }
}

複製代碼
  1. 建立 WordReducer
package wordcount;


import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
    private IntWritable result = new IntWritable();

    public void reduce(Text	key, Iterable<IntWritable> values, Context context) throws IOException,InterruptedException {
        int sum = 0;
        for(IntWritable val:values) {
            sum += val.get();
        }
        result.set(sum);
        context.write(key,result);
    }
}
複製代碼
  1. 建立 WordMain 驅動類
package wordcount;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordMain {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        /**
         * 這裏必須有輸入/輸出
         */
        if (otherArgs.length != 2) {
            System.err.println("Usage: WordCount <in> <out>");
            System.exit(2);
        }

        Job job = new Job(conf, "wordcount");
        job.setJarByClass(WordMain.class);       //主類
        job.setMapperClass(WordMapper.class);     //Mapper
        job.setCombinerClass(WordReducer.class);  //做業合成類
        job.setReducerClass(WordReducer.class);    //Reducer
        job.setOutputKeyClass(Text.class);       //設置做業輸出數據的關鍵類
        job.setOutputValueClass(IntWritable.class);  //設置做業輸出值類
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));   //文件輸入
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));  //文件輸出
        System.exit(job.waitForCompletion(true) ? 0 : 1);   //等待完成退出
    }
}
複製代碼

IDEA中直接運行程序

選擇 Run -> Edit Configurations, 在程序參數欄目中輸入 input/ output,以下圖所示

input 目錄中添加統計單詞個數的測試的文件 wordcount1.txt

Hello,i love coding
are you ok?
Hello, i love hadoop
are you ok?
複製代碼

再次運行程序,會看到以下的 output 目錄結構

- input
- output
    | - ._SUCCESS.crc
    | - .part-r-00000.crc
    | - ._SUCCESS
    | - part-r-00000
複製代碼

打開 part-r-00000 文件,便可看到單詞出現次數的統計結果

Hello,	1
Hello,i	1
are	2
coding	1
hadoop	1
i	1
love	2
ok?	2
you	2
複製代碼

須要注意的是,因爲Hadoop的設定,下次運行程序前,須要先刪除output文件目錄。

導出jar包運行程序

  1. File -> Project Structure 選項中,爲工程添加 Artifacts,選擇 WordMain

  1. 選擇 Build -> Build Artifacts...,生成 .jar 文件

  1. 進入HDFS系統目錄(不是其他文件系統目錄),執行下述命令
hadoop jar WordCount.jar input/ out/
複製代碼

HDFS分佈式文件系統詳解

認識HDFS

HDFS(Hadoop Distributed File System)是一個用在普通硬件設備上的分佈式文件系統。 HDFS 具備高容錯性(fault-tolerant)和高吞吐量(high throughput),適合有超大數據集的應用程序,能夠實現經過流的形式訪問文件系統中的數據。

運行在HDFS之上的應用程序必須流式地訪問它們的數據集,它不是典型的運行在常規的文件系統之上的常規程序。HDFS的設計適合批量處理,而不是用戶交互式的,重點是數據吞吐量,而不是數據訪問的反應時間。

HDFS以塊序列的形式存儲每個文件,文件中除了最後一個塊的其餘塊都是相同的大小。

HDFS架構

HDFS 爲Hadoop 這個分佈式計算框架一共高性能,高可靠,高可擴展的存儲服務。HDFS是一個典型的主從架構,一個HDFS集羣是由一個主節點(Namenode)和必定數目的從節點(Datanodes)組成。

  • Namenode 是一箇中心服務器,負責管理文件系統的名字空間(namespace)以及客戶端對文件的訪問。同時肯定塊和數據節點的映射。
    • 提供名稱查詢服務,它是一個 Jetty 服務器
    • 保存 metadata 信息,包括文件 owershippermissions,文件包含有哪些塊,Block 保存在哪一個 DataNode
    • NameNode 的 metadata 信息在啓動後會加載到內存中
  • Datanode通常是一個節點一個,負責管理它所在節點上的存儲。DataNode 一般以機架的形式組織,機架經過一個交換機將全部系統鏈接起來。 DataNode的功能包括
    • 保存Block,每一個塊對應一個元數據信息文件
    • 啓動DataNode線程的時候會向NameNode彙報Block信息
    • 經過向NameNode發送心跳保持與其聯繫(3秒一次)

  • 機架(Rack):一個 Block 的三個副本一般會保存到兩個或者兩個以上的機架中,進行防災容錯
  • 數據塊(Block)是 HDFS 文件系統基本的存儲單位,Hadoop 1.X 默認大小是 64MB,Hadoop 2.X 默認大小是 128MB。HDFS上的文件系統被劃分爲塊大小的多個分塊(Chunk)做爲獨立的存儲單元。和其餘文件系統不一樣的是,HDFS上小於一個塊大小的文件不會佔據整個塊的空間。使用塊抽象而非整個文件做爲存儲單元,大大簡化了存儲子系統的設計。
  • 輔助元數據節點(SecondaryNameNode)負責鏡像備份,日誌和鏡像的按期合併。

使用 hadoop fsk / -files -blocks 能夠顯示塊的信息。

Block 數據塊大小設置的考慮因素包括

  1. 減小文件尋址時間
  2. 減小管理快的數據開銷,因每一個快都須要在 NameNode 上有對應的記錄
  3. 對數據塊進行讀寫,減小創建網絡的鏈接成本

塊備份原理

Block 是 HDFS 文件系統的最小組成單元,它經過一個 Long 整數被惟一標識。每一個 Block 會有多個副本,默認有3個副本。爲了數據的安全和高效,Hadoop 默認對3個副本的存放策略以下圖所示

  • 第1塊:在本地機器的HDFS目錄下存儲一個 Block
  • 第2塊:不一樣 Rack 的某個 DataNode 上存儲一個 Block
  • 第3塊:在該機器的同一個 Rack 下的某臺機器上存儲一個Block

這樣的策略能夠保證對該 Block 所屬文件的訪問可以優先在本 Rack 下找到。若是整個 Rack 發生了異常,也能夠在另外的 Rack 找到該 Block 的副本。這樣足夠高效,而且同時作到了數據的容錯。

Hadoop的RPC機制

RPC(Remote Procedure Call)即遠程過程調用機制會面臨2個問題

  1. 對象調用方式
  2. 序列/反序列化機制

RPC 架構以下圖所示。Hadoop 本身實現了簡單的 RPC 組件,依賴於 Hadoop Writable 類型的支持。

Hadoop Writable 接口要求每一個實現類多要確保將本類的對象正確序列化(writeObject)和反序列化(readObject)。所以,Hadoop RPC 使用 Java 動態代理和反射實現對象調用方式,客戶端到服務器數據的序列化和反序列化由 Hadoop框架或用戶本身來實現,也就是數據組裝定製的。

Hadoop RPC = 動態代理 + 定製的二進制流

開源數據庫HBase

Overview

  • HBase 是一個可伸縮的分佈式的,面向列的開源數據庫,是一個適合於非結構化數據存儲的數據庫。須要注意的是,HBase 是基於列的而不是基於行的模式。
  • 利用 HBase 技術能夠在廉價 PC Server上搭建大規模結構化存儲集羣。
  • HBase 是 Google Bigtable 的開源實現,與 Google Bigtable 利用GFS做爲其文件存儲系統相似, HBase 利用 Hadoop HDFS 做爲其文件存儲系統。Google 運行 MapReduce 來處理 Bigtable 中的海量數據,HBase 一樣利用 Hadoop MapReduce 來處理海量數據。Google Bigtable 利用 Chubby 做爲協同服務,HBase 利用 Zookeeper 做爲對應。

HBase 的特色以下

  1. 大:一個表能夠有上億行,上百萬列
  2. 面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索
  3. 稀疏:對於爲空(NULL)的列,並不佔用存儲空間,所以,表能夠設計的很是稀疏。

Hadoop 實戰Demo

有句話說得好,「大數據勝於算法」,意思是說對於某些應用(例如根據以往的偏好來推薦電影和音樂),不論算法有多牛,基於小數據的推薦效果每每都不如基於大量可用數據的通常算法的推薦效果。 —— 《Hadoop 權威指南》

相關文章
相關標籤/搜索