福利!大資料技術框架整理
大資料離線部分
HDFS
1:HDFS的架構部分及工作原理
NameNode:負責管理元素據,將資訊儲存在記憶體中
DataNode:儲存資料,以塊的形式儲存。啟動後需要定時的向NameNode傳送心跳,報告自身儲存的塊資訊
2:HDFS的上傳過程
3:HDFS的下載
4:NameNode的元資料安全機制
以記日誌的形式將每一個操作寫在磁碟的日誌檔案中,然後藉助Secondary NameNode的checkpoint功能將fsImage和日誌進行合併。
重點:記住checkpoint工作過程
5:如果伺服器的磁碟壞了,如何挽救資料?
配置多個dfs.namenode.name.dir 路徑為本地磁碟路徑和nfs網路磁碟路徑。
6:hdfs叢集中,受到拓展瓶頸的是NameNode還是Datanode?
是NameNode,因為DataNode不夠可以很方便的水平拓展,而工作的NameNode只有一個,他的儲存能力完全取決於他的記憶體。
但是其實NameNode一般不會成為瓶頸,因為一個塊記錄的元資料資訊大小約為150B,如果每一個塊大小為128M的話,那麼15G的NameNode記憶體可以儲存12PB的資料。
7:datanode明明已啟動,但是叢集中的可用datanode列表中就是沒有,怎麼辦?
在她的Data目錄下,已經有其他NameNode的標記,這個NameNode不認。
8:檔案下載到window中,為什麼會報錯?
預設使用作業系統的核心進行磁碟資料的寫入,也就是需要一個winutil的工具,而預設的安裝包中不提供,所以需要編譯原始碼或者設定為使用Java的進行磁碟寫入。
9:hadoop的HA(高可用)
MapReduce
1:MapReduce中,fileinputformat -> map -> shuffle -> reduce的過程
2:MapReduce中,job提交的過程
3:自定義Javabean作為資料,需要extends writableandCompareble介面。
4:自定義outputformat,進行不同方向的處理。
5:MapReduce的一些應用場景
1、排序並且求 TOPOne 和TOPN
2、求某個使用者前幾個月的總流量,並且選擇出流量前幾名的使用者。
3、reduce端的join
4、map端join
5、求共同好友問題
hive
1:什麼是hive?
一個將sql轉化為MapReduce程式的、單機版的、資料倉庫工具。通過關係型資料庫(mysql等)來記錄表元資料資訊。真正的資料在HDFS中。
Hive利用HDFS儲存資料,利用MapReduce查詢分析資料
hive2.0版本之後,都是基於Spark處理了。
安裝的時候,需要注意jline的版本衝突。
2:如何啟動?
3:執行的sql的形式
hiveshell、 hive -e “sql命令”、 hive -f “一個包含著很多SQL語句的檔案”
4:hive的建立表操作
內部表、外部表 就差連個關鍵字(external 和 location)
分割槽表、分桶表
5:hive查詢表
join
動態分割槽
分組查詢
複雜的那個累計報表操作。
6:hive自定義函式(UDF)
sqoop
利用hadoop的map端進行資料的並行匯入匯出。
安裝在HDFS上,配置HDFS的路徑和Hive路徑即可。
flume
1:agent:sources 、 channel 、 sinks
2:sources:exec、spooldir、arvo (加一個攔截器)
3:channel:men 、 disk
4:sinks:arvo 、HDFS、kafka
5:flume安裝在資料來源這一邊。
6:如何自定義攔截器?
class myiterceptor implements Iterceptor
//裡面有一個靜態的公共內部類。
public static class mybuilder implements Iterceptor.Builder
7:如何實現flume的多級連線,以及如何實現高可用?
大資料實時storm部分
storm
1 : storm是一個實時的計算框架,只負責計算,不負責儲存。它通過spout的open和nextTuple方法去外部儲存系統(kafka)獲取資料,然後傳送給後續的bolt處理,
bolt利用prepare和execute方法處理完成後,繼續往後續的bolt傳送,或者根據輸出目錄,把資訊寫到指定的外部儲存系統中。
2:storm的資料不丟失原理
交叉收到的資料做異或元算中間結果不為0的原理。
3:設定spout_max_pending (可以限流)
4:jstorm的通訊機制,每一個:worker都有一個接受執行緒和輸出執行緒
5:storm的架構分析
nimbus、zookeeper、supervisor、worker
nimbus:接受任務請求,並且進行任務的分發,最後寫入到zookeeper中。
supervisor:接受nimbus的任務排程,然後啟動和管理屬於自己的worker程序,supervisor是可以快速失敗的,不影響任務的執行。
我們可以寫一個指令碼來監控supervisor的程序,如果不存在了,立馬啟動,就可以了。
worker:啟動spoutTask、boltTask等等任務,去執行業務邏輯。
6:storm的程式設計模型
topology:由spout和bolt組成的一個流程圖。他描述著本次任務的資訊
spout:
open
nexttuple
declareOutputFields
bolt:
prepare
execute
declareOutputFields
6:storm的tuple結構,它裡面有兩個資料結構,一個list、一個是map
list:記錄著資訊
map:記錄著每個欄位對應的下表,通過找到下邊再去上面的list中找資料。
7:storm任務提交的過程
kafka
1、kafka和jms的區別
2、kafka的topic理解
topic是邏輯存在的,真正在物理磁碟中的體現是partitioner,一個topic可以對應多個partition,不同的paritition存放在不同的broker中,以提高併發儲存能力。
3、partitioner
partition是topic資訊在屋裡儲存中的具體體現,在磁碟中它是一個資料夾,名字是topic名字_partition編號。4、segment
每個partition對對應多個segment檔案,預設大小是1G,為了快速定位到指定的offset位置。
5、kafka為什麼這麼快
1/使用了作業系統使用的pagecache快取,快取大,快取到一定量的資料時,以順序寫入的方 式寫入到磁碟中。
因為:磁碟順序寫入的方式非常的快=>600MB/s,而隨機儲存只有100kb/s左右。
2/使用作業系統的sendfile技術。在讀取資訊傳送的時候,不需要經過使用者區,而是在os端直接傳送,可以減少很多步驟。
6、為什麼要多個partitioner7、為什麼每個partitioner需要切分為多個segment檔案
8、kafka的HA
對partitioner分割槽進行備份,利用zookeeper的選舉機制選擇leader。資料的生產儲存和消費讀取都是有leader負責,其他的replicatition只是負責備份而已。
9、kafka如何用shell指令碼來講一個檔案讀寫進去?10、kafka如何用JavaAPI實現生產者和消費者?
大資料一站式解決方案:Scala和Spark部分
scala回顧
1、如何定義變數
2、如何定義函式、方法,如何在將函式作為方法的引數傳入進去?
3、條件判斷語句,迴圈控制語句
4、集合操作:Array、list、set、tuple、map (注意:可變和不可變的區別)5、樣例類的使用6、trit、抽象類的使用7、主構造器和輔助構造器的使用
8、scala的高階特性
高階函式:作為值得函式、匿名函式、閉包、柯里化
隱式轉換:一個類物件中,如果他沒有摸一個功能,但是我們有想要它實現,可以使用英式轉換的方式。
object MyPredef{
//定義隱式轉換方法
implicit def fileReadToRichFile(file: File)=new RichFile(file)
}
使用:
import MyPredef._9、Actor
寫起來像多執行緒,用起來像socket10、akka
ActorSystem.actorOf()建立一個Actor,
建立的同時,就是執行Actor中的prestart方法,去初始化一些資訊。
Spark RDD
1、SparkRDD叫做:彈性分散式資料集,其實就是一個類,用來描述:任務的資料從哪裡讀取、用那個算進行計算、得到的結果有存放在哪裡、RDD之間的依賴關係是款以來還是窄依賴
2、RDD有五個特點
一系列分割槽
每個運算元作用在每個分割槽上
一系列依賴關係
最有位置(如果從HDFS上讀取資料)
3、RDD的兩種運算元Transformation和Action
Transformation是懶載入,只是定義了這個運算元的任務,該如何做,但是還沒有做。
Action是立即執行,當執行到Action時,會觸發DAGSchudle切分stage,切分完成後,有TaskScheduler將任務通過DriverActor傳送到executor中執行。
4、RDD的幾個複雜的Transformation
->combineByKey(x=>x,(a:List[String],b:String) => a :+ b,
(m:List[String],n:List[String])=> m ++ n)
第一個引數表示分組後的第一個值如何處理,
第二個引數表示後續的值和前一個值如何處理,
第三個引數表示,map端處理完成後,在reduce端如何對這些list進行處理。
->aggregate(“初始量,可以是String也可以是int”)(第一個func,第二個func)
初始量作用於沒一個分割槽,第一個func作用於map端,第二個func作用於reduce端。
->reduceByKey(_+_) 作用於map端和reduce端,可以進行區域性聚合。
其實reduceByKey和aggregateByKey在底層都呼叫了combineByKey方法來實現響應的功能。
->mapPartitions
對每一個分割槽進行操作,直接在裡面使用匿名函式即可
當然如果邏輯非常複雜也是可以考慮在外面先定義好這個函式之後在傳輸進去。
rdd1.mapPartitions((it:Iterator[String]) => {
it.toList.map(x => (x,1)).iterator
})
>mapPartitionsWithIndex
首先定義一個函式,當然也可以寫在裡面作為匿名函式
val func = (index:Int, it:Iterator[Int]) => {
it.toList.map(x => ("index:" + index, x)).iterator
}
rdd1.mapPartitionsWithIndex(func).collect
5、RDD自定義Partitioner
//自定義分割槽器,重寫裡面的getPartition方法和numPartitions方法。
//構造這個物件的時候,就把所有情況的資訊傳輸過來,然後在裡面進行分類處理。
class HostPartition(hostArr:Array[String]) extends Partitioner{
//對所有的資料進行分類,每一種型別對應一個int編號。所以使用map比較合適。
val map = new mutable.HashMap[String,Int]()
for(index
map.put(hostArr(index),index)
}
//重寫getPartition的方法。
override def getPartition(key: Any): Int = {
map.getOrElse(key.toString,0)
}
override def numPartitions: Int = hostArr.length
}
應用:
val hostPartition: HostPartition = new HostPartition(hostList)
val allPartitionRDD: RDD[(String, (String, Int))] = host_url_count.partitionBy(hostPartition)
6、自定義排序規則 ==>定義一個
case class Gril(yanzhi:Int,nianling:Int) extends Ordered[Gril] with Serializable{
override def compare(that: Gril): Int = {
val yanzhiResult: Int = this.yanzhi.compareTo(that.yanzhi)
if(yanzhiResult == 0){
return this.nianling.compareTo(that.nianling)
}
return yanzhiResult
}
}
應用:
val rdd2: RDD[(String, Int, Int)] = rdd1.sortBy(msg => Gril(msg._2,msg._3))
Spark的SQLContext
1、Spark整合Hive和HDFS 只需要將Hive的hive-site.xml ; hadoop的core-site.xml和hdfs-site.xml拷貝到Spark的conf目錄下即可。Spark就知道如何使用hive的表,同時也知道去哪個NameNode哪裡都資料了。
2、DataFrame是什麼?
是一個分散式資料集,對RDD的封裝。RDD有的方法他基本上都有
3、DataFrame如何建立?
三種方式:->RDD + case class
->RDD + structType
->sqlContext.read.format.options(Map())
4、DataFrame首先需要註冊成表結構之後才可以使用sqlContext來操作。
dF.registerTempTable(“person”)
5、使用sqlContext ==> 返回一個DataFrame
sqlContext.sql(“select * from person”)
6、DataFrame將資料寫入到HDFS或者mysql中
val prop = new Properties()
prop.put("user", "root")
prop.put("password", "815325")
//如果資料庫中沒有這個表,那麼他也會建立一張表(很強大)
resultDF.write.mode("append").jdbc("jdbc:mysql://localhost:3306/bigdata","result",prop)
結語
感謝您的觀看,如有不足之處,歡迎批評指正。
為了幫助大家讓學習變得輕鬆、高效,給大家免費分享一大批資料,幫助大家在成為大資料工程師,乃至架構師的路上披荊斬棘。在這裡給大家推薦一個大資料學習交流圈:658558542 歡迎大家進群交流討論,學習交流,共同進步。
當真正開始學習的時候難免不知道從哪入手,導致效率低下影響繼續學習的信心。
但最重要的是不知道哪些技術需要重點掌握,學習時頻繁踩坑,最終浪費大量時間,所以有有效資源還是很有必要的。
最後祝福所有遇到瓶疾且不知道怎麼辦的大資料程式設計師們,祝福大家在往後的工作與面試中一切順利。