HDFS對於CAP原理是取捨了哪個?
從HDFS寫數據的角度來說, 對於A和P和C都有取捨.
HDFS寫數據是通過pipeline的方式來進行的, 我想目前市面上的很多文檔對這個都有描述, 我就不細說了, 粗略說, 就是設HDFS的數據都有N=3個副本, 開始寫數據時, NameNode會制定3個data node, 分別作為這3個副本的存儲機器, 然後這3個機器通過socket串接在一起.這裡還有個"最小寫副本數"的概念, 設這個值為MinN, 意思就是說, 當寫成功MinN個副本, 就認為寫成功了, 然後HDFS內部再會在後台非同步將這個副本同步到其他的N - MinN個機器上, 最終形成N個副本.
那麼回到開頭, 為什麼說HDFS其實對於A和P和C都會有取捨呢?1 如果MinN設為1, 那麼其實就是犧牲了P; 因為這種情況下如果有寫操作, pipeline管道只有1個data node, 寫成功後, hdfs如果在同步這個副本到其他data node的過程中, 有這個block的data node壞掉了, 那麼這個單副本的block數據就等於永久丟失了. 相當於無法保證P.2 如果1 &< MinN &<= N, 比如MinN == N == 3, 那麼這種情況下, pipeline管道中有3個data node都建立連接, 必須要同時寫成功3個data node才會算作寫成功, 在3個副本任一個副本沒有確認寫成功前, 寫入的流數據(注意, 也是按照流數據, 將數據分做一個一個packet, 依次寫入3個data node), 是無法被外部其他Client看到的, 這相當於犧牲了A.3 最後說說, 為什麼說也會犧牲C呢? 每個連入piepine的data node, 其正在被寫入的block, 會記錄一個當前已確認寫入的數據的offset, 我們叫它ackOffset. 這個ackOffset, 決定了當有Client來本dataNode讀取數據時, 可以返回給讀Client能夠讀取的數據邊界. ackOffset是如何確定的呢? 處於pipeline的最後一個data node, 將數據寫入後(我記得不一定會flush磁碟到磁碟, 需要分場景), 更新當前自己的ackOffset, 然後會發送一個ack給它上游的data node; 上游data node收到這個ack後, 才會也更新自己的ackOffset, 然後同樣發個ack給自己的上游data node.這個過程雖然很快, 但是理論上也會出現, 當ack在多個data node的pipeline中傳遞的過程中, 不同的Client讀取不同的datanode, 導致讀取的數據不一致的問題, 雖然概率會很小, 因為ack的傳遞會比較快.
另外, hdfs設計為, 同一個block,同時只能有一個寫Client, 相當於將這個block租給某一個client,這個就是lease租約機制; 這種情況下, 相當於犧牲了A(因為其他寫Client不能進行), 得到了C(只有一個Client寫, 所以對於寫來說強一致性, 讀仍是上面那一大段), 也得到了P.
我認為, 當前的分散式系統, C主要指的是多個讀如何做到一致性, 所以如果想做到強一致性, 那麼只有寫操作完全完成後, 才能讓讀操作看到,這樣就相當於犧牲了A, 而保證了C強一致性. paxos等演算法我想就是這個原理.推薦閱讀:
※王家林的技術水平到底咋樣?
※在Hadoop 和Spark之間如何取捨?
※Erasure Code編碼大文件的問題?
※八斗學院到底怎麼樣 ?
※2017 年國內房價是漲了還是跌了?