分布式計算概述
版權說明:
本文由 LeftNotEasy 原創,聯系方式wheeleast@gmail.com
本文可以被任意的轉載,請保留完整的文章(含版權說明)。如果商用,請聯系原作者。
發布于http://leftnoteasy.cnblogs.com/
前言:
云計算以及很多誤解
云計算這個概念被炒作得非常的火熱,只要跟互聯網沾邊的公司,都喜歡用上云計算這個詞。云計算其實不是一個那樣廣義的概念,云計算的定義并不是若干臺機器用某種方式管理起來,然后用于存儲或者計算這么簡單,包括很多的云殺毒、云安全、云存儲等等,都不一定是真正的云計算。
上wikipedia可以看看相對來說比較完備的云計算定義,云計算一個很重要的特性是跟虛擬化相關的,像水、電一樣為用戶提供計算的資源。另外在key features這個章節上說明了很多云計算的特性,如果某一個系統只具備了里面的一個或者很少的幾個特性,那稱其為云計算就有點那么勉強了。
云計算一些很重要的特性包括
1)可擴展性,用戶能夠方便的增加、減少計算和存儲的能力,而且有著足夠的擴展性。按這個定義、一堆GPU或者CPU組成的網格可能就很難稱為云計算了,這種超級計算機有著非常好的計算能力,但是對存儲的支持相對較差,據內部人士透露,天河的存儲能力就相當的差,做做計算還不錯,但是數據大了就只有傻眼了)
2)成本相對低廉,云計算對終端用戶而言,消費相對較低,對于公司而言,也能減少管理成本。按這個定義,某些很“高級”的服務器組成的集群就很難稱為云計算了,之前聽說廣東公安局的身份證處理電腦的硬盤是單機320T的磁盤陣列,硬盤這種東西就是,買起來很便宜,但是硬盤架非常的貴,想在單機組成一個大的磁盤陣列,那可能就非常的高了。而且云計算的集群管理成本也不高。以一個極端的例子來說,一般一個大一點(100-200臺電腦)的網吧都要配2-3個網管。但是我所在的公司幾萬臺服務器,管理服務器的人就在20個人左右,相對管理成本很低。
3)穩定性,至少在程序運行的時候,錯誤處理能夠做好,比如說N個節點計算,某個節點死機了,那程序是不是一定得重新運行?或者集群中某臺電腦的硬盤壞掉了,那這些數據會不會就丟失了?按這個定義,普通的多點存儲(簡單的將數據備份到2塊或者多塊硬盤中去),以及那些某個節點出錯了,計算任務就需要完全重跑的計算方式可能就不算云計算了(比如說MPI,這兒本章后面將會更詳細一點提到)
由此看出,云計算是一個很龐大的系統,并非一般的開源項目(大的開源項目還是可以的,比如說Hadoop)可以完成的。就算能完成,也會有這樣那樣的問題,比如Hadoop集群就沒有實現Service的常駐運行(只能跑job,也就是跑完就結束的那種)
分布式的數據挖掘
另一方面,數據挖掘也是一個很有意思、被很多人看重,也在很多領域上發揮大作用的一門學科,從個人而言,我對數據挖掘的興趣非常的大。傳統的計算機想要用數據挖掘,玩玩簡單的算法可以,但是在工業界看來,總體來說是一個玩具。比如說weka,學習算法用它還行,但是想要對大規模的數據進行處理,是不太可能的。為了進行大規模的數據處理,分布式計算就很必要了。
分布式計算分類:
一般來說,現在比較常見的并行計算有下面的方式:OpenMP, CUDA,MPI,MapReduce。
OpenMP:
是對于多核的條件下,也就是一些超級計算機可以使用的方式,一個很重要的特性是共享存儲,多個instance的關系是線程與線程的關系,也就限制了OpenMP主要是在單機(可能是超級計算機)中進行科學計算的任務。
CUDA:
這個概念是最近幾年的事情,似乎ATI最近也搞了一個通用計算的內容,主要是用GPU并聯起來進行計算,由于GPU的架構和CPU不太一樣,采用這種方式可以對某些計算為主的任務加速幾個數量級。對這一塊我不太了解,也不太清楚現在CUDA計算、存儲能力,還有穩定性等等做到什么樣的程度了。這里就不加以評論
Map-Reduce:
發揚光大從Google的論文-MapReduce: Simplified data processing on large clusters開始的。Map-Reduce將程序的運行分成了Map和Reduce兩個步驟,Map是一個讀取、處理原始數據的過程,而Reduce是根據Map處理的內容,進行整合、再處理。Reduce可以認為又是一個Map,為下一級的Reduce過程作準備,這樣數據的處理可以按這種方式進行迭代。
Map-Reduce的重點在下面的幾處:
1)運行程序的方式,Map-Reduce一般是在以GFS(Google文件系統),或者HDFS等類似的系統上面進行的,這個系統一般有諸多的如磁盤負載平衡,數據冗余(replica),數據遷移(比如說集群中的某臺硬盤壞了,這個硬盤里面的數據會用某種方式備份到其他的硬盤中去,而且保證每塊硬盤的數據量都大致平衡)。不過這里先不談數據的存儲,主要談談任務的調度。
一般像這樣的集群里面都有一百臺以上的電腦,按每個電腦8個核計算,至少會有幾百上千個CPU的資源。在運行每一個Map-Reduce的時候,用戶會先填寫需要多少的資源(CPU與內存),然后集群的負責人(可能被稱為JobMaster),會去查看當前集群中的計算資源情況,看看能否成功的運行這個作業。如果不行的話,會排隊。舉一個Map-Reduce的例子:
對于一個很大的文件(由一堆的浮點數組成的),計算這個文件中Top1000的數是什么。那么程序的運行可能是下面的過程。
a. 先在N個CPU(可能在不同的電腦中的)上運行程序,每個CPU會負責數據的一部分,計算出Top1000的數值,將結果寫入一個文件(共N份數據)
b. 在M = N/16個CPU上運行程序,每個CPU會負責上面步驟的16個結果文件,計算出這些文件中Top1000的數值,然后將結果寫入一個文件(共N / 16份數據)
c. 在O = M/16個CPU上運行程序,同樣每個CPU負責上面的16個結果文件。(共N / 256份數據)
..
按照這種方式迭代,直到求出真正的Top1000數值。
所以說,Map-Reduce的數據按每次迭代,是一個減少的過程,如果數據處理的時候有這樣的特性,那就非常適合于用Map-Reduce去解決。
2)多個進程間的數據傳遞,對Map-Reduce而言,沒有辦法進行傳統方式的進程間通信(比如說socket通信),進程間的通信純粹是用文件去聯系的,對于一個Map-Reduce任務,是多級組成的,每一級會起若干的進程,每個進程做的事情就是去讀取上一級進程生成的數據,然后處理后寫入磁盤讓下一級進程進行讀取。
這個特性使得Map-Reduce有著良好的容錯性,當某一級的某一個進程出錯了(比如說機器死機了,程序出異常了等等),JobMaster會重新調度這個進程到另外一個機器上,重新運行,如果是由于外部的問題(比如說機器死機了),一般這樣的錯誤不會使得整個任務重復運行。不過真正如果是寫程序出的邏輯問題,那程序也不能正常運行的,JobMaster會試著將失敗的進程調度幾次,如果都失敗了,則任務就失敗了。
但是用文件來同步機器間的通訊這個特性也有一個壞處,就是每當Map-Reduce的某一個步驟運行完后,需要重新調度下一級任務。如果是程序是一個重復迭代,直至收斂的過程,比如說KMeans算法、矩陣奇異值分解(SVD),則由于調度產生的開銷會非常的大,網絡傳輸不僅僅是發送需要的數據,還有一個讀取文件、寫入文件的磁盤IO過程,在迭代次數很多的時候(在大規模的SVD分解的時候,迭代的次數可能會達到上萬次),這樣的方式可能是無法忍受的。
目前Map-Reduce已經被很多的公司實現,Map-Reduce并不是一套標準,而是一種編程的方式,所以每個公司提供的API都有很大的區別,這會使得不能讓程序比較通用。一般來說,如果想學Map-Reduce,可以在單機配置一個Hadoop。這算是一個非常標準的Map-Reduce過程。
MPI:
全稱是Message Passing Interface,也就是定義了一系列的消息傳遞接口,可以看看MPI的Wikipedia,里面的內容從了解MPI來說比較好,這里說說重點,就不粘程序了。
MPI其實是一套標準,對C,C++,Fortran,Java,Python等都規定了一系列的接口,MPI的內部有一系列的函數,比如獲取當前有多少進程MPI_Comm_size, 進程間同步MPI_Barrier等函數。對每種支持的語言,MPI都定了一個函數接口,也保證了不同的實現下,MPI的程序寫出來都是一樣的。MPI是一個在學術界和工業界都應用非常廣泛的一套接口,目前MPI的實現非常多,開源的有OpenMPI和MPICH比較好,有些MPI實現來自一些大學的實驗室,有些MPI的實現來自一流的公司(比如Microsoft就有自己的一套實現,還弄了一個C#版本的)。
MPI相對MapReduce來說,開發、調試也更接近單機,MPI的部署可以在單機上完成,調用的時候也可以制定多線程運行程序,如果有興趣,可以下載一個OpenMPI或者MPICH,在自己的linux機器上進行部署,寫寫簡單的代碼是足夠了。在單機保證邏輯正確的情況下,再上集群上面跑,就容易多了。
MPI的優點是,程序的調度是一次性的,就是比如開始申請了50個進程,那這50個進程就會一起跑,同生同死,在程序中指定的同步等操作,也會讓這些進程進行同步,也可以在互相之間發送數據,通過MPI的封裝,讓發數據更操作變得非常的方便(MPI有100多個函數)。也就是從程序開始到結束,每個進程只會調度一次,如果有迭代的操作,就用下面的語句,加上必要的同步就行了:while (condition) { … }。對于需要迭代次數比較多的程序,MPI的運行時間普遍來說會比MapReduce強很多。
MPI相對MapReduce也有很多的缺點,開源的MPI或者一些商業的MPI都沒有提供一個GFS系統,這個讓大文件的存放,讀取都成了一個問題,如果底層有一個GFS,再在上面搭一個MPI的系統,使用起來會非常的舒服。而且MPI的容錯性一般不容易做,因為程序是同生同死的,某一個進程掛了,整個任務就掛了,除非在程序運行的時候,經常往磁盤中dump數據,不然容錯性是完全沒法保證的。
MPI據說還有一個缺點,不過現在也拿不到資料去證實,就是MPI的集群規模一般沒法做大,如果做到幾千臺,進行數據傳輸、同步的開銷就大了,而MapReduce的集群規模做到幾萬臺電腦理論也是沒有什么問題的。
分布式計算的學習:
分布式計算的學習主要可以參考一下下面的一些資料,首先是Google的幾篇重量級的文章:MapReduce: Simplified data processing on large clusters,也是上文提到過的,還有一篇Google File System。然后就是wikipedia,用map-reduce,clound-computing等關鍵字搜索一下,可以看到很多有意思的內容。至于國內的教材,我也沒有看太多,不太好評價,從我看到的一些來說,感覺講得還是不太清楚的。
另外如上面提到的,分布式計算的兩個最主要的分支:MapReduce和MPI,MapReduce復雜的地方來自底層的文件系統,想搞清楚這個文件系統很痛苦的,而MPI復雜的地方來自眾多的函數,到目前為止,我熟練使用的函數就十來個,不過也可以實現很多基本的功能了。
另外學習MapReduce看Hadoop,學習MPI看OpenMPI和MPICH都可以,其他開源的SDK都很難和上面這幾個相比。
從國內的公司而言,MPI和MapReduce的應用也很廣,比如百度就是同時使用的Hadoop與MPI,學好了這兩個東西,找個好工作還是比較容易的:)