天天看點

一文讀懂Hadoop、HBase、Hive、Spark分布式系統架構

一文讀懂Hadoop、HBase、Hive、Spark分布式系統架構

機器學習、資料挖掘等各種大資料處理都離不開各種開源分布式系統,hadoop使用者分布式存儲和map-reduce計算,spark用于分布式機器學習,hive是分布式資料庫,hbase是分布式kv系統,看似互不相關的他們卻都是基于相同的hdfs存儲和yarn資源管理,本文通過全套部署方法來讓大家深入系統内部以充分了解分布式系統架構和他們之間的關系

本文結構

首先,我們來分别部署一套hadoop、hbase、hive、spark,在講解部署方法過程中會特殊說明一些重要配置,以及一些架構圖以幫我們了解,目的是為後面講解系統架構和關系打基礎。

之後,我們會通過運作一些程式來分析一下這些系統的功能

最後,我們會總結這些系統之間的關系

分布式hadoop部署

<a href="http://apache.fayea.com/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz">http://apache.fayea.com/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz</a>

下載下傳到 /data/apache 并解壓

在真正部署之前,我們先了解一下 hadoop 的架構

hadoop分為幾大部分:yarn負責資源和任務管理、hdfs負責分布式存儲、map-reduce負責分布式計算

先來了解一下yarn的架構:

yarn的兩個部分:資源管理、任務排程。

資源管理需要一個全局的resourcemanager(rm)和分布在每台機器上的nodemanager協同工作,rm負責資源的仲裁,nodemanager負責每個節點的資源監控、狀态彙報和container的管理

任務排程也需要resourcemanager負責任務的接受和排程,在任務排程中,在container中啟動的applicationmaster(am)負責這個任務的管理,當任務需要資源時,會向rm申請,配置設定到的container用來起任務,然後am和這些container做通信,am和具體執行的任務都是在container中執行的

yarn差別于第一代hadoop的部署(namenode、jobtracker、tasktracker)

然後再看一下hdfs的架構:hdfs部分由namenode、secondarynamenode和datanode組成。datanode是真正的在每個存儲節點上管理資料的子產品,namenode是對全局資料的名字資訊做管理的子產品,secondarynamenode是它的從節點,以防挂掉。

最後再說map-reduce:map-reduce依賴于yarn和hdfs,另外還有一個jobhistoryserver用來看任務運作曆史

hadoop雖然有多個子產品分别部署,但是所需要的程式都在同一個tar包中,是以不同子產品用到的配置檔案都在一起,讓我們來看幾個最重要的配置檔案:

各種預設配置:core-default.xml, hdfs-default.xml, yarn-default.xml, mapred-default.xml

各種web頁面配置:core-site.xml, hdfs-site.xml, yarn-site.xml, mapred-site.xml

從這些配置檔案也可以看出hadoop的幾大部分是分開配置的。

除上面這些之外還有一些重要的配置:hadoop-env.sh、mapred-env.sh、yarn-env.sh,他們用來配置程式運作時的java虛拟機參數以及一些二進制、配置、日志等的目錄配置

下面我們真正的來修改必須修改的配置檔案。

修改etc/hadoop/core-site.xml,把配置改成:

&lt;configuration&gt; 

    &lt;property&gt; 

        &lt;name&gt;fs.defaultfs&lt;/name&gt; 

        &lt;value&gt;hdfs://127.0.0.1:8000&lt;/value&gt; 

    &lt;/property&gt; 

        &lt;name&gt;io.file.buffer.size&lt;/name&gt; 

        &lt;value&gt;131072&lt;/value&gt; 

&lt;/configuration&gt; 

這裡面配置的是hdfs的檔案系統位址:本機的9001端口

修改etc/hadoop/hdfs-site.xml,把配置改成:

        &lt;name&gt;dfs.namenode.name.dir&lt;/name&gt; 

        &lt;value&gt;file:/data/apache/dfs/name&lt;/value&gt; 

        &lt;name&gt;dfs.datanode.data.dir&lt;/name&gt; 

        &lt;value&gt;file:/data/apache/dfs/data&lt;/value&gt; 

        &lt;name&gt;dfs.datanode.fsdataset.volume.choosing.policy&lt;/name&gt; 

        &lt;value&gt;org.apache.hadoop.hdfs.server.datanode.fsdataset.availablespacevolumechoosingpolicy&lt;/value&gt; 

        &lt;name&gt;dfs.namenode.http-address&lt;/name&gt; 

        &lt;value&gt;127.0.0.1:50070&lt;/value&gt; 

        &lt;name&gt;dfs.namenode.secondary.http-address&lt;/name&gt; 

        &lt;value&gt;127.0.0.1:8001&lt;/value&gt; 

這裡面配置的是hdfs檔案存儲在本地的哪裡以及secondary namenode的位址

修改etc/hadoop/yarn-site.xml,把配置改成:

        &lt;name&gt;yarn.resourcemanager.hostname&lt;/name&gt; 

        &lt;value&gt;127.0.0.1&lt;/value&gt; 

        &lt;name&gt;yarn.resourcemanager.webapp.address&lt;/name&gt; 

        &lt;value&gt;127.0.0.1:8088&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.aux-services&lt;/name&gt; 

        &lt;value&gt;mapreduce_shuffle&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.aux-services.mapreduce.shuffle.class&lt;/name&gt; 

        &lt;value&gt;org.apache.hadoop.mapred.shufflehandler&lt;/value&gt; 

        &lt;name&gt;yarn.log-aggregation-enable&lt;/name&gt; 

        &lt;value&gt;true&lt;/value&gt; 

        &lt;name&gt;yarn.log-aggregation.retain-seconds&lt;/name&gt; 

        &lt;value&gt;864000&lt;/value&gt; 

        &lt;name&gt;yarn.log-aggregation.retain-check-interval-seconds&lt;/name&gt; 

        &lt;value&gt;86400&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.remote-app-log-dir&lt;/name&gt; 

        &lt;value&gt;/yarnapp/logs&lt;/value&gt; 

        &lt;name&gt;yarn.log.server.url&lt;/name&gt; 

        &lt;value&gt;http://127.0.0.1:19888/jobhistory/logs/&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.local-dirs&lt;/name&gt; 

        &lt;value&gt;/data/apache/tmp/&lt;/value&gt; 

        &lt;name&gt;yarn.scheduler.maximum-allocation-mb&lt;/name&gt; 

        &lt;value&gt;5000&lt;/value&gt; 

        &lt;name&gt;yarn.scheduler.minimum-allocation-mb&lt;/name&gt; 

        &lt;value&gt;1024&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.vmem-pmem-ratio&lt;/name&gt; 

        &lt;value&gt;4.1&lt;/value&gt; 

        &lt;name&gt;yarn.nodemanager.vmem-check-enabled&lt;/name&gt; 

        &lt;value&gt;false&lt;/value&gt; 

這裡面配置的是yarn的日志位址以及一些參數配置

通過cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml建立etc/hadoop/mapred-site.xml,内容改為如下:

        &lt;name&gt;mapreduce.framework.name&lt;/name&gt; 

        &lt;value&gt;yarn&lt;/value&gt; 

        &lt;description&gt;execution framework set to hadoop yarn.&lt;/description&gt; 

        &lt;name&gt;yarn.app.mapreduce.am.staging-dir&lt;/name&gt; 

        &lt;value&gt;/tmp/hadoop-yarn/staging&lt;/value&gt; 

        &lt;name&gt;mapreduce.jobhistory.address&lt;/name&gt; 

        &lt;value&gt;127.0.0.1:10020&lt;/value&gt; 

        &lt;name&gt;mapreduce.jobhistory.webapp.address&lt;/name&gt; 

        &lt;value&gt;127.0.0.1:19888&lt;/value&gt; 

        &lt;name&gt;mapreduce.jobhistory.done-dir&lt;/name&gt; 

        &lt;value&gt;${yarn.app.mapreduce.am.staging-dir}/history/done&lt;/value&gt; 

        &lt;name&gt;mapreduce.jobhistory.intermediate-done-dir&lt;/name&gt; 

        &lt;value&gt;${yarn.app.mapreduce.am.staging-dir}/history/done_intermediate&lt;/value&gt; 

        &lt;name&gt;mapreduce.jobhistory.joblist.cache.size&lt;/name&gt; 

        &lt;value&gt;1000&lt;/value&gt; 

        &lt;name&gt;mapreduce.tasktracker.map.tasks.maximum&lt;/name&gt; 

        &lt;value&gt;8&lt;/value&gt; 

        &lt;name&gt;mapreduce.tasktracker.reduce.tasks.maximum&lt;/name&gt; 

        &lt;name&gt;mapreduce.jobtracker.maxtasks.perjob&lt;/name&gt; 

        &lt;value&gt;5&lt;/value&gt; 

        &lt;description&gt;the maximum number of tasks for a single job. 

            a value of -1 indicates that there is no maximum. 

        &lt;/description&gt; 

這裡面配置的是mapred的任務曆史相關配置

如果你的hadoop部署在多台機器,那麼需要修改etc/hadoop/slaves,把其他slave機器ip加到裡面,如果隻部署在這一台,那麼就留一個localhost即可

下面我們啟動hadoop,啟動之前我們配置好必要的環境變量:

export java_home="你的java安裝位址" 

先啟動hdfs,在此之前要格式化分布式檔案系統,執行:

./bin/hdfs namenode -format myclustername 

如果格式化正常可以看到/data/apache/dfs下生成了name目錄

然後啟動namenode,執行:

./sbin/hadoop-daemon.sh --script hdfs start namenode 

如果正常啟動,可以看到啟動了相應的程序,并且logs目錄下生成了相應的日志

然後啟動datanode,執行:

./sbin/hadoop-daemon.sh --script hdfs start datanode 

如果考慮啟動secondary namenode,可以用同樣的方法啟動

下面我們啟動yarn,先啟動resourcemanager,執行:

./sbin/yarn-daemon.sh start resourcemanager 

然後啟動nodemanager,執行:

./sbin/yarn-daemon.sh start nodemanager 

然後啟動mapreduce jobhistory server,執行:

./sbin/mr-jobhistory-daemon.sh start historyserver 

下面我們看下web界面

到此為止我們對hadoop的部署完成。下面試驗一下hadoop的功能

先驗證一下hdfs分布式檔案系統,執行以下指令看是否有輸出:

[root@myay hadoop]# ./bin/hadoop fs -mkdir /input 

[root@myay hadoop]# cat data 

[root@myay hadoop]# ./bin/hadoop fs -put input /input 

[root@myay hadoop]# ./bin/hadoop fs -ls /input 

found 1 items 

-rw-r--r--   3 root supergroup          8 2016-08-07 15:04 /input/data 

下面我們以input為輸入啟動一個mapreduce任務

[root@myay hadoop]# ./bin/hadoop jar ./share/hadoop/tools/lib/hadoop-streaming-2.7.2.jar -input /input -output /output -mapper cat -reducer wc 

之後看是否産生了/output的輸出:

[root@myay hadoop]# ./bin/hadoop fs -ls /output 

found 2 items 

-rw-r--r--   3 root supergroup          0 2016-08-07 15:11 /output/_success 

-rw-r--r--   3 root supergroup         25 2016-08-07 15:11 /output/part-00000 

[root@myay hadoop]# ./bin/hadoop fs -cat /output/part-00000 

      4       4      12 

為什麼兩處都有曆史呢?他們的差別是什麼呢?

我們看到cluster顯示的其實是每一個application的曆史資訊,他是yarn(resourcemanager)的管理頁面,也就是不管是mapreduce還是其他類似mapreduce這樣的任務,都會在這裡顯示,mapreduce任務的application

type是mapreduce,其他任務的類型就是其他了,但是jobhistory是專門顯示mapreduce任務的

hbase的部署

解壓後修改conf/hbase-site.xml,改成:

        &lt;name&gt;hbase.cluster.distributed&lt;/name&gt; 

        &lt;name&gt;hbase.rootdir&lt;/name&gt; 

        &lt;value&gt;hdfs://127.0.0.1:8001/hbase&lt;/value&gt; 

        &lt;name&gt;hbase.zookeeper.quorum&lt;/name&gt; 

其中hbase.rootdir配置的是hdfs位址,ip:port要和hadoop/core-site.xml中的fs.defaultfs保持一緻

其中hbase.zookeeper.quorum是zookeeper的位址,可以配多個,我們試驗用就先配一個

啟動hbase,執行:

./bin/start-hbase.sh 

這時有可能會讓你輸入本地機器的密碼

啟動成功後可以看到幾個程序起來,包括zookeeper的hquorumpeer和hbase的hmaster、hregionserver

下面我們試驗一下hbase的使用,執行:

hbase(main):001:0&gt; status 

1 active master, 0 backup masters, 1 servers, 0 dead, 3.0000 average load 

建立一張表

hbase(main):004:0&gt; create 'table1','field1' 

0 row(s) in 1.3430 seconds 

=&gt; hbase::table - table1 

擷取一張表

hbase(main):005:0&gt; t1 = get_table('table1') 

0 row(s) in 0.0010 seconds 

添加一行

hbase(main):008:0&gt; t1.put 'row1', 'field1:qualifier1', 'value1' 

0 row(s) in 0.4160 seconds 

讀取全部

hbase(main):009:0&gt; t1.scan 

row                                                                 column+cell 

 row1                                                               column=field1:qualifier1, timestamp=1470621285068, value=value1 

1 row(s) in 0.1000 seconds 

我們同時也看到hdfs中多出了hbase存儲的目錄:

[root@myay hbase]# ./hadoop/bin/hadoop fs -ls /hbase 

found 7 items 

drwxr-xr-x   - root supergroup          0 2016-08-08 09:05 /hbase/.tmp 

drwxr-xr-x   - root supergroup          0 2016-08-08 09:58 /hbase/masterprocwals 

drwxr-xr-x   - root supergroup          0 2016-08-08 09:05 /hbase/wals 

drwxr-xr-x   - root supergroup          0 2016-08-08 09:05 /hbase/data 

-rw-r--r--   3 root supergroup         42 2016-08-08 09:05 /hbase/hbase.id 

-rw-r--r--   3 root supergroup          7 2016-08-08 09:05 /hbase/hbase.version 

drwxr-xr-x   - root supergroup          0 2016-08-08 09:24 /hbase/oldwals 

這說明hbase是以hdfs為存儲媒體的,是以它具有分布式存儲擁有的所有優點

hbase的架構如下:

其中hmaster負責管理hregionserver以實作負載均衡,負責管理和配置設定hregion(資料分片),還負責管理命名空間和table中繼資料,以及權限控制

hregionserver負責管理本地的hregion、管理資料以及和hdfs互動。

zookeeper負責叢集的協調(如hmaster主從的failover)以及叢集狀态資訊的存儲

用戶端傳輸資料直接和hregionserver通信

hive的部署

解壓後,我們先準備hdfs,執行:

[root@myay hadoop]# ./hadoop/bin/hadoop fs -mkdir /tmp 

[root@myay hadoop]# ./hadoop/bin/hadoop fs -mkdir /user 

[root@myay hadoop]# ./hadoop/bin/hadoop fs -mkdir /user/hive 

[root@myay hadoop]# ./hadoop/bin/hadoop fs -mkdir /user/hive/warehourse 

[root@myay hadoop]# ./hadoop/bin/hadoop fs -chmod g+w /tmp 

[root@myay hadoop]# ./hadoop/bin/hadoop fs -chmod g+w /user/hive/warehourse 

使用hive必須提前設定好hadoop_home環境變量,這樣它可以自動找到我們的hdfs作為存儲,不妨我們把各種home和各種path都配置好,如:

hadoop_home=/data/apache/hadoop 

export hadoop_home 

hbase_home=/data/apache/hbase 

export hbase_home 

hive_home=/data/apache/hive 

export hive_home 

path=$path:$home/bin 

path=$path:$hbase_home/bin 

path=$path:$hive_home/bin 

path=$path:$hadoop_home/bin 

export path 

拷貝建立hive-site.xml、hive-log4j2.properties、hive-exec-log4j2.properties,執行

[root@myay hive]# cp conf/hive-default.xml.template conf/hive-site.xml 

[root@myay hive]# cp conf/hive-log4j2.properties.template conf/hive-log4j2.properties 

[root@myay hive]# cp conf/hive-exec-log4j2.properties.template conf/hive-exec-log4j2.properties 

修改hive-site.xml,把其中的${system:java.io.tmpdir}都修改成/data/apache/tmp,你也可以自己設定成自己的tmp目錄,把${system:user.name}都換成使用者名

:%s/${system:java.io.tmpdir}/\/data\/apache\/tmp/g 

:%s/${system:user.name}/myself/g 

[root@myay hive]# schematool -dbtype derby -initschema 

成功之後我們可以以用戶端形式直接啟動hive,如:

[root@myay hive]# hive 

hive&gt; show databases; 

ok 

default 

time taken: 1.886 seconds, fetched: 1 row(s) 

hive&gt; 

試着建立個資料庫是否可以:

hive&gt; create database mydatabase; 

time taken: 0.721 seconds 

mydatabase 

time taken: 0.051 seconds, fetched: 2 row(s) 

這樣我們還是單機的hive,不能在其他機器登陸,是以我們要以server形式啟動:

nohup hiveserver2 &amp;&gt; hive.log &amp; 

預設會監聽10000端口,這時可以通過jdbc用戶端連接配接這個服務通路hive

hive的具體使用在這裡不贅述

spark部署

spark有多種部署方式,首先支援單機直接跑,如執行樣例程式:

./bin/spark-submit examples/src/main/python/pi.py 10 

它可以直接運作得出結果

下面我們說下spark叢集部署方法:

解壓安裝包後直接執行:

[root@myay spark-2.0.0-bin-hadoop2.7]# sbin/start-master.sh 

這時可以打開 http://127.0.0.1:8080/ 看到web界面如下:

根據上面的url:spark://myay:7077,我們再啟動slave:

[root@myay spark-2.0.0-bin-hadoop2.7]# ./sbin/start-slave.sh spark://myay:7077 

重新整理web界面如下:

出現了一個worker,我們可以根據需要啟動多個worker

下面我們把上面執行過的任務部署到spark叢集上執行:

./bin/spark-submit --master spark://myay:7077 examples/src/main/python/pi.py 10 

web界面如下:

spark程式也可以部署到yarn叢集上執行,也就是我們部署hadoop時啟動的yarn

我們需要提前配置好hadoop_conf_dir,如下:

hadoop_conf_dir=${hadoop_home}/etc/hadoop/ 

export hadoop_conf_dir 

下面我們把任務部署到yarn叢集上去:

./bin/spark-submit --master yarn --deploy-mode cluster examples/src/main/python/pi.py 10 

總結一下

hdfs是所有hadoop生态的底層存儲架構,它主要完成了分布式存儲系統的邏輯,凡是需要存儲的都基于其上建構

yarn是負責叢集資源管理的部分,這個資源包括計算資源和存儲資源,是以它也支撐了hdfs和各種計算子產品

map-reduce元件主要完成了map-reduce任務的排程邏輯,它依賴于hdfs作為輸入輸出及中間過程的存儲,是以在hdfs之上,它也依賴yarn為它配置設定資源,是以也在yarn之上

hbase基于hdfs存儲,通過獨立的服務管理起來,是以僅在hdfs之上

hive基于hdfs存儲,通過獨立的服務管理起來,是以僅在hdfs之上

spark基于hdfs存儲,即可以依賴yarn做資源配置設定計算資源也可以通過獨立的服務管理,是以在hdfs之上也在yarn之上,從結構上看它和mapreduce一層比較像

總之,每一個系統負責了自己擅長的一部分,同時互相依托,形成了整個hadoop生态。

作者:佚名

來源:51cto