文章目錄
- 2.1 實現 NameNode 的高可用——AvatarNode
- 2.2 Hadoop RPC 相容性和資料區塊可用性
- 2.3 即時負載的效能最佳化
- 2.4 HDFS sync 最佳化和並發讀
- 3.1 行層級原子性和一致性
- 3.2 可用性
- 3.3 效能最佳化
原文地址:
http://blog.solrex.org/articles/facebook-realtime-hadoop-system.html
作者:楊文博
Facebook 在今年六月 SIGMOD 2011 上發表了一篇名為“Apache Hadoop Goes Realtime at Facebook”的會議論文 (pdf),介紹了 Facebook 為了打造一個即時的 HBase 系統使用到的獨門秘技。由於該論文提到的應用情境與小弟負責的系統要解決的問題域有相似之處,因而抽時間仔細閱讀了這篇論文。下面便是結合論文的內容,談一談我的一些看法和感想,如有謬誤,敬請指正。
這篇 10 頁的長文主要的內容是 Facebook 在 Hadoop 系統上的工程實踐,這些工程實踐的目標則是題目所點出的——即時。雖然缺乏 Hadoop 系統的開發或使用經驗,但是我覺得並沒有妨礙我對這篇論文的理解。在我的腦子裡,HDFS 就是 GFS,HBase 就是 BigTable。它們實現上可能有差異之處,但主要的思想應該是相通的。如果熟悉 GFS 和 BigTable 那兩篇文章,這篇文章就可以視為 GFS 和 BigTable “進階”。
1. 應用情境和需求
文章的最初是一些背景介紹,主要給出了三類應用情境:Facebook Messaging、Facebook Insight 和 Facebook Metrics System(ODS)。Messaging 就是 Facebook 的新型Message Service,Insight 是提供給開發人員和網站主的資料分析工具,ODS 則是 Facebook 內部的軟硬體狀態統計系統。這三個應用情境都有各自的特色,但簡單地來說,面臨的問題是同樣的:單機或者拆分的關係型資料庫無法滿足需求。
基於應用情境的資料特徵,Facebook 抽象出了幾個對儲存系統的需求。由於描述起來有些複雜,例如 Efficient and low-latency strong consistency semantics within a data center,這些需求就不一一列舉了。相比需求,更讓人感興趣的是它的那些“非需求”,總共有三條:
- 容忍單資料中心內部的網路分化,Facebook 認為這個問題應該從網路硬體層面(做冗餘設計)而不是軟體層面去解決;
- 單個資料中心宕機不影響服務,Facebook 認為這種災難很難發生,因而願意接受這種風險;
- 跨資料中心的資料熱備服務能力,Facebook 假設使用者資料是分配到固定的資料中心的,可能帶來的響應延遲問題應該通過緩衝來解決。
從這些“非需求”上可以看出,Facebook 考慮的是更實際的情況,而不是一個理想中的分布式系統,在這點上有一定的借鑒意義。
根據以上的需求和非需求,Facebook 自然而然地給出選擇 Apache Hadoop 這套系統的理由,其中有社區的成熟度等級、Hadoop 在一致性、擴充性、可用性、故障容忍、讀寫效率等等的各項優點,這些方面的優點也是有目共睹的。
2. 打造即時的 HDFS
HDFS 本身設計來支援離線 MapReduce 計算的Distributed File System,雖然在擴充性和吞吐上有很好的表現,但在即時性方面表現並不好。如果想讓基於 HDFS 的 HBase 有更好的效能,HDFS 層的最佳化是不可避免的。為了把 HDFS 打造成一個通用的低時延檔案系統,Facebook 主要做了以下一些最佳化。
2.1 實現 NameNode 的高可用——AvatarNode
HDFS 的 NameNode 是系統單點,就意味著 NameNode 掛掉會導致系統的不可用。NameNode 重啟時載入記憶體快照、應用log和收集 DataNode 的資料區塊資訊報告大概需要 45 分鐘。即便使用了 BackupNode,仍然需要收集資料區塊資訊報告,切換的時間仍然可能大於 20 分鐘。但有即時性需求的系統一般都會要求系統 24x7 的可用性,因而 Facebook 對單點的 NameNode 進行了改進,實現了 NameNode 的雙節點熱備,稱為 AvatarNode,如所示:
AvatarNode
簡單地來說,備份 AvatarNode 通過 NFS 讀取並回放主 AvatarNode 的交易記錄來保持資料的同步,並同時接收 DataNode 的資料區塊資訊報告,這保證了主備 AvatarNode 的資料差距儘可能地小,使得備份 AvatarNode 能夠很快地切換為主節點的角色。主備 AvatarNode 的角色是註冊到 ZooKeeper 中的,DataNode 可以根據 ZooKeeper 中資訊判斷需要服從哪個 AvatarNode 節點的指令。
為了實現熱備 AvatarNode 的資料同步和易用性,Facebook 還改進了 NameNode 交易記錄,並部署了 DAFS (Distributed Avatar File System) 屏蔽了 AvatarNode 的故障切換,使得這些改變對用戶端透明。文中並沒有提到 AvatarNode 的切換是手工還是自動進行的,但是考慮到 ZooKeeper 的 lease 機制,自動切換應該不難實現。
2.2 Hadoop RPC 相容性和資料區塊可用性
在之前的系統需求中,有提到一點是 Fault Isolation,並且 Facebook 的 Hadoop 系統是在單機房部署的,因而同一個服務必然會使用多套 Hadoop 系統。為了系統升級獨立方便,使用戶端相容不同版本的 Hadoop RPC 是自然而然的事情。
HDFS 在分配副本資料區塊位置時,雖然會考慮到機架位,但整體來說仍然是相當隨機的。其實我以前也曾經與同事討論過類似的問題,到底是選擇隨機分配副本位置,還是使用一定的組策略去分配。隨機分配的好處是簡單均衡,壞處是一旦發生多台宕機,由於副本隨機分布,導致某塊資料副本全部丟失機率很大;用一定的組策略去分配的好處是多台宕機如果不發生在同一組裡,不會丟資料,但是一旦多台宕機發生在同一組,會丟很多資料。看來 Facebook 是選用了組策略分配的方法,認為多台宕機發生在同一組的機率不大。
但這樣做是否正確,我是有疑問的。同一個機架或相鄰機架上的伺服器一般上架時間、硬體型號等都相同,那麼同時發生故障的事件不是完全獨立的,其機率是要大於理想故障分布情況下機率的。我想這也是為什麼 Facebook 最終方案中一組機器是 (2, 5),2 個機架,5 台伺服器。這兩個機架的選擇,如果很謹慎的話,能夠盡量避免我說的這種情況。不過,凡事還得看執行力,如果不瞭解部署情況去選擇機架的話,不一定能夠達到預期效果。
2.3 即時負載的效能最佳化
除了上面的改動之外,Facebook 還對用戶端的 RPC 過程進行了最佳化。為 RPC 添加逾時機制,加快檔案 lease 的撤銷速度(由於對 HDFS 檔案操作不瞭解,我沒明白為什麼要加快 lease 撤銷)。
此外,還提到了最重要的一點:局部性!Facebook 增加了一個檢查檔案塊是否在原生功能,如果在本機就直接讀取。不知道它具體實現方式是怎樣的,但我覺得這個做法其實是“很黃很暴力”的,不知道會不會破壞資料一致性。
2.4 HDFS sync 最佳化和並發讀
為了提高寫效能,Facebook 允許不等待 sync 結束就繼續寫,這一點看起來也很暴力,不知道會不會影響資料正確性。
為了能夠讀到最新資料,Facebook 允許用戶端讀一個還未寫完的資料檔案。如果讀到正在寫入的最後一個塊,就重新計算 checksum。
3. 打造即時生產壞境的 HBase 3.1 行層級原子性和一致性
雖然 HBase 已經保證了行層級的原子性,但節點宕機可能導致最後一條更新日誌不完整。Facebook 不夠滿意,引入了 WALEdit,一個日誌事務概念來保證每條更新日誌的完整性。
一致性方面,看來 HBase 能夠滿足需求。不過對於 3 個副本同時校正失敗導致資料區塊停用情況,Facebook 增加了事後分析的機制,而不是簡單丟棄。
3.2 可用性
為了提高 HBase 的可用性,Facebook 對其進行了完善的測試,並解決了以下幾個問題:
- 重寫 HBase Master,將 ragion 分配資訊儲存到 ZooKeeper 中以保證宕機切換正確完成。
- 使得 compaction 可以中斷以加速 RegionServer 的正常退出速度,並實現 rolling restarts(就是逐台升級),降低程式升級對服務的影響。
- 將宕機 RegionServer 的日誌拆分功能從 Master 中拆離,由多個 RegionServer 進行拆分,以提高 RegionServer 故障恢複效率。
這幾個問題的解決倒是有通用的用途,我想不久以後很有可能會合并到 Hadoop 的代碼中。
3.3 效能最佳化
效能最佳化主要從兩點進行,一個是 compaction 效能,另一個是讀效能。
讀過 BigTable 論文的應該對其 memtable 和 compaction 的特性比較熟悉。這裡主要討論了讓 minor compaction 也刪除資料的好處,以及如何做 major compaction 能夠提高合并的效能。
在資料讀效能方面,文章裡主要討論了減少 IO 操作的方法,其中包括 bloom filter 和特定類型 meta 資訊(時間戳記)的使用。還有很重要的一點,在部署上保持 RegionServer 和物理檔案的局部性!
文章後面還給出了 Facebook 在部署和營運方面的一些經驗,其中有一些有趣的點,我後續可能會寫篇文章專門討論,這裡就不詳細說明了。
4. 總結
以前我們也曾經討論過如何在Distributed File System的基礎上搭建一套即時資料分析系統,當時認為如果有成熟的 GFS 可用的話,這個工作會比較簡單。現在讀到 Facebook 的這篇文章,才發現當初想法的幼稚。僅僅從這篇文章中的技術點體現出的工作量來看,文中說這個系統是多年持續工作的結晶是令人信服的。當然,這也意味著想複製一套這樣的系統並不是件輕鬆容易的事。
從系統設計的成果來看,這個系統應該能達到文章開頭制定的需求目標,並也能夠滿足大部分應用情境的需要。不過有一點,我存在疑問,即是為 Insights 提供的 Realtime Analytics 功能。Realtime 沒問題,但使用 HBase, Analytics 究竟能支援多好呢?可能還需要再去瞭解 HBase 的功能才能有答案。
從這個系統的很多細節可以發現,有不少折中和 trick。我想這就是現實世界,凡事很難做到盡善盡美,工程也一樣。在設計系統時追求完美沒有錯,但是需要考慮代價和可行性,不要忘記滿足需求才是最重要的目標。除此之外,也不妨再列出一些“非需求”,排除這些限制可能會降低不少的系統複雜度。