Spark進(jìn)行IO不僅考慮本地開銷,還有數(shù)據(jù)在不同主機(jī)之間的開銷袜硫,同時(shí)對(duì)數(shù)據(jù)的尋址方式也要改變婉陷,以應(yīng)對(duì)大數(shù)據(jù)
序列化
- 用于進(jìn)程間通信官研,不同節(jié)點(diǎn)之間數(shù)據(jù)傳輸
- 用于持久化存儲(chǔ)到磁盤,序列化速度影響集群總體效率
在默認(rèn)情況下担神,Spark采用Java的ObjectOutputStream序列化一個(gè)對(duì)象始花。該方式適用于所有實(shí)現(xiàn)了java.io.Serializable的類酷宵。Java序列化非常靈活,但是速度較慢炕置。Spark也能使用Kryo序列化對(duì)象男韧。Kryo不但速度極快,而且產(chǎn)生的結(jié)果更為緊湊(通常能提高10倍)甚纲。Kryo的缺點(diǎn)是不支持所有類型
壓縮
- 序列化后的數(shù)據(jù)進(jìn)行壓縮朦前,減少空間開銷
- 大片連續(xù)區(qū)域進(jìn)行數(shù)據(jù)存儲(chǔ)并且存儲(chǔ)區(qū)域中數(shù)據(jù)重復(fù)性高的狀況下,數(shù)據(jù)適合進(jìn)行壓縮節(jié)省空間
Spark采用兩種壓縮算法这溅,snappy和LZF悲靴,可以自定義壓縮庫
Snappy壓縮速度更快,LZF壓縮比更高
塊管理
RDD邏輯上按照Partition分塊耸三,RDD可以看作是一個(gè)分區(qū)作為數(shù)據(jù)項(xiàng)的分布式數(shù)組浇揩,物理上存儲(chǔ)單位是Block,一個(gè)Partition對(duì)應(yīng)一個(gè)Block积锅,partitionId通過元數(shù)據(jù)映射到物理Block
整體IO管理分為兩個(gè)層次
通信層:IO模塊采用Master-Slave結(jié)構(gòu)實(shí)現(xiàn)通信層的架構(gòu)
存儲(chǔ)層:Spark塊數(shù)據(jù)需要存儲(chǔ)到內(nèi)存或者磁盤
BlockManager中的通信
主節(jié)點(diǎn)和從節(jié)點(diǎn)之間通過Actor傳送消息傳遞命令和狀態(tài)
數(shù)據(jù)讀寫
數(shù)據(jù)寫入:
1.RDD調(diào)用compute()方法進(jìn)行制定分區(qū)的寫入缚陷。
2.CacheManager中調(diào)用BlockManager判斷數(shù)據(jù)是否已經(jīng)寫入往核,如果未寫入則寫入聂儒。
3.BlockManager中數(shù)據(jù)與其他節(jié)點(diǎn)同步。
4.BlockManager根據(jù)存儲(chǔ)級(jí)別寫入制定的存儲(chǔ)層窜护。
5.BlockManager向主節(jié)點(diǎn)匯報(bào)存儲(chǔ)狀態(tài)谅猾。
數(shù)據(jù)讀取:
在RDD類中坐搔,通過compute方法調(diào)用iterator讀寫某個(gè)分區(qū)(Partition)敬矩,作為數(shù)據(jù)讀取的入口弧岳。分區(qū)是邏輯概念凳忙,在物理上是一個(gè)Block业踏。
通過BlockManager讀取代碼進(jìn)入讀取邏輯,在本地同步讀取數(shù)據(jù)塊涧卵,首先看能否在內(nèi)存讀取數(shù)據(jù)塊勤家,如果不能讀取,則看能否從Tacjyon讀取數(shù)據(jù)塊柳恐,如果仍不能讀取伐脖,則看能否從本地磁盤讀取數(shù)據(jù)。如果仍不存在乐设,再看看網(wǎng)絡(luò)中其它節(jié)點(diǎn)是否有數(shù)據(jù)讼庇。