- 鳳凰架構:構建可靠的大型分布式系統
- 周志明
- 3117字
- 2021-06-24 11:30:49
1.1 原始分布式時代
可能與絕大多數人的認知有些差異,“使用多個獨立的分布式服務共同構建一個更大型系統”的設想與實際嘗試,其實要比今天大家所了解的大型單體系統出現的時間更早。
在20世紀70年代末期到80年代初,計算機科學剛經歷了從以大型機為主向以微型機為主的蛻變,計算機逐漸從一種存在于研究機構、實驗室當中的科研設備,轉變為存在于商業企業中的生產設備,甚至是面向家庭、個人用戶的娛樂設備。此時的微型計算機系統通常具有16位尋址能力、不足5MHz時鐘頻率的處理器和128KB左右的內存地址空間。譬如著名的英特爾處理器的鼻祖Intel 8086處理器,就是在1978年研制成功,流行于80年代中期,甚至一直持續到90年代初期仍在生產銷售。
計算機硬件有限的運算處理能力,已直接影響到了單臺計算機上信息系統軟件能夠達到的最大規模。為突破硬件算力的限制,高校、研究機構、軟硬件廠商開始分頭探索,尋找使用多臺計算機共同協作來支撐同一套軟件系統的可行方案。這一階段是對分布式架構最原始的探索,從結果來看,歷史局限決定了它不可能一蹴而就地解決分布式的難題,但從過程來看,這個階段的探索稱得上成績斐然,研究過程中的很多成果都對今天計算機科學的諸多領域產生了深遠影響,并直接推動了后續軟件架構的演化進程。譬如,惠普公司(及后來被惠普收購的Apollo)提出的網絡運算架構(Network Computing Architecture,NCA)是未來遠程服務調用的雛形;卡內基·梅隆大學提出的AFS(Andrew File System,Andrew文件系統)是日后分布式文件系統的最早實現(Andrew意為紀念Andrew Carnegie和Andrew Mellon);麻省理工學院提出的Kerberos協議是服務認證和訪問控制的基礎性協議,也是分布式服務安全性的重要支撐,目前仍被用于實現包括Windows和Mac OS在內的眾多操作系統的登錄、認證功能等。
為了避免UNIX系統的版本戰爭[1]在分布式領域中重演,負責制定UNIX系統技術標準的“開放軟件基金會”(Open Software Foundation,OSF,也即后來的“國際開放標準組織”)邀請了當時業界主流的計算機廠商一起參與,共同制訂了名為“分布式運算環境[2]”(Distributed Computing Environment,DCE)的分布式技術體系。DCE包含一套相對完整的分布式服務組件規范與參考實現,譬如源自NCA的遠程服務調用規范(Remote Procedure Call,RPC),當時被稱為DCE/RPC,它與后來Sun公司向互聯網工程任務組(Internet Engineering Task Force,IETF)提交的基于通用TCP/IP協議的遠程服務標準ONC RPC被認為是現代RPC的共同鼻祖;源自AFS的分布式文件系統(Distributed File System,DFS)規范,當時被稱為DCE/DFS;源自Kerberos的服務認證規范;還有時間服務、命名與目錄服務,甚至現在程序中很常用的通用唯一識別符(Universally Unique Identifier,UUID)也是在DCE中發明出來的。
額外知識
UNIX的分布式設計哲學
保持接口與實現的簡單性,比系統的任何其他屬性,包括準確性、一致性和完整性,都來得更加重要。
——Richard P.Gabriel,The Rise of Worse is Better,1991
由于OSF本身的UNIX背景,當時對這些技術的研究都帶著濃厚的UNIX設計風格,有一個預設的重要原則是要使分布式環境中的服務調用、資源訪問、數據存儲等操作盡可能透明化、簡單化,從而使開發人員不必過于關注他們訪問的方法或其他資源是位于本地還是遠程。這樣的設計主旨非常符合UNIX一貫的設計哲學,然而這個過于理想化的目標背后其實蘊含著彼時根本不可能完美解決的技術困難。關于UNIX設計哲學,有幾個不同的版本,這里指的是Common Lisp的作者Richard P.Gabriel提出的簡單優先原則,即“Worse is Better”。
盡管“調用遠程方法”與“調用本地方法”只有兩字之差,但若要兼顧簡單、透明、性能、正確、魯棒、一致等特點,兩者的復雜度就完全不可同日而語了。且不說遠程方法不能再依靠本地方法那些以內聯為代表的傳統編譯優化來提升速度,光是“遠程”二字帶來的網絡環境下的新問題,譬如,遠程的服務在哪里(服務發現),有多少個(負載均衡),網絡出現分區、超時或者服務出錯了怎么辦(熔斷、隔離、降級),方法的參數與返回結果如何表示(序列化協議),信息如何傳輸(傳輸協議),服務權限如何管理(認證、授權),如何保證通信安全(網絡安全層),如何令調用不同機器的服務返回相同的結果(分布式數據一致性)等一系列問題,全都需要設計者耗費大量精力。
面對重重困難與壓力,DCE不僅從零開始、從無到有地回答了其中大部分問題,構建出大量的分布式基礎組件與協議,而且真的盡力做到了相對“透明”,譬如在DFS上訪問文件,如果不考慮性能差異,很難感受到它與本地磁盤文件系統有什么不同。可是,一旦考慮性能差異,那遠程和本地的鴻溝是無比深刻的,兩者的速度往往有著數量級上的差距,完全不可調和。尤其是在那個時代的機器硬件條件下,為了讓程序在運行效率上可被用戶接受,開發者只能在方法本身運行時間很長、可以相對忽略遠程調用成本時的情況下考慮分布式。如果方法本身運行時間不夠長,就要人為用各種Tricks刻意構造出這樣的場景,譬如將幾個原本毫無關系的方法打包到一個方法體內,一起進行遠程調用。一方面,這種長耗時方法本身就與期望用分布式來突破硬件算力限制、提升性能的初衷相悖;另一方面,此時的開發人員實際上仍然必須每時每刻都意識到自己是在編寫分布式程序,不可輕易踏過本地與遠程的界限。設計向性能做出的妥協,令DCE“盡量簡單透明”的努力幾乎全部付諸東流,無論是從編碼、設計、部署還是從運行效率上看,遠程與本地都有著天壤之別。開發一個能良好運作的分布式應用,需要極高的編程技巧和各方面的專業知識去支撐,這時候反而是人本身對軟件規模的約束超過了機器算力上的約束。
對DCE的研究是計算機科學第一次對分布式有組織領導、有標準可循、有巨大投入的嘗試,但無論是DCE還是稍后出現的CORBA,從結果來看,都不能稱得上成功,因為將一個系統拆分到不同的機器中運行,為解決這樣做帶來的服務發現、跟蹤、通信、容錯、隔離、配置、傳輸、數據一致性和編碼復雜度等方面的問題所付出的代價已遠遠超過了分布式所取得的收益。親身經歷過那個年代的計算機科學家、IBM院士Kyle Brown事后曾評價道,“這次嘗試最大的收獲就是對RPC、DFS等概念的開創,以及得到了一個價值千金的教訓:某個功能能夠進行分布式,并不意味著它就應該進行分布式,強行追求透明的分布式操作,只會自尋苦果。”
額外知識
原始分布式時代的教訓
某個功能能夠進行分布式,并不意味著它就應該進行分布式,強行追求透明的分布式操作,只會自尋苦果。
——Kyle Brown,IBM Fellow,Beyond Buzzwords:A Brief History of Microservices Patterns,2016
以上結論是有違UNIX設計哲學的,卻是當時現實情況下不得不做出的讓步。擺在計算機科學面前有兩條通往更大規模軟件系統的道路:一條是盡快提升單機的處理能力,以避免分布式帶來的種種問題;另一條是找到更完美的、解決如何構建分布式系統的解決方案。
20世紀80年代正是摩爾定律開始穩定發揮作用的黃金時期,微型計算機的性能以每兩年增長一倍的驚人速度提升,硬件算力束縛軟件規模的鏈條很快變得松動,信息系統進入以單臺或少量幾臺計算機即可作為服務器來支撐大型信息系統運作的單體時代,且在很長的一段時間內,單體都將是軟件架構的絕對主流。盡管如此,對于另外一條路,即對分布式計算、遠程服務調用的探索也從未中斷。關于遠程服務調用這個關鍵問題的歷史、發展與現狀,筆者還會在第2章中以現代RPC和RESTful為主角來進行更詳細的講述。那些在原始分布式時代中遇到的各種分布式問題,也還會在軟件架構演進后面幾個時代里被人們反復提起。
原始分布式時代提出的構建符合UNIX設計哲學的、如同本地調用一般簡單透明的分布式系統的這個目標,是軟件開發者對分布式系統最初的美好愿景,但迫于現實,它會在一定時期內被妥協、被舍棄。換句話說,分布式將會經過一段越來越復雜的發展過程。不過,在三十多年后的21世紀10年代[3],隨著分布式架構逐漸成熟、完善,并取代單體成為大型軟件的主流架構風格以后,這個美好的愿景終將會重新被開發者拾起。
[1] UNIX系統的版本戰爭:https://en.wikipedia.org/wiki/Unix_wars。
[2] 分布式運算環境:https://en.wikipedia.org/wiki/Distributed_Computing_Environment。
[3] 20世紀80年代的三十多年之后。這里是指服務網格提出后,重新崛起的透明通信。