1、大數據概述:復習習題集上的例題即可
大數據的特征:
1:數據量大(volume)
非結構化數據的超大規模增長導致數據集合的規模不斷擴大,數據單位已經從GB級到TB級再到PB級,甚至開始以EB和ZB來計數。
2:類型繁多(variety)
大數據的類型不僅包括網絡日志、音頻、視頻、圖片、地理位置信息等結構化數據,還包括半結構化數據甚至是非結構化數據,具有異構性和多樣性的特點。
3:價值密度低(value)
大數據價值密度相對較低。如隨着物聯網的廣泛應用,信息感知無處不在,信息海量,但價值密度較低,存在大量不相關信息。因此需要對未來趨勢與模式作可預測分析,利用機器學習、人工智能等進行深度復雜分析。而如何通過強大的機器算法更迅速地完成數據的價值提煉,是大數據時代亟待解決的難題。雖然單位數據的價值密度在不斷降低,但是數據的整體價值在提高。
4:處理速度快(velocity)
處理速度快,時效性要求高。需要實時分析而非批量式分析,數據的輸入、處理和分析連貫性地處理,這是大數據區分於傳統數據挖掘最顯著的特征。
大數據的應用:
- 互聯網行業,通過大數據分析客戶行為,進行商品推薦和針對性的廣告投放
- 個人生活:分析個人生活行為習慣,提供更周到的個性化服務
- 物流行業:優化物流網絡,提高物流效率,降低物流成本
大數據關鍵技術:
大數據計算模式:
- 批處理計算:MapReduce、Spark
- 流計算:Storm,S4
- 圖計算:GraphX,Hama
- 查詢分析計算:Impala,Hive
大數據、雲計算、物聯網的關系:
區別:大數據側重於對海量數據的處理、存儲和分析。雲計算側重於整合和優化各種IT資源。物聯網側重於實現物物相連,應用創新。
聯系:大數據根植於雲計算,很多技術都來自於雲計算。反之,大數據也為雲計算提供了”用武之地“。物聯網的傳感器產生大量數據,需要借助雲計算和大數據技術,實現物聯網大數據的存儲、分析和處理。
2、Hadoop:注意單機安裝和偽分布式安裝的區別,以及Hadoop中塊的概念及意義!
單機模式(standalone)
單機模式是Hadoop的默認模式。這種模式在一台單機上運行,沒有分布式文件系統,而是直接讀寫本地操作系統的文件系統。
偽分布模式(Pseudo-Distributed Mode)
這種模式也是在一台單機上運行,但用不同的Java進程模仿分布式運行中的各類結點
偽分布模式在“單節點集群”上運行Hadoop,其中所有的守護進程都運行在同一台機器上。該模式在單機模式之上增加了代碼調試功能,允許你檢查內存使用情況,HDFS輸入輸出,以及其他的守護進程交互。
全分布模式(Fully Distributed Mode)
Hadoop守護進程運行在一個集群上
塊的概念即意義:
在HDFS系統中,為了便於文件的管理和備份,引入分塊概念(block)。這里的 塊 是HDFS存儲系統當中的最小單位,HDFS默認定義一個塊的大小為64MB。當有文件上傳到HDFS上時,若文件大小大於設置的塊大小,則該文件會被切分存儲為多個塊,多個塊可以存放在不同的DataNode上,整個過程中 HDFS系統會保證一個塊存儲在一個datanode上 。但值得注意的是 如果某文件大小沒有到達64MB,該文件並不會占據整個塊空間 。
關於塊的大小:
設計較大的塊,可以把尋址開銷分攤到較多的數據中,降低了單位數據的尋址開銷。
但也不宜過大,MapReduce中Map任務一次只處理一個塊中的數據,啟動任務太少,會降低作業並行處理速度。
設置數據塊的好處:
- 支持大規模文件存儲:文件以塊為單位進行存儲,一個大規模文件可以被分拆成若干個文件塊,不同的文件塊可以被分發到不同的節點上,因此,一個文件的大小不會受到單個節點的存儲容量的限制,可以遠遠大於網絡中任意節點的存儲容量
- 簡化系統設計:首先,大大簡化了存儲管理,因為文件塊大小是固定的,這樣就可以很容易計算出一個節點可以存儲多少文件塊;其次,方便了元數據的管理,元數據不需要和文件塊一起存儲,可以由其他系統負責管理元數據
- 適合數據備份:每個文件塊都可以冗余存儲到多個節點上,大大提高了系統的容錯性和可用性
3、HDFS
(1)名稱節點的3大數據結構(FsImage、EditLog以及放在內存中的元數據)的構成,以及合作關系!
- FsImage:維護文件系統樹 以及 文件樹中的文件和文件夾的元數據;
- EditLog:記錄針對文件的創建、刪除、重命名等這樣的更新操作;
- 元數據(Metadata):維護HDFS文件系統中文件和目錄的信息,分為內存元數據和元數據文件兩種。NameNode維護整個元數據。
(2)數據存放的策略
集群內:發起操作請求的數據節點
集群外:挑一台磁盤不太滿,CPU不太忙的數據節點
(3)數據上傳(復制)的流程
流水線復制:
塊向名稱節點發起寫請求,名稱節點選擇一個數據節點列表返回給客戶端,客戶端把數據寫入第一個datanode,第一個datanode接收到數據,寫入本地,然后向第二個datanode寫入數據和列表,第二個datanode把數據寫入本地,以此類推,形成流水線復制。
(4)數據錯誤的恢復
名稱節點出錯
名稱節點保存了所有的元數據信息,其中,最核心的兩大數據結構是FsImage和Editlog,如果這兩個文件發生損壞,那么整個HDFS實例將失效。因此,HDFS設置了備份機制,把這些核心文件同步復制到 備份服務器SecondaryNameNode上。當名稱節點出錯時,到遠程網絡掛載的文件系統的獲取備份的元數據信息,放到第二名稱節點上恢復,然后就可以根據備份服務器SecondaryNameNode中的FsImage和Editlog數據進行恢復。
數據節點出錯
每個數據節點會定期向名稱節點發送“心跳”信息,向名稱節點報告自己的狀態
當數據節點發生故障,或者網絡發生斷網時,名稱節點就無法收到來自一些數據節點的心跳信息,這時,這些數據節點就會被標記為“宕機”,節點上面的所有數據都會被標記為“不可讀”,名稱節點不會再給它們發送任何I/O請求
這時,有可能出現一種情形,即由於一些數據節點的不可用,會導致一些數據塊的副本數量小於冗余因子
名稱節點會定期檢查這種情況,一旦發現某個數據塊的副本數量小於冗余因子,就會啟動數據冗余復制,為它生成新的副本。
HDFS和其它分布式文件系統的最大區別就是可以調整冗余數據的位置
數據出錯
網絡傳輸和磁盤錯誤等因素,都會造成數據錯誤
客戶端在讀取到數據后,會采用md5和sha1對數據塊進行校驗,以確定讀取到正確的數據
在文件被創建時,客戶端就會對每一個文件塊進行信息摘錄,並把這些信息寫入到同一個路徑的隱藏文件里面
當客戶端讀取文件的時候,會先讀取該信息文件,然后,利用該信息文件對每個讀取的數據塊進行校驗,如果校驗出錯,客戶端就會請求到另外一個數據節點讀取該文件塊,並且向名稱節點報告這個文件塊有錯誤,名稱節點會定期檢查並且重新復制這個塊。
4、HBase
(1)HBase數據模型、概念視圖、物理視圖以及列式存儲
數據模型:
- 表
- 行
- 列族
- 列限定符
- 單元格
- 時間戳
概念視圖:
HBase是稀疏存儲數據的,因此某些列可以是空白的
物理視圖:
在概念視圖上面有些列是空白的,在物理視圖這樣的列實際上並不會被存儲,當請求這些空白的單元格時,會返回null值。
如果在查詢的時候不提供時間戳,那么會返回距離現在最近的那一個版本的數據,因為在存儲的時候,數據會按照時間戳來排序。
列示存儲:
(2)Region定位的三層映射結構
(3)Region服務器的工作原理
1、讀寫數據
寫數據:分配到Region服務器執行,用戶數據先寫入到MenStore和Hlog中,當寫入HLog后,才會調用commit返回客戶端。
讀數據:Region首先訪問MemStore緩存,當數據不在緩存中,才會到磁盤的StoreFile上去找。
2、緩存的刷新
系統會周期性的把MenStore緩存中的數據寫到StoreFile中,清空緩存,並在HLog上寫入一個標記。
每個Region都有一個HLog,啟動時會進行檢查,查看HLog是否已經發生寫入操作。若無,則數據已經保存到StoreFile中。若有則把更新寫入MenStore,然后寫入緩存,最后寫入StoreFile中,刪除舊的HLog。
3、Store的合並
當StoreFile文件的數量達到一個閾值的時候,才會觸發合並操作。把多個StoreFile文件合並成一個大文件。
(4)Store的工作原理
每個Store對應表中一個列族的存儲,包含一個MemStore緩存和若干個StoreFile文件。
隨着StoreFile文件數量的不斷增加,達到閾值時,觸發合並操作,多個StoreFile合並成一個大的StoreFile,當單個StoreFile的大小超過某個閾值時,又會觸發分裂操作。
(5)HLog的工作原理
每個Region服務器共用一個HLog文件,所有Region對象共有一個Hlog文件。
數據恢復:
Zookeeper實時監測每個Region服務器的狀態,當R發生故障時,Z會通知Master。系統會根據每條日志所屬的Region對象進行拆分,分別放到對應Region對象的目錄下,講失效的R重新分配到可用的R服務器中,並把對應的HLog文件也發送過去,R服務器會重做一遍HLog記錄的各種操作,把數據寫入MemStore緩存,然后寫入StoreFile文件中,完成數據恢復。
5、NoSQL:復習習題課例題即可
(1)NoSQL的四大類型:
- 鍵值數據庫:Redis、Riak
- 列族數據庫:HBase,HadoopDB
- 文檔數據庫:RavenDB,SosoDB
- 圖數據庫:OrientDB,GraphDB
(2)CAP理論:
- C(一致性):多點的數據是一致的;
- A(可用性):快速獲取數據,在確定的時間返回操作結果;
- P(分區容忍性):當出現網絡分區(系統部分節點間無法通信),分離的系統也能夠正常運行;
- CA:嚴重影響系統的可拓展性
- CP:網絡分區時,受影響的服務需要等待數據一致,在此期間無法對外服務
- AP:允許系統返回不一樣的數據
(3)最終一致性:
概念:允許后續的訪問操作可用暫時讀不到更新后的數據,但一段時間后,必須最終讀到更新后的數據。(只要最終數據是一致的就可以,不需要每時每刻數據都一致)
分類:
- 因果一致性
- 讀己之所寫一致性
- 會話一致性
- 單調讀一致性
- 單調寫一致性
6、MapReduce:
(1)注意基本關系運算(交,並,差,內外左右連接)的MapReduce中Map端、Shuffle操作以及Reduce端的設計。
基本關系運算:
交
並
差
除
笛卡爾積:R*S 即R的每一行和S的每一行連接
外連接(out join)
外連接分為外左連接(left outer join)和外右連接(right outer join)
注釋:left outer join 與 left join 等價, 一般寫成left join
right outer join 與 right join等價,一般寫成right join
左連接,取左邊的表的全部,右邊的表按條件,符合的顯示,不符合則顯示null
舉例:select <select list> from A left join B on A.id=B.id
右連接:取右邊的表的全部,左邊的表按條件,符合的顯示,不符合則顯示null
舉例:select <select list> from A right join B on A.id=B.id
內連接(inner join)
內連接:也稱為等值連接,返回兩張表都滿足條件的部分
注釋:inner join 就等於 join
設計:
用MapReduce實現關系的自然連接:
假設有關系R(A,B)和S(B,C),對二者進行自然連接操作
使用Map過程,把來自R的每個元組<a,b>轉換成一個鍵值對<b, <R,a>>,其中的鍵就是屬性B的值。把關系R包含到值中,這樣做使得我們可以在Reduce階段,只把那些來自R的元組和來自S的元組進行匹配。類似地,使用Map過程,把來自S的每個元組<b,c>,轉換成一個鍵值對<b,<S,c>> 所有具有相同B值的元組被發送到同一個Reduce進程中.
Reduce進程的任務是,把來自關系R和S的、具有相同屬性B值的元組進行合並 Reduce進程的輸出則是連接后的元組<a,b,c>,輸出被寫到一個單獨的輸出文件中
(2)盡量搞懂大作業3、5的MapReduce設計
3. Top-k 極值問題
本題為求解一堆數據中最大的前 k 個數,那么我們最終的輸出應該是<商品,數量>的 形式。然而,本題中給出的是多個文件,且每個文件中會有商品的重復,因此,本問題可以 由兩種方式來解決,一種是自己不寫排序過程,2 次 MapReduce 即可完成;一種是把處理 邏輯放在 Reduce 中。 解題思路 1:首先,將該問題變成一個經典的 wordcount 問題,word 即為商品名稱,對 應的 count 可以直接從原始文件中取,這樣 Map 任務即輸出<商品,數量>的集合,假設一 個文件對應一個 Map 任務,則 Reduce 端不需要任何處理,直接將最終的<數量,商品>寫入 HDFS 即可,之所以是<數量,商品>的集合,是因為 Shuffle 過程中會對 key 進行排序,若 key 為數量,則我們不需要寫任何排序代碼,將第一次 MapReduce 生成的文件直接進行 MapReduce 任務,Map 直接讀即可,Reduce 端直接迭代並倒序輸出即可,不需要任何多余 的代碼。該方法代碼量非常少(可能自己寫的代碼只要十幾行),實現也非常容易。 解題思路 2:該思路只需要一次 MapReduce 過程,Map 過程類似於 wordcount 過程,在 Reduce 任務中,可以獲得所有商品的銷售總量的哈希表,基於這個哈希表,我們可以設計 非常多高效的方法進行 Top-k 極值的選擇,最簡單的方法就是先排序,再取前 k 個,代碼量 也很少,且容易實現,但時間復雜度為 O(n2 )。
5. 購物籃數據的關聯分析
本題為求解所有的關聯集合,用白話來說,給定某個集合 S,若 S 出現在數據集中的次 數達到了 d 以上,則 S 就可以輸出了,因此,本題轉化為求 S 的個數的問題,基於 MapReduce 的特性,我們 Map 的輸出一定得是<集合,在當前數據集中存在的個數>這樣的一個鍵值對, 然而,數據集給的是一條一條的記錄,一個記錄里可能包含了很多的集合,因此,本題的難 點在於如何把這些集合都拆解出來,而拆解集合其實就是一個求子集的過程,每讀到一條購 物記錄,則將其所有子集拆出來(只含 1 項的去掉),然后轉化為<子集,1>的形式,這樣 又變成了 1 個 wordcount 問題,Reduce 過程幾乎不用做任何處理。所以,當數據集被讀入時, 每讀到一個購物記錄,則生成該購物記錄的所有子集,剔除其中只含有 1 個商品的子集,並 將每個子集計數為 1,並輸出。Reduce 端不需要做任何處理,只要判斷某個集合的計數是否 不小於 d,若不小於 d 則輸出即可,本題完結。
7、Spark
(1)窄依賴、寬依賴的概念
窄依賴定義:一個父RDD的partition至多被子RDD的某個partition使用一次。 一對一、多對一。不會有shuffle的產生。父RDD的一個分區去到子RDD的一個分區。
寬依賴定義: 一個父RDD的partition會被子RDD的某個partition使用多次。 一對多。會有shuffle的產生。父RDD的一個分區的數據去到子RDD的不同分區里面。
(2)stage的划分
- Stage概念
Spark任務會根據RDD之間的依賴關系,形成一個DAG有向無環圖,DAG會提交給DAGScheduler,DAGScheduler會把DAG划分相互依賴的多個stage,划分stage的依據就是RDD之間的寬窄依賴。遇到寬依賴就划分stage,每個stage包含一個或多個task任務。然后將這些task以taskSet的形式提交給TaskScheduler運行。 stage是由一組並行的task組成。
- stage切割規則
切割規則:從后往前,遇到寬依賴就切割stage。
(3)RDD的概念,對“血緣關系”以及“惰性調用”的理解
RDD概念:RDD(Resilient Distributed Dataset)叫做分布式數據集,是Spark中最基本的數據抽象,它代表一個不可變、可分區、彈性、里面的元素可並行計算的集合。
RDD的操作:轉化操作(Transformation)和行動操作(Action)。RDD 的轉化操作是返回一個新的 RDD的操作,比如 map()和 filter(),而行動操作則是向驅動器程序返回結果或把結果寫入外部系統的操作。比如 count() 和 first()。
血緣關系:即依賴關系,就是在大量記錄上執行的單個文件操作,將創建的RDD的一系列的血緣記錄下來,以便恢復丟失的數據,記錄的是粗顆粒度的轉換操作行為。
惰性調用:RDD采用了惰性調用,即在RDD的執行過程中,真正的計算發生在RDD的“行動”操作,對於“行動”之前的所有“轉換”操作,Spark只是記錄下“轉換”操作應用的一些基礎數據集以及RDD生成的軌跡,即相互之間的依賴關系,而不會觸發真正的計算。
(4)RDD的操作,以及各個操作的辨析(圖10-12)
RDD運行過程
通過對RDD概念、依賴關系和階段划分的介紹,結合之前介紹的Spark運行基本流程,這里再總結一下RDD在Spark架構中的運行過程(如圖9-12所示):
(1)創建RDD對象;
(2)SparkContext負責計算RDD之間的依賴關系,構建DAG;
(3)DAGScheduler負責把DAG圖分解成多個階段,每個階段中包含了多個任務,每個任務會被任務調度器分發給各個工作節點(Worker Node)上的Executor去執行。
(5)RDD的容錯方式
容錯方式:Spark的容錯策略主要是根據RDD依賴關系重新計算、對RDD做cache、對RDD做checkpoint手段完成RDD計算的故障容錯。
- 對於寬依賴實質是指一個父RDD的分區會對應一個或多個子RDD多個分區,在此情況下,如果出現部分計算結果丟失,單一計算丟失的數據無法達到效果,便采用計算該步驟的所有數據,從而導致計算數據重復。
- 對於窄依賴而言,由於窄依賴的一個RDD 分區最多對應一個子RDD 分區,在此情況下出現計算結果丟失,由於計算結果只依賴父RDD相關數據有關,所以不需要計算全部數據,只需計算部分數據即可。
Spark會對數據檢查點開銷和重新計算RDD分區的開銷進行比較,自動選擇最優的恢復策略。
(6)徹底搞懂RDD的wordcount代碼(10.5.2)
import org.apache.spark.SparkContext import org.apache.spark.SparkContext._ import org.apache.spark.SparkConf object WordCount { def main(args: Array[String]) { val inputFile = "file:///usr/local/spark/mycode/wordcount/word.txt" //用於統計的文本文件 val conf = new SparkConf().setAppName("WordCount").setMaster("local[2]") val sc = new SparkContext(conf) val textFile = sc.textFile(inputFile) val wordCount = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b) wordCount.foreach(println) } }
8、Storm
(1)徹底讀懂Storm的wordcount代碼(11.4.5)
public static class WordCount extends BaseBasicBolt { Map<String, Integer> counts = new HashMap<String, Integer>(); public void execute(Tuple tuple, BasicOutputCollector collector) { String word = tuple.getString(0); Integer count = counts.get(word); if (count == null) count = 0; count++; counts.put(word, count); collector.emit(new Values(word, count)); }
(2)會畫拓撲圖
一個Topology是由spouts和bolts組成的圖,Topology是storm里面的最高一級的抽象(類似job),Topology里面的每一個處理節點都包含處理邏輯,而節點之間的連接則表示數據流動的方向。
Topology里面的每一個節點都是並行運行的,在topology里面,你可以指定每個節點的並行度,storm則會在集群里分配那么多線程來同時計算。
一個topology會一直執行,知道你手動kill掉他,storm會自動重新執行失敗的任務,並且storm可以保證不會有數據丟失(如果開啟了高可靠性的話)。
(3)Storm中各個分組策略的辨析
1)Shuffle Grouping: 隨機分組,輪詢,平均分配。隨機派發stream里面的tuple,保證每個bolt接收到的tuple數目大致相同。
2)Fields Grouping:按字段分組,比如按userid來分組,具有同樣userid的tuple會被分到相同的Bolts里的一個task,而不同的userid則會被分配到不同的bolts里的task。
3)All Grouping:廣播發送,對於每一個tuple,所有的bolts都會收到。
4)Global Grouping:全局分組,這個tuple被分配到storm中的一個bolt的其中一個task。再具體一點就是分配給id值最低的那個task。
5)Non Grouping:不分組,這stream grouping個分組的意思是說stream不關心到底誰會收到它的tuple。目前這種分組和Shuffle grouping是一樣的效果。在多線程情況下不平均分配。
6)Direct Grouping:直接分組,這是一種比較特別的分組方法,用這種分組意味着消息的發送者指定由消息接收者的哪個task處理這個消息。只有被聲明為Direct Stream的消息流可以聲明這種分組方法。而且這種消息tuple必須使用emitDirect方法來發射。消息處理者可以通過TopologyContext來獲取處理它的消息的task的id (OutputCollector.emit方法也會返回task的id)。
7)Local or shuffle grouping:如果目標bolt有一個或者多個task在同一個工作進程中,tuple將會被隨機發送給這些tasks。否則,和普通的Shuffle Grouping行為一致。