1.分佈式系統概述
注:由於大數據技術領域的各類技術框架基本上都是分佈式系統,因此,理解hadoop、storm、spark等技術框架,都需要具備基本的分佈式系統概念
1.1 分佈式軟件系統(Distributed Software Systems)
² 該軟件系統會劃分成多個子系統或模塊,各自運行在不同的機器上,子系統或模塊之間通過網絡通信進行協作,實現最終的整體功能
² 比如分佈式操作系統、分佈式程序設計語言及其編譯(解釋)系統、分佈式文件系統和分佈式數據庫系統等。
1.2 分佈式軟件系統舉例:solrcloud
A. 一個solrcloud集羣通常有多臺solr服務器
B. 每一個solr服務器節點負責存儲整個索引庫的若干個shard(數據分片)
C. 每一個shard又有多臺服務器存放若干個副本互爲主備用
D. 索引的建立和查詢會在整個集羣的各個節點上併發執行
E. solrcloud集羣作爲整體對外服務,而其內部細節可對客戶端透明
總結:利用多個節點共同協作完成一項或多項具體業務功能的系統就是分佈式系統。
1.3 分佈式應用系統模擬開發
需求:可以實現由主節點將運算任務發往從節點,並將各從節點上的任務啓動;
程序清單:
AppMaster
AppSlave/APPSlaveThread
Task
程序運行邏輯流程:
2.離線數據分析流程介紹
注:本環節主要感受數據分析系統的宏觀概念及處理流程,初步理解hadoop等框架在其中的應用環節,不用過於關注代碼細節
一個應用廣泛的數據分析系統:“web日誌數據挖掘”
2.1 需求分析
2.1.1 案例名稱
“網站或APP點擊流日誌數據挖掘系統”。
(
一般中型的網站(10W的PV以上),每天會產生1G以上Web日誌文件。大型或超大型的網站,可能每小時就會產生10G的數據量。
具體來說,比如某電子商務網站,在線團購業務。每日PV數100w,獨立IP數5w。用戶通常在工作日上午10:00-12:00和下午15:00-18:00訪問量最大。日間主要是通過PC端瀏覽器訪問,休息日及夜間通過移動設備訪問較多。網站搜索瀏量佔整個網站的80%,PC用戶不足1%的用戶會消費,移動用戶有5%會消費。
對於日誌的這種規模的數據,用HADOOP進行日誌分析,是最適合不過的了。
)
2.1.2 案例需求描述
“Web點擊流日誌”包含着網站運營很重要的信息,通過日誌分析,我們可以知道網站的訪問量,哪個網頁訪問人數最多,哪個網頁最有價值,廣告轉化率、訪客的來源信息,訪客的終端信息等。
2.1.3 數據來源
本案例的數據主要由用戶的點擊行爲記錄
獲取方式:在頁面預埋一段js程序,爲頁面上想要監聽的標籤綁定事件,只要用戶點擊或移動到標籤,即可觸發ajax請求到後臺servlet程序,用log4j記錄下事件信息,從而在web服務器(nginx、tomcat等)上形成不斷增長的日誌文件。
形如:
58.215.204.118 - - [18/Sep/2013:06:51:35 +0000] "GET /wp-includes/js/jquery/jquery.js?ver=1.10.2 HTTP/1.1" 304 0 "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 (Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0" |
2.2 數據處理流程
2.2.1 流程圖解析
本案例跟典型的BI系統極其類似,整體流程如下:
但是,由於本案例的前提是處理海量數據,因而,流程中各環節所使用的技術則跟傳統BI完全不同,後續課程都會一一講解:
1) 數據採集:定製開發採集程序,或使用開源框架FLUME
2) 數據預處理:定製開發mapreduce程序運行於hadoop集羣
3) 數據倉庫技術:基於hadoop之上的Hive
4) 數據導出:基於hadoop的sqoop數據導入導出工具
5) 數據可視化:定製開發web程序或使用kettle等產品
6) 整個過程的流程調度:hadoop生態圈中的oozie工具或其他類似開源產品
2.2.2 項目技術架構圖
2.2.3 項目相關截圖
a) Mapreudce程序運行
b) 在Hive中查詢數據
c) 將統計結果導入mysql
./sqoop export --connect jdbc:mysql://localhost:3306/weblogdb --username root --password root --table t_display_xx --export-dir /user/hive/warehouse/uv/dt=2014-08-03 |
2.3 項目最終效果
經過完整的數據處理流程後,會週期性輸出各類統計指標的報表,在生產實踐中,最終需要將這些報表數據以可視化的形式展現出來,本案例採用web程序來實現數據可視化
效果如下所示:
3. 集羣搭建
3.1 HADOOP集羣搭建
3.1.1集羣簡介
HADOOP集羣具體來說包含兩個集羣:HDFS集羣和YARN集羣,兩者邏輯上分離,但物理上常在一起
HDFS集羣:
負責海量數據的存儲,集羣中的角色主要有 NameNode / DataNode
YARN集羣:
負責海量數據運算時的資源調度,集羣中的角色主要有 ResourceManager /NodeManager
(那mapreduce是什麼呢?它其實是一個應用程序開發包)
本集羣搭建案例,以5節點爲例進行搭建,角色分配如下:
hdp-node-01 NameNode SecondaryNameNode hdp-node-02 ResourceManager hdp-node-03 DataNode NodeManager hdp-node-04 DataNode NodeManager hdp-node-05 DataNode NodeManager |
部署圖如下:
3.1.2服務器準備
本案例使用虛擬機服務器來搭建HADOOP集羣,所用軟件及版本:
ü Vmware 11.0
ü Centos 6.5 64bit
3.1.3網絡環境準備
ü 採用NAT方式聯網
ü 網關地址:192.168.33.1
ü 3個服務器節點IP地址:192.168.33.101、192.168.33.102、192.168.33.103
ü 子網掩碼:255.255.255.0
3.1.4服務器系統設置
ü 添加HADOOP用戶
ü 爲HADOOP用戶分配sudoer權限
ü 同步時間
ü 設置主機名
n hdp-node-01
n hdp-node-02
n hdp-node-03
ü 配置內網域名映射:
n 192.168.33.101 hdp-node-01
n 192.168.33.102 hdp-node-02
n 192.168.33.103 hdp-node-03
ü 配置ssh免密登陸
ü 配置防火牆
3.1.5 Jdk環境安裝
ü 上傳jdk安裝包
ü 規劃安裝目錄 /home/hadoop/apps/jdk_1.7.65
ü 解壓安裝包
ü 配置環境變量 /etc/profile
3.1.6 HADOOP安裝部署
ü 上傳HADOOP安裝包
ü 規劃安裝目錄 /home/hadoop/apps/hadoop-2.6.1
ü 解壓安裝包
ü 修改配置文件 $HADOOP_HOME/etc/hadoop/
最簡化配置如下:
vi hadoop-env.sh
# The java implementation to use. export JAVA_HOME=/home/hadoop/apps/jdk1.7.0_51 |
vi core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hdp-node-01:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/HADOOP/apps/hadoop-2.6.1/tmp</value> </property> </configuration> |
vi hdfs-site.xml
<configuration> <property> <name>dfs.namenode.name.dir</name> <value>/home/hadoop/data/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/home/hadoop/data/data</value> </property>
<property> <name>dfs.replication</name> <value>3</value> </property>
<property> <name>dfs.secondary.http.address</name> <value>hdp-node-01:50090</value> </property> </configuration> |
vi mapred-site.xml
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> |
vi yarn-site.xml
<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop01</value> </property>
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration> |
vi salves
hdp-node-01 hdp-node-02 hdp-node-03 |
3.1.7 啓動集羣
初始化HDFS
bin/hadoop namenode -format |
啓動HDFS
sbin/start-dfs.sh |
啓動YARN
sbin/start-yarn.sh |
3.1.8 測試
1、上傳文件到HDFS
從本地上傳一個文本文件到hdfs的/wordcount/input目錄下
[HADOOP@hdp-node-01 ~]$ HADOOP fs -mkdir -p /wordcount/input [HADOOP@hdp-node-01 ~]$ HADOOP fs -put /home/HADOOP/somewords.txt /wordcount/input |
2、運行一個mapreduce程序
在HADOOP安裝目錄下,運行一個示例mr程序
cd $HADOOP_HOME/share/hadoop/mapreduce/ hadoop jar mapredcue-example-2.6.1.jar wordcount /wordcount/input /wordcount/output |
4 集羣使用初步
4.1 HDFS使用
1、查看集羣狀態
命令: hdfs dfsadmin –report
可以看出,集羣共有3個datanode可用
也可打開web控制檯查看HDFS集羣信息,在瀏覽器打開http://hdp-node-01:50070/
2、上傳文件到HDFS
² 查看HDFS中的目錄信息
命令: hadoop fs –ls /
² 上傳文件
命令: hadoop fs -put ./ scala-2.10.6.tgz to /
² 從HDFS下載文件
命令: hadoop fs -get /yarn-site.xml
4.2 MAPREDUCE使用
mapreduce是hadoop中的分佈式運算編程框架,只要按照其編程規範,只需要編寫少量的業務邏輯代碼即可實現一個強大的海量數據併發處理程序
4.2.1 Demo開發——wordcount
1、需求
從大量(比如T級別)文本文件中,統計出每一個單詞出現的總次數
2、mapreduce實現思路
Map階段:
a) 從HDFS的源數據文件中逐行讀取數據
b) 將每一行數據切分出單詞
c) 爲每一個單詞構造一個鍵值對(單詞,1)
d) 將鍵值對發送給reduce
Reduce階段:
a) 接收map階段輸出的單詞鍵值對
b) 將相同單詞的鍵值對匯聚成一組
c) 對每一組,遍歷組中的所有“值”,累加求和,即得到每一個單詞的總次數
d) 將(單詞,總次數)輸出到HDFS的文件中
1、 具體編碼實現
(1)定義一個mapper類
//首先要定義四個泛型的類型 //keyin: LongWritable valuein: Text //keyout: Text valueout:IntWritable
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{ //map方法的生命週期: 框架每傳一行數據就被調用一次 //key : 這一行的起始點在文件中的偏移量 //value: 這一行的內容 @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //拿到一行數據轉換爲string String line = value.toString(); //將這一行切分出各個單詞 String[] words = line.split(" "); //遍歷數組,輸出<單詞,1> for(String word:words){ context.write(new Text(word), new IntWritable(1)); } } } |
(2)定義一個reducer類
//生命週期:框架每傳遞進來一個kv組,reduce方法被調用一次 @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { //定義一個計數器 int count = 0; //遍歷這一組kv的所有v,累加到count中 for(IntWritable value:values){ count += value.get(); } context.write(key, new IntWritable(count)); } } |
(3)定義一個主類,用來描述job並提交job
public class WordCountRunner { //把業務邏輯相關的信息(哪個是mapper,哪個是reducer,要處理的數據在哪裏,輸出的結果放哪裏。。。。。。)描述成一個job對象 //把這個描述好的job提交給集羣去運行 public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job wcjob = Job.getInstance(conf); //指定我這個job所在的jar包 // wcjob.setJar("/home/hadoop/wordcount.jar"); wcjob.setJarByClass(WordCountRunner.class); wcjob.setMapperClass(WordCountMapper.class); wcjob.setReducerClass(WordCountReducer.class); //設置我們的業務邏輯Mapper類的輸出key和value的數據類型 wcjob.setMapOutputKeyClass(Text.class); wcjob.setMapOutputValueClass(IntWritable.class); //設置我們的業務邏輯Reducer類的輸出key和value的數據類型 wcjob.setOutputKeyClass(Text.class); wcjob.setOutputValueClass(IntWritable.class); //指定要處理的數據所在的位置 FileInputFormat.setInputPaths(wcjob, "hdfs://hdp-server01:9000/wordcount/data/big.txt"); //指定處理完成之後的結果所保存的位置 FileOutputFormat.setOutputPath(wcjob, new Path("hdfs://hdp-server01:9000/wordcount/output/")); //向yarn集羣提交這個job boolean res = wcjob.waitForCompletion(true); System.exit(res?0:1); } |
4.2.2 程序打包運行
1. 將程序打包
2. 準備輸入數據
vi /home/hadoop/test.txt
Hello tom Hello jim Hello ketty Hello world Ketty tom |
在hdfs上創建輸入數據文件夾:
hadoop fs mkdir -p /wordcount/input
將words.txt上傳到hdfs上
hadoop fs –put /home/hadoop/words.txt /wordcount/input
3. 將程序jar包上傳到集羣的任意一臺服務器上
4. 使用命令啓動執行wordcount程序jar包
$ hadoop jar wordcount.jar cn.itcast.bigdata.mrsimple.WordCountDriver /wordcount/input /wordcount/out
5. 查看執行結果
$ hadoop fs –cat /wordcount/out/part-r-00000