誰來拯救云計算 —— 云計算的技術路線探討
注:原文發布于2012-02-03
引言
當前的“云計算”一詞已經被神話,似乎快成了放之四海皆準的時髦真理,就好比當初言必稱“希臘”一般,表面光芒四射,但實際上卻無比教條、且越來越令人生厭。
作為“云計算”的一個普通開發者和推廣者,很有必要通過親身實踐,以正視聽,希望能讓后來者(云計算系統的開發者)少走彎路——有所為、有所不為。
前言
我們所要談論的不是商業領袖們所熱衷的云計算概念、云計算市場,而是討論技術人員眼中云計算具體形態和切實的實現辦法。
我們將從需求分析入手、進而討論設計理念、再具體化到子系統設計和實現中存在的難點問題、最后談談云計算對外服務的技術選擇。其中有些觀點屬于業界共識,也不少屬于個人看法——難免有所偏頗——真誠歡迎從事云計算開發的朋友積極討論和批評。
本文試圖回答這么幾么幾問題:
1. 技術人員理想的云計算是什么?
2. 理想和現實的鴻溝是什么?
3. 云計算到底需要什么樣的基礎架構?
4. 云計算基礎架構可能的組成部分。
5. 虛擬機和App Engine等云計算的關系。
強調一下——本文僅以開發人員視角出發!以大中型互聯網公司、海量數據、多業務線運維為背景,圍繞后臺基礎架構進行分析討論。
另外,借此機會王婆賣瓜式的推薦一下我個人發起的開源云計算相關的小項目:http://code.google.com/p/cloudxy/。
我們到底要什么云
現在的麻煩
談理想之前先回顧當前現實中RD(開發人員)和OP(運維人員)的工作場景。作為一個”過來人”,分析一下RD和OP在開發、測試、部署一個新應用時不得不做的那些麻煩事吧。
開發階段面對的麻煩:
Ø 可用性問題——互聯網應用作為在線服務都希望能永遠在線;而從成本考慮,規模使用廉價PC SERVER、廉價硬盤、廉價路由器等必然就會出現相對較高的故障率,甚至可以說故障是常態,因此從應用設計上必須考慮故障切換,而且最好是自動透明的故障切換。
Ø 負載均衡問題——無論存儲集群或者是應用服務集群等都可能出現負載不均勻情況。同一集群中因種種原因總是會有熱點(因為訪問壓力大而造成的或磁盤空間不夠、或內存不足、或CPU負載太高、或網絡帶寬不足)出現,當熱點出現時,就需要將熱點的訪問流量分流到比較冷的服務器上去。總之希望集群中的服務器冷熱均勻,服務才能穩定、高效。
Ø 擴容縮容——當你的應用用戶越來越多時,就要有擴容要求(集群中補充新機器),擴容時最好能不停或者少停服務。
上面這些問題,其實是分布系統的普遍共性問題,解決辦法無非是采用supervisor、主從熱備、smartclient、狀態報告、一致性哈希、數據分區等等技術,兵來降擋,水來土掩的case by case的解決。
作為一個在線應用RD(開發人員),很可能在處理上述問題花的功夫,比自己應用邏輯本身的還要多不少,這顯然是一個不小的負擔。
測試階段面臨的麻煩
測試首先在于搭建環境和系統部署。這點說起來簡單,其實現實操作中可夠你折騰一陣了。因為你不得不做:
Ø 搶到足夠多的機器——你很可能要排隊、要求人、總之要費點點功夫。
Ø 搭建存儲服務——應用開發人員對存儲系統各種配置參數和部署方式的理解和摸索過程,絕對是一個常犯錯誤的窩工活。
這個過程對很多RD和測試人員來說,絕對比寫代碼要費時費力。溝通成本(公司大了,很多溝通都是跨部門的)不容小視呀。
部署的麻煩
Ø 容量規劃——一個應用上線前肯定需要根據經驗(或者拍腦袋)估算出未來一段時間內系統面臨的負載。估算少了,肯定要面臨擴容的風險,這無疑是自搬起石頭砸自己腳。再加上一些好大喜功的人類天性,應用負責人肯定會滿打滿算的推算出最大可能的機器規模。
Ø 申請機器,搭建集群——申請機器意味著報計劃、等審批、等機器、走麻煩的流程(這很多都是經理的事啦)。搭建集群則是RD和OP一起攜手完成(RD出上線步驟等,OP 實施),這個過程要小心謹慎,需要不止一個人反復檢查(差勁點的應用會是實例配置不統一,每個實例的配置都有所區別),還常常需要RD陪同實施,總之絕對是個體力活。
Ø 備機準備——很多應用為了防止意外機器硬件故障(硬盤、主板、網卡、電源等壞了)下,能快速進行故障恢復,還會搞一些備機,以防萬一。這些機器純粹是養兵千日用兵一時。
任何一個自認為重要的應用都希望自己單獨占領一個集群,如果和別人混合部署,害怕資源征用,自己被拖累。鑒于此原因一個應用往往就意味者需要搭建1個以上集群(很可能存儲、或者其他服務都要單獨搭建一個集群為其使用)。應用RD人員還好說,為自己應用搭建一次就OK了、存儲等基礎服務RD就要多搭建幾次,受點累了;而OP就更辛苦了,要不斷重復這些體力勞動。
容量規劃和備機準備多多少少會帶來物理資源的閑置,容量規劃意味著預先準備未來一定時期內都足以應付請求壓力的足夠機器,那也就是說初期用戶規模還沒上來前,壓力還不大時,集群中多余的機器或者每個機器上的多數資源都會被閑置。
上線后的麻煩
故障恢復——一旦出現物理故障,或者系統自動FAILOVER做的不好情況下。但凡有機器異常,就有可能需要手動或自動(一般是手自一體的)進行故障恢復了。這個時候如果是常見故障,OP則需要按照事先準備的運維預案進行故障恢復。
OP最怕線上服務出現問題,影響用戶訪問。這種事故一旦碰到,就必須立刻響應,不容有誤。如果不幸的OP碰到那些未能自動透明的進行故障恢復而倉促上線的服務,那絕對夠喝一壺了。
一言以概之,困擾我們是:
- 系統分布化帶來的麻煩
- 反復溝通帶來的麻煩
- 搭建環境帶來的麻煩
- 資源浪費(這點一般是大老板們關心的問題)
我們憧憬的云計算
RD們真的希望能有一臺“超級計算機”,它大的有用不完的內存和磁盤、有強大無比的計算能力、更有無限帶寬、而且還是永不宕機!!!
如果真有這么一臺超級計算機,那么我們開發程序就不用再去考慮什么分布化、什么機器故障、負載均衡等事啦;也不用費神去申請機器,搭建集群(因為資源無限嗎);甚至上線動作都可省去,不再需要麻煩OP同學如履薄冰的部署程序,RD自己就能如同部署本機程序一樣簡單的部署線上服務。
如果那樣就太酷斃了,應用RD從此可以心無旁逸的投入到自己業務邏輯的開發中去,徹底釋放自己的想象力了。
完美理想的破滅
OK ! 我們想要的已經清楚了,那么當今什么是否能有這樣的超級計算機呢?或者說是否使用集群技術實現這種理想的超級計算機呢?答案是否定的!我們無法使用集群技術實現這樣的超級計算機。
否定的原因在于:1. 我們沒法將集群機器中的CPU計算代數相加,變成超級CPU(能做的只能是把任務分解,讓多個CPU并行計算罷了);2. 我們沒法將集群機器的內存代數相加,變成超大內存。千萬別想著用我們普通以太網做共享內存嘗試,要知道內存帶寬(GB量級)可要比網絡帶寬(MB量級)高出好多個量級;
次完美理想的再破滅
我們向現實第一次妥協,我們不求像寫單機程序那樣寫應用了,我們將應用請求分區處理,即將應用請求按照給定規則劃分成多個處理單元,每個處理單元都下發到集群中的某臺機器上執行——我們從理想的統一集中處理,變為“化整為零分區并行處理”。
我們無法擁有資源無限的超級計算機來肆意開發程序,而是要遵循限制:
- 必須在單機資源容量(尤其內存)的顧慮下來開發服務程序——以求在集群中被并行處理。
- 還必須給出分區規則——以求能化整為零,分區執行。
然而我們仍然奢望我們可以不用考慮如何進行分區、也不用考慮如何調度各子任務在集群中調度,不用考慮如何進行故障遷移、不用考慮如何負載均衡、不用考慮擴容縮容等分布式系統的共性問題;同時我們也奢望的程序上線自動化(無需人工干預),即應用可自動在云環境中部署和自動運行的。至于如何分區、如何調度、何時擴容等都交給“云”老大了。舉個例子,如果我們開發了一個key value系統,只要告訴“云老大”我們需要的分區規則(或者哈希打散、或者字典序分區)則萬事大吉了。
那么當今是否能有這樣智能的云呢?答案還是否定的!我們還是無法真正實現這樣智能的云。為什么呢?
首先我們思索一下這種智能云如果存在,會隱含有那些具體要求:
Ø 規模足夠大——足夠的規模的集群才配稱為云,才能提供認任我們為所欲為,不用考慮無法獲取資源的情況(當然不意味你可無限使用,可是要算錢的)。
Ø 支持共享—— 云可不是為了某一個應用專門搭建的,它必然要支持各種千差萬別的應用服務同時運行其中。
Ø 支持自動分區、任務派發、啟動——只要告訴分區規則,就能根據集群中資源情況,自動對應用服務進行分區,并派發服務程序到合適節點機器上、然后自動運行服務。我們不需要具體指定該分多少區、該部署到那個機器上,也不用自己拷貝執行程序和配置到目標機器、也不用手動去啟動服務。
Ø 支持自動故障切換—— 云應該具備高可用性,任何在其中運行的程序都應該有可用性保證。所以云中任何“節點故障”的處理應該能自動實施故障切換;而且云中任何“應用服務故障”也都應該能獲得自動故障切換的保障。應用開發人員從此可高枕無憂了。
Ø 支持自動擴容——應用服務當壓力負載加大時,需要能不影響服務的前提下,自動試試擴容(獲得更多資源,運行更多實例)。
Ø 支持負載均衡,智能調度——避免應用所在實例中出現冷熱不均的情況。當發生熱點時,可進行分區再分區方式,變一個服務實例為多個服務實例,并將分出來的實例遷移到多個機器上運行,從而消除熱點。
接下來的問題應該是:這些技術要求,從技術實現角度而言到底意味什么?實現難度到底在那里?
在我剛從事云基礎架構設計開發時,對上述要求真可謂是信心百倍。甚至我們會有意炫耀式的掛在嘴邊,無數次向別人吹噓。但事實教育了我,仰望星空,仍然要腳踏實地。我們展開來分析這些貌似理所當然的一些技術點,在云計算實踐中會有那些困難制約我們。
應用共享云資源之制約
不同用戶、不同特征的應用在一起混合部署、同時運行時候,相互之間需要保證“資源隔離”,這種隔離意味著避免相互資源爭用,否則同一機器上的不同程序服務必然相互影響,對資源的你爭我奪的情況下,服務性能必然發生抖動,從而破壞我們許諾的SLA(服務質量保證)—— 這也是為什么很多項目經理,都怕和別人的應用公用一個服務集群或存儲集群的原因。
資源隔離這個問題,我們要深刻認識,這點是實現大規模云計算面臨的一個普遍問題(誰也躲不開)。對于資源隔離這個共性問題,自然前人研究過無數種解法: 內存的預分區使用(如機器虛擬機XEN為domu預分配內存)、CPU的分核(利用CPU Affinity性)和配額限制下的分時復用、磁盤的分盤器使用、網絡QOS等等。
但是很不幸的是——相對富足的資源(如CPU在當前服務器中多數情況下大多屬于營養過剩,供大于求)和可以分區使用資源(如MEM、磁盤容量都可按配額預先劃分給應用)可以理想的做到資源隔離(或者說應用之間影響有限);可對于機器中緊缺資源,說白了就是“IO資源”(磁盤I/O和網絡I/O)隔離效果就很不理想了。我們實驗結果表明網卡QOS將損失近近一半帶寬,而磁盤QOS幾乎不能有效防止I/O爭用(兩個I/O密集型應用在一起爭奪I/O依舊那么不可控制)。
因此當前的技術條件下,你可借助內核工具Cgroup(Google放出來的一個內核資源受控功能),或用戶信號suspend\resume、自維護內存池等等技術做到給應用服務固定的CPU和內存配額限制,但沒有太好方法多I/O進行配額限制(至少沒有很理想的辦法)。所以我個人認為要想解決I/O爭用問題,要么借助于新硬件的升級——萬兆網絡代替千兆網絡、SSD代替IDE硬盤等——使得I/O資源變的相當富足;要么就避免I/O密集性程序混合部署,也避免離線任務(多是I/O密集性任務)和在線任務(尤其是有數據查詢的在線任務,key value 存儲服務)混合部署,以防止I/O爭用給在線服務造成響應延遲。
智能調度之制約
我們理想的調度意味著應用服務程序可以在集群中任意資源夠用的機器上啟動運行,甚至更理想的是能不停服務的情況下,將應用程序進行機器間動態遷移。
很顯然如若讓應用程序可在任意機器上執行,就要求應用服務的“上下文狀態”不能持久化在本地磁盤,也不能從本地反持久化(總之不能依賴本地存儲)—— 這就是常說的無狀態。只有這樣才有可能實現程序的運行和位置無關(即,和運行其的宿主機無關),從而才能有智能調度的基礎。
“上下文”不持久化于本地,就要求云環境能提供存儲服務,以便各應用的上下文能存儲分布式的、安全、高效的存儲在云中,但至于具體在那里,應用不必也不想關心。
“上下文” 的定義是寬泛的,包括各種格式的存儲容器。比如Hbase應用中,可以將是Range Server看作應用服務,而數據就是它的上下文——被分布式的存放于HDFS之中,也正是因為這種上下文位置無關的設計,使得Range Server可以被智能調度。 同樣HBase又被作為一個上下文存儲服務,供其他更多應用服務使用,那么這些應用服務也就和位置無關了。
作為一個云服務,應該提供有:基于offset的類文件存儲系統;key value存儲系統;類似數據庫(SQL)存儲系統;類似BigTable這種(No Sql)列存儲系統;甚至可能的圖存儲等等。
不過這種上下文遠程存儲實現在實踐中所面臨的最大挑戰是網絡帶寬不夠,一旦數據持久化的真實位置與提交、查詢的位置不在一個機器內的情況發生,必然帶來響應時間惡化,帶寬被大大占用。
仍以HBase為例,Range Server 接受客戶端提交的數據,然后當數據在內存中積攢到一定量后,再寫入到HDFS中,因為HDFS的寫入優先選擇最近的Chunk Server,而Chunk Server和Range Server是混合部署的,所以必然初期負責某個分區的Range Server與該分區落地的數據實際上是存儲都在同一個機器上(這就是HBase所謂的location相關性指標此刻為100%)。但當Range Server負責的分區數據過多,已至超過單機存儲量時;或者Range Server發生了故障切換后被重新調度,則Range Server和對應數據可能就不再在一個物理機器上時,顯然讀寫都必須多了一次跨機器交互——這種多余交互在千兆以太網環境下很可能要花去幾毫秒,對于強調響應時間的在線應用很可能是不可接受的。
跨機器帶來額外的帶寬占用毋庸置疑,更需要考慮的還有,因為性能原因Range Server不可能每一條數據都寫透到HDFS中,而必須聚合起來到達一大批時才一次推到HDFS中(目的無非是減少網絡交互的消耗)。但是如果還沒有被推入HDFS之前,Range Server所在機器宕機則肯定要丟失數據了。所以為了防止丟失,Range Server需要在成批寫入HDFS之前,將提交請求先記錄下來(所謂editlog),為安全和調度時效性原因(Range Server故障后,需要立刻進行故障切換),也不能存儲于本地,而是要存儲在遠程(實際上是以append模式寫到HDFS中)。我們知道為了避免數據丟失,HDFS存儲采用了多副本技術(一般3份)。因此一份數據從客戶端提交開始有可能需要在網絡中傳播7次(從客戶端到Range Server一份,Range Server寫editlog三份,Range Server聚合后到HDFS三份)。對于網絡的壓力可想而知,所以沒有一個超級強大的網絡基礎架構休想這樣理想的實現所有上下文數據遠程化。
很多公司都設想數據遠程化,但這之前請先設計一個強大的網絡環境。谷歌網絡環境許諾“任何機器”之間都能達到500大B的傳送速度;而我們國內又有幾家能保證這么快呢,可能500小b都不敢拍胸脯保證。
故障切換之制約
故障切換除了要求和智能調度一樣的"上下文數據遠程化"以外,還有一個很重要的要求——速度快,要做到對客戶端透明。
客戶端透明的一般要借助于Smart Client和服務邏輯尋址技術。Smart Client是指服務端盡量無狀態(或者狀態在啟動后可以重建),而把智能放在客戶端實現。其中一個重要智能就是故障探測和故障切換;服務邏輯尋址是說尋址過程不再直接使用具體IP尋址,而是使用一個邏輯名稱表示某個服務實例(邏輯名稱對應實際的IP屬于系統全局信息)。Client根據邏輯地址查詢系統全局信息,獲得具體IP地址,從而進行訪問。當服務發生故障,進行故障切換后,系統刷新該全局信息。而Client發現原IP地址訪問失效后,則從系統全局信息處重新獲取給定邏輯地址對應的Ip地址,重新進行連接并訪問——透明的完成故障切換。
全局信息維護并非難事,主要是考慮高可用性。不過這方面已經有很多成功辦法了。如Erlang有Globe模塊提供全局注冊名、ZooKeeper等服務也可作為配置中心存放這種全局信息。
回頭來說切換速度的問題。切換速度取決于:{故障發現 + 應用服務重啟后構建上下文}
故障發現看似簡單,其實是個錯誤多發區,而且也沒太好解決辦法。分布系統故障有機器故障、服務故障、網絡故障(還有包括該死的網絡分區故障)。故障發現一般依靠外部watch dog監控、心跳、或者外部搶鎖等機制。但不管如何判斷都要是要一定時間的,因為需要為了防止假死情況——一旦發生服務假死,而發生故障切換,就會出現雙主并存而引發數據錯亂等等麻煩——所以往往需要一個確認時間(或者租約到期,或者是提升版本確認新舊)。另外,上下文重建也需要時間,比如key value服務或Range Server等服務可能需要加載一些索引進內存,才能開始提供服務,那么這個加載動作根據數量級不同而不同,數據多時,甚至需要數分鐘才能完成。
我們要心知肚明——這些故障切換耗時并非所有應用都能接受,有些應用可能根本無法容忍分鐘級別的切換時間(記得亞馬遜的傳奇論文dynamo就是一個要求always writeable的產品)。這種應用實際上并不合適采用上述的準實時故障切換策略,而是需要采用熱備、熱切、多提交點等架構才能得意滿足。
調度以及負載均衡的制約
master-slave模式的分布系統應用中,master的職能一般包含元數據管理、接受用戶命令并下發給slave、還有就是負載均衡、故障切換等等。總之,全局性動作一般都需要由master參與處理。
智能云老大要想使用統一的方式接管各種應用的“負載均衡”和“故障切換”,也就是說實現一個大Master負責所有應用的負載均衡和故障切換。想法很好,但難免有寫天真。原因有二。
第一,應用的負載均衡和故障切換未必能簡單粗暴的使用一種模式完成。也就是說不一定僅僅選一個資源(CPU、內存、I/O)夠的機器就能可以遷移應用,或者進行恢復。很多應用具有自己特殊的調度要求,比如有些應用要求所有實例都處于一個路由器之下(如VM在線遷移)、或者要求必須不能處于同一機架(如DFS等)。
這種約束往往是case by case的,并不容易統一抽象出來。所以大Master方法對于各種約束是否能從容面對,是其一個很大挑戰!
第二,實時負載均衡就必須隨時掌握應用實例的負載情況,也就是要不斷采集(很多信息是靠心跳消息報帶給master )應用實例的各種負載指標。采集越勤,調度越實時。但是高頻度采集狀態是有代價的,它必然會給大Master帶來不小負載(網絡帶寬負載、處理請求計算負載等)。所以全局性的狀態監控是系統擴展性的一大障礙,經驗數據是大Master大約監視6000-10000個應用實例的負載就是處理上限了,再大就很難調度管理了。
分區的制約
我們雖然很想把如何分區工作交給云來做,我們只用給出規則。可實現這個理想還是有些障礙的。
1. 這個規則描述上就有一定的難度。因為每個分布應用往往都有自己的分區方式(其實就是我們所謂的7層負載均衡),如HBase使用字典序分區(因為要實現按序檢索);Memcache則實現一致性哈希分區(隨機查詢);還有些應用使用步長式分區;而更多應用則有自己特殊的規則進行分區,比如有些應用按地域分區(美國的請求一個區、日本的請求一個區等)、有的按用戶年齡、甚至還有的按照動態負載進行分區等等。
2. 除了規則難以統一外,更棘手的是:實例的資源分配量,云很難確定。如果錯誤的資源配置很可能應用實例無法使用——有些應用會要求實例的最小資源配額(如有些服務要加載巨大的字典表,就必須要有足夠的內存才能完成);而有些應用實例更會因為分區大小的不同對資源的要求也不同(分區越大資源要求越大,但比例關系并非線性,所以不好確定)。
3. 剩下的麻煩就是擴容時如何將分區再劈開呢? 字典序列、一致性哈希等還算好劈開,按地點則難度就麻煩些了,要是分區規則更復雜,則劈分區也絕對是個有難度的事情了。
綜上所屬,就分區一事與調度、負載均衡一樣是個性化的東西,可謂各應用蛇有蛇道,鼠有鼠道。真的很難做到一刀切的統一實現。
現實可能的云計算
上述分析后(我也實際實踐過),我們知道了現實環境的種種制約。我們不得不尊重現實,因此我們要重新定義我們智能云的職責功能了,重點是明確云的職能范圍(有所為,而有所不為!)。
強化資源管理職能
資源管理智能需要從下面幾個方面考慮:
Ø 沙箱容器
要想混合部署各種服務實例,我們自然希望有類似沙箱的容器,能把運行實例“封”在其中,所謂封意思限制其資源使用。既包含有資源配額管理,也包含隔離意思。最徹底、但也是最重(為什么重,我們后面分析)的容器自然是機器虛擬機(machine virtual machine)、其次是系統虛擬機(system virtual machine);另外java 、perl、erlang等語言虛擬機也可算是不太合格的容器(封的不夠)。
但不要迷信虛擬機做容器,道理上講凡是能提供受限環境都屬于容器。容器實現并未有確切套路。比如一個C開發的基于事件(網絡IO、信號、超時、甚至磁盤IO)驅動的服務程序便是一個很好的容器,它接管了所有事件處理,提供了一些標準的資源訪問接口。任何應用邏輯都將被實現為一個動態庫,按需加載到該服務程序中,從而能通過自身實現的消息回調函數執行具體的業務邏輯;同時對內存、磁盤當訪問也都使用容器提供的特定接口完成,不再直接調用標準庫。如此資源使用、對外通訊都被容器所監控——Google的App Engine就是類似這種實現的,不過不是借用了一些語言虛擬機的能力罷了。
如果應用不情愿使用容器提供的資源接口,而是按傳統方式申請資源。那么從外部使用cgroup等手段也可達到資源配額管理的目的。
Ø 接管IO
只從容器限制應用服務的資源還不夠,因為容器只能控制自己本身的資源使用。但是對是整個機器的資源卻缺乏“全局控制”。若要從機器角度控制資源,不能僅靠容器,而應該借助于獨立的駐機監控程序完成。
Cgroup實際上就是一個這樣的監控程序(雖然實現于內核),它可以控制機器上所有程序的資源(CPU/Mem)配額。
IO配額管理也同樣道理,需要接管服務程序接管機器上所有程序的IO使用——即,代理所有IO請求。機器上所有其它服務程序都不能再擅自直接使用IO,而是將請求交給代理服務進行;機器之間也不會存在服務socket直連,只可能是各自的代理服務socket連接(其實這也可減少socket連接資源占用)。
這樣做的好處是:代理服務能控制所有應用服務的IO配額,從而避免資源爭用——壞處不用說:IO流程被加長,效率低了點。
注意,我們這里所說的IO包括網絡IO,也包括磁盤IO。網絡IO代理可以做的類似于消息中間件,甚至可以實現點播、組播、廣播、故障切換等功能。磁盤IO代理則還要考慮管理多個磁盤的IO排隊,優先級問題等。
分區、調度策略、故障恢復等智能下放給應用
上一個章節我們分析了應用之間的差別性使得很難存在一個超級Master一刀切的處理各種應用的分區、調度、故障恢復等“智能”的行為。尤其要認識到越是基礎性的服務——尤其在線核心服務,其“智能”越強,因為其可用性等要求越嚴格、設計也更具復雜性、也越難進行統一方式管理。
比如,對于可用性要求比較寬松的應用服務而言:Master探測到slave發生故障后,再重新在另外機器上啟動一個新實例(可能還要重構上下文),然后再對外提供服務。這個時間很可能需要數分鐘之久(探測故障需要花時間、重啟實例需要時間、重構上下文需要時間)。
再高要求一些的應用,備用實例可能預先啟動好,所以切換時只需要重啟上下文(如Hbase就是將故障分區交給其他在分區管理)。
如果要求繼續加快故障切換時間,那么就需要使用熱備熱切方式了(所謂熱備份是指實時同步主備之間數據同步,保持同構上下文)。
如果這還不夠,那么就采用對等網結構,也就是無主結構(保證系統無單點)。客戶端可多點提交,各點之間的一致性通過集中決策等技術保證(如dynamo系統)
說了這么多,無非是告訴大家,不要指望有一個超級智能的大Master能搞定應用程序的各種智能,尤其是越重要的應用越難接管。所謂人貴在有自知之明,當我們熟悉互聯網應用的復雜性后,就別再強求做大一統的Master了。不如退而求其次,放手將智能性的動作下發給各個應用服務本身把,因為只有他們自己更了解自己的需求。
下放智能意味著各應用可以有自己的Master來處理個性化的、“智能”高的需求,而智能低的需求當然可以交出去統一完成了。
注:master傳統意義上負責那些職責(籠統概念,實際并非絕對如此,往往都是具備下述部分功能罷了):
- 負責存儲原數據——slave節點位置信息、各服務實例運行配置。總之是應用之間的數據中心。
- 負責管理命令——由于安全、以及元數據集中管理的原因,管理類命令一般只發給master,然后如果需要master再發向slave。
- 負責數據分區和調度實例——化整為零的工作由master做。
- 負責故障監控——探測slave故障(如通過心跳)、并可做出故障切換。
- 負責負載均衡——采樣負載信息(常通過心跳報實例負載)。
放棄統一的負載監控、動態調度
很多時候我們宣稱能削峰填谷式的使用集群中所有資源,可以根據集群中機器資源使用情況,動態調度應用實例。這樣不但可消除熱點,也能節約資源,因為應用實例可按需使用資源,不用的可以將資源還給大資源池。這種分時復用資源的方式無疑是很符合大老板的審美觀——似乎資源能被最有效的利用了。
但如果你多實施幾個大應用,就會發現這么做不大現實。因為你會碰到如下幾個切實的障礙。
1. 監控實例運行態負載帶來的壓力
監控實例運行狀態不是無代價的。監控意味著需要頻繁對實例采樣和上報超級Master,上報必然要占用寶貴的網絡帶寬,尤其是要占用超級Master所在機器的帶寬(有時會利用前置衛星機分擔Master壓力);而且超級Master還必須不斷記錄和隨時計算這些上報的負載信息。如果想盡可能及時發現負載變化,那么就要求盡可能頻繁負載采樣,從而給Master帶來更大傳輸和計算壓力。隨著越來越多的實例,Master將承擔越來越重的壓力,直到無法承受。
通常網絡環境(千兆以太網)和機器情況(numa體系的8核路服務器)情況下,大概到6000-10000個實例(一個機器可運行數個實例)就是監控上限了,因此可見大Master方案本身對擴展性就有制約。所以還是那句話,放棄大Master調度,各應用的Master負責監控自己應用實例。
2. 調度代價太大
理想中當發生熱點時,必須將肇事實例或相關實例遷移走。但遷移服務是有巨大代價的:
Ø 遷移很可能需要影響可用性
Ø 遷移很可能給網絡帶來壓力(重構上下文需要網絡流量)
不過這些都不是最糾結的事,最糾結的是調度是否真的合理未嘗可知。因為我們調度無非是依靠曾經的負載情況推斷未來的負載情況——當發現眼前某個實例運行資源不足時,需要找一個眼前和這一段時間負載都不重的機器,將實例遷移過去。但是眼前資源不足也許只是一個突發事件,而眼前和近一段時間負載輕的機器也許很快也將迎來自己的壓力高峰。如果調度碰到這種情況,就需要再重新調度,當然還有可能又出現類似情況——這就是抖動。如果這樣,那反而不如不作為的好。
就一個公司而言,應用數量有限,而且因為地域性或者應用特性很有規律可循,那么負載規律也是有據可循的。有據可循自然容易合理調度(甚至可以制定完美的調度計劃——消峰填谷式的資源消耗不同類型應用混合部署,也可差開時間段運行不同類型應用等)。但是當你需要提供公共云服務時,天南地北、魚龍混雜的各種應用就難說負載有據可循了,發生調度抖動的潛在危險也將大大增加。因此與其去動態調度,不如大方一點(不大方也不行呀),給每個實例一個資源配置上限,即便運行時資源利用不到上限,也不會讓別人占用——簡而言之,實例資源不復用,讓實例霸占吧!!!。
現實中云計算大約的架構
下來簡要總結一下當前業界所能接受和未來可能接受的云計算架構。
數據總線(Data Bus)
我們試圖接管集群中所有的網絡IO請求,實現下述功能。
- 面向應用的配額控制
- 優先級控制
- 流控(滑動窗口)
- 通訊故障處理
- 異步或同步消息
甚至可以將很多通用消息功能做到數據總線上:
- 點播、組播、廣播
- 負載均衡
消息總線實現和部署特點是:
1. 數據總線是駐機后臺程序,每個機器理論上只部署一個。
2. 數據總線服務程序兩兩之間只借助一個sock完成通訊,已節約連接資源。
分布式塊存儲
我們試圖將集群中機器所有磁盤都能通過網絡方式連為一體,形成存儲資源池。其目的在于:
1. 資源池化可防止局部存儲資源不足(單機存儲不夠),使得資源利用最大化。
2. 存儲資源(磁盤存儲)和計算資源和內存資源剝離,從而解放任任務調度。
3. 接管所有的磁盤請求,原則不允許應用直接訪問本地磁盤。
4. 存儲高可用性,不比再擔心磁盤故障(多副本等冗余技術保證)
運行容器
容器完全是個邏輯概念,虛擬機是容器(機器虛擬機,系統虛擬機,語言虛擬機),進程也是容器。容器不在乎實現,而是在于是能做到應用資源受限使用(重在內容,不再形式)。
駐機精靈
說白了就是一個系統默認服務(系統安裝好就在其中,系統啟動后就自動運行)。這個駐留精靈應該具備一下功能:
1. 按要求下載指定應用的應用程序發布包
2. 對應用程序運行期管理——啟動、關閉、暫停、恢復。注意當發現應用crash后,精靈往往要負責重啟,以提高系統可用性——這點可參看erlang的supervisor,都是類似的東西。
3. 對應用程序資源配額限制——比如采用cgroup規定資源配額;或者監控proc性能指標而調整nice 、或通過suspend/resume信號控制程序運行(好比輕點剎車一樣)。總之方法很多。
4. 匯報系統狀態——狀態包括有:靜態狀態(系統版本、機器資源等);應用狀態(runing,crash等);機器和應用負載(上文分析了負載可能會帶來性能問題)。
資源分配中心
資源分配其實映射為程序運行容器(可需可實)的分配。資源分配中心要有集群中所有機器的資源信息和位置信息。當有應用需要運行一個應用實例時,就向該中心發出請求。中心從資源池中找一個能滿足需要的物理機,然后告知該機器上的駐機精靈去獲取該應用的發布包,并按要求啟動應用實例。
上述是一個概要描述,具體實現可能要做如下幾個考慮:
1. 應用和資源中心可協商資源(討價還價)—— 比如應用的master向中心要100個20G內存的運行容器,而中心發現資源池不足這么多可用容器,那么告訴只能給90個15G內存的容器,你要不要? Master則根據具體情況,看是接受還是拒絕(如果可以將就著接受,那么master繼續啟動;如果不能接受,則拒絕退出,不繼續不啟動)
2. 容器的資源請求可能受網絡環境、機架位置等約束。因為除了內存等資源要求外,有些應用有機架感知要求(如HDFS)、或者有網絡布局要求(如要求在一個路由器下等——虛擬機動態遷移往往需要統一路由器下,fake arp才能走通)。
3. 有時也能接管一些力所能及的負載均衡或故障切換等功能(注意,復雜的智能邏輯可做不來,應該交給應用自己的master處理)。當然這要在應用允許情況下(如發現機器故障——精靈可報告,中心負責重新選擇一個新機器,再啟動一個新容器,并重新運行該實例)。
資源分配中心的存在為應用部署、管理提供了很大方便。Google內部使用的borg就是這種系統的代表(對應的駐機精靈叫borglet —— borg是德語城堡的意思,感覺不打貼切,不如我們曾經開發的matrix系統,對應的祝機精靈叫smithJ)。
另外值得注意的是應用資源描述問題!最高境界是開發一個描述性語言,做得簡陋點就用XML、json等搞個配置文件,應用資源被描述其中。資源描述應該覆蓋如下方面:
- 角色(如master, slave)—— 一個應用可能會包含多個角色(這點和erlang中一個relase有多個application類似吧)
- 角色實例的資源要求 —— 內存量、IO吞吐、CPU能力等等
- 角色實例故障后是否重新啟動 —— 如erlang中superivsor選擇重啟的幾個方式
- 角色的全局地址—— 類似于erlang的全局注冊名等,供別人訪問
- 還有很多七七八八的限制等,如依賴服務、日志級別、性能計數等等,不再嘮叨了。
全局命名中心
為了對各應用通訊尋址實現解耦目的,我們要避免應用實例之間直接寫定對方IP和端口地址(如寫在配置文件中)來實現通訊。因為直接給定IP意味著各程序的運行宿主機固定不變,也就意味著我們失去了服務遷移、故障切換等自由——意味著資源被綁定。
若要解開資源綁定,我們需要使用邏輯地址代替物理IP+端口方式尋址,而邏輯地址具體綁定那個物理地址則是可變的。比如應用的邏輯地址(類似于一個URI)是http://myexample.master,其開始運行在192.168.0.1機器上,這時邏輯地址http://myexample.master實際指向192.168.0.1(端口2000);但當應用被遷移到192.168.0.2機器上,這時同樣的邏輯地址http://myexample.master則又指向192.168.0.2(端口2000)了。
顯然上述的邏輯地址到實際物理地址的映射關系需要存儲在某個地方,這便是我們所謂的全局命名中心。實例之間只知道對方的邏輯地址,相互連接前都要詢問該中心獲得真實的IP地址,然后才能進行連接通訊。當通訊失敗(很可能是被連接實例切換機器了)后,需要再重新去命名中心詢問該邏輯名對應的新物理地址,再重新連接——這種更新邏輯地址映射關系和實際連接則往往是客戶端負責的事情了。
Erlang 中的global模塊提供的進程全局注冊服務,完成的就是類似功能,只不過erlang的global服務沒集中存儲這個命名關系,而是分布存儲在集群中了。
配置管理中心
配置中心為各應用實例提供了一個配置信息的集中存儲地。所有應用都可以將自己的配置信息,尤其一些動態變化的配置信息(靜態一般就由配置文件管理)存儲在該配置中心中,從而能在需要時(如重啟后)從配置中心獲取對應配置。
比如HBase中的range分區信息和Range Server的位置信息都屬于動態變化信息,這些信息傳統上是交給Master維護。但更合理的做法是將這些原信息存儲在統一的配置中心,如此以來即便Master倒掉,也可借助查詢配置中心獲得上述信息了——簡單講,Master把原數據存儲功能交出來了,自己不再負責,因為元數據存儲智能要求不高,完全可以由一個通用服務——配置管理中心——負責。
分布式鎖
分布應用中難免有需要串行化完成的動作——任務需要有序執行;或者有需要保護的臨界資源——一個時刻只能一個實例訪問。
上述的鎖要求和線程鎖的需求很類似,不同無非是放大了執行單位——從線程粒度變為實例粒度。使用上遵循非強制鎖(協同鎖)的使用方式,即鎖被作為一個外部服務,只提供加減鎖以及檢測是否加鎖的操作,但是不提供鎖的控制與協調工作。依賴于各應用自覺的去檢測是否加鎖,然后通過內部協議來約束各實例的行為。比如bigtable使用分布鎖chubby完成表格防并發訪問,就是各實例自己負責訪問前加鎖,訪問后解鎖。
故障監控服務
我們上面提到過Master的各種任務,其中有一點是負責監控slave各節點是否正常。如果發生異常則要進行故障切換等動作。而具體狀態監控則往往通過心跳等方式——當發現slave出現連續幾個未報心跳時,則認為slave發生故障。
顯然監控狀態這點事,也屬于通用型功能,完全可以提出來由一個公共服務來完成。也就是實例的心跳都報向該心跳監控服務,將故障探測這個臟活交給從我們特有的應用中剝離出來。
除了簡單監控各實例死活外,可能還要將其死訊通知其伙伴才算有始有終——因此告知給定的”聯系人”也應該是該服務所接管。
在分布系統中碰到故障時的主備切換(這里主從是active – non active關系,別和master/slave模式搞混淆),完全可以交給上述監控服務完成——當發現主點倒閉后,則通知備機點變為主,完成故障切換。
另外,為了避免系統雙主出現(因為往往主點要求必須是邏輯單點,才能確保操作的串行化次序,所以如果系統出現雙主,那怕暫時,也則會造成的數據錯亂)。因此各實例常常需要和監控服務定一個租約協議:當租約超期時,監控服務負責通知備機(重新選主);租約到期的實例則自殺來防止系統雙主出現。
注意:
全局命名中心、配置管理中心、分布鎖服務等幾個服務作為全局服務都有一個毋庸置疑的要求——高可用性;另外一個共性則是還一定的存儲能力——存儲配置、命名等記錄信息、鎖記錄;最后一個共性是服務必須邏輯上單點(即便內部用小集群實現),才能原子和串行處理請求事務。
我們必須感謝開源項目zookeeper(打心底敬佩yahoo公司,雖然它業務上最近不大景氣,但從其推出的zookeeper、S4等重量級的開源系統來看,無疑國內公司還未有能達到其高度的,至少開源胸懷上還不能相比),因為它一氣呵成的提供了上述三個服務。
Ø 它采用Paoxs類協議實現了高可用性(容錯率達到2F+1),以小集群形式實現了邏輯單點;
Ø 它采用樹形結構存儲描述實現了配置存儲管理和分布鎖;
Ø 它采用租約協議實現了故障監控(不需要我們自己實現心跳探測)。
從而用一種架構同時提供了上述幾種全局服務,逐步成為分布系統服務基石之一,越來越被業界所認可——不少自視甚高的公司最終都選擇zookeeper,放棄了自己獨自開發類似項目的想法和實踐。
不過要知道zookeeeper強于高可用性,而非存儲能力,雖然它確實可用來存儲一些配置類信息。但因為任何Paoxs協議需要在小集群中一致性協商,所以性能必然隨集群規模而下降,尤其是寫性能。所以不要把zookeeper當作key value服務那樣,進行頻繁IO請求。如果你只是想找一個可靠的地方存儲你那些不大變化的元數據,那么選擇zookeeper無疑是明智之舉。比如很多時候我們將分布系統的第一層(最上層)原信息存放在zookeeper上,比如你可以將向將hdfs的namenode分布化——將第一層分布分區和位置信息存放在zookeeper之上。
各種結構或半結構化數據存儲
數十年來使用的關系型數據庫在當今互聯網應用場景下已經顯得有點力不從心、或者說不合時宜了。究其原因大約如下:
1. 擴展性(scalability)不夠好。關系型數據庫實現上那些范式規則強調數據關系約束性,但在大規模分布系統上實現這些約束,顯然則不是很高效——性能不會很高。
2. 可用性不夠好。傳統上數據庫實現多采用專用機器或者說將異常情況交給硬件處理,本身軟件層面錯誤處理做的比較少(也就是主從備份等吧)。而互聯網世界中更多采用大量廉價存儲機器搭建起來,因此錯誤更常態化,所以軟件要做更多的容錯工作——多副本、故障切換等考慮要更多。
3. 數據組織方式不合時宜。關系型數據庫更合適處理離線的數據倉庫這種復雜關系模型的統計、分析任務。而互聯網上面數據組織和查詢有所區別,具體來講:
Ø 可能需要歷史版本。
Ø 可能關系性要求弱,而強調訪問速度,因此可能需要進行——空間換時間、反范式化、利用過濾代替jion、非精確查詢(允許少量錯誤)等折中手段達到性能要求。
Ø 可能數據更稀疏,列訪問特征突出。
Ø 可能需要圖元遍歷,比如廣度和深度遍歷好友等。
總而言之互聯網世界受歡迎的存儲系統(不敢稱數據庫系統)會有:
- Key Value 存儲 —— 代表作有dynoma (對等網實現) 、MemcacheDB、Tokyo Tyrant等
- NoSql 存儲 —— 代表作有Bigtable 、HBase 等
他們最大的共同特點是擴展性很強、總體性能幾乎可以線性擴展!弱點是和關系數據庫相比,關系特性要簡單的多,key value不用說,就是bigtable、Hbase等NoSql存儲也只是支持簡單的select查詢,復雜join、事務操作、存儲過程等強關系操作都能不支持。
更重要的妥協還在于放棄了傳統數據庫的ACID(Atomicity-原子性、Consistency-一致性、Isolation-隔離性、Durability-持久性)精髓;而去擁抱BASE(Basically Availble-基本可用、Soft-state、EventualConsistency-最終一致性) 和 CAP(Consistenc-一致性、Availability-可用性、Tolerance of network Partition-分區容忍性——可理解為部分節點故障或節點之間連接故障下系統仍可正常工作)。
這種弱一致性妥協極大松綁了分布式存儲設計,雖然和完美主義要求有不小差距,但對互聯網世界來說,夠了!!!
存儲的分層實現策略
如果能忍受性能上的一定損耗,我很贊同數據存儲的分層實現——即最下層是抽象類的塊存儲層,其上是分布(式)類文件系統層,建立在其上的是結構化和半結構化數據存儲層——即hadoop中的ssFile,hdfs層和其上的hbase的關系(google 也是分層設計的擁戴者)。
所謂類文件系統層就是在用戶態實現的分布式存儲系統,又為了方便管理實現了一些類文件操作的語意,如open/close/write/read/opendir等等。結構化和半結構化存儲層則是建立在類文件系統層之上,自己按需組織數據——數據又已文件形式存儲在類文件系統之上。
類文件系統這層負責所有集群磁盤資源管理:負責處理數據冗余存儲(多副本)、負責機器容錯(故障切換)、負責負載均衡等等任務。而上層結構化數據存儲層則不再關心這些特性,只需要處理具體的數據組織。這種分層實現避免了各種結構數據存儲系統重復開發分布系統的通用特性,也很有利于運維簡單化。
另外值得一提的是我個人很贊同類文件系統層采用——只允許追加方式修改的設計,不允許隨機修改。因為這樣做帶來了好處很明顯:
- 寫操作只會順序向前進行,對于IDE硬盤而言,能提供更大的寫吞吐和寫響應速度(對于SSD而言雖然沒有磁頭機械臂的移動,但其實順序寫也會帶來巨大收益)
- 不允許隨機修改,對于系統多副本一致性和故障后的反熵(同步各副本差異)操作帶來了很大遍歷,簡化了很多。
當然,如果下層的類文件系統只能追加寫,那么上層的結構化存儲必然需要以log structure方式實現。比如其上實現leveldb那樣實現key value結構存儲;或者hbase那樣實現nosql結構都是如此。Log structure存儲系統實踐證明,性能沒問題,而且很容易實現歷史版本查詢,還可實現快照等我們夢寐的高級功能;其代價則是需要更多的磁盤空間(還好,當前認為最廉價的就是磁盤了),還有經常的垃圾回收(別怕,總有閑的時候讓你回收)。
再次做一下廣告,我們cloudxy中子項目hlfs就是在hdfs之上實現的log structure 磁盤鏡像存儲系統,請見http://code.google.com/p/cloudxy/。歡迎喜歡云計算和開源的朋友加入。
重要思想重申
上面分析了似乎不少,其實各個部對于做分布式系統的朋友來說都應該都不陌生。只不過大家可能過去更多關心具體的分布應用、或者分布存儲、或者調度等專用系統的設計開發,而不大會上升到全公司甚至更大范疇的基礎架構體系角度去考慮——如何消除重復勞動、提高資源利用率。
所以思路的轉變是做云計算的首要前提——要從宏觀上考慮云計算實現,而不是一城一池的得失;其次從云計算技術上講其實并無太大躍變,其仍可看做是分布存儲、并行計算等普遍技術的再升華——主要體現更強調大規模、強調普通硬件、強調低成本等。
明白上述兩點,就能除去云計算的神秘。這里我們回過頭來再重申幾個云計算架構設計中的核心思想,我們把握這下面幾個主要原則,有所為有所不為。
Ø 分層劃分和實現功能
盡可能將系統分層設計(雖然會損失一定性能,但你得到的更多),這樣每層能各司其職,非常有利于功能收斂、系統穩定;減少重復勞動;便于調試;便于優化;解耦等。只有在一個好的層次結構下,系統才能有序演化。所以很建議將資源分配、塊存儲、類分布文件系統、結構數據存儲等功能分層實現。
Ø 接管資源分配
盡可能接管一切資源分配工作,原因很簡單——我們希望做類似超級計算機,那么就需要像單機操作系統那樣,在集群中接管資源分配:包括內存、IO、存儲等。莫要讓用戶程序自己直接調用本地操作系統接口使用資源,以防止從全局角度失控。比如不要讓用戶自己直接寫本地磁盤,而是使用存儲服務操作;也不要讓不通機器程序自己直連,而是要委托消息中間件進行連接。
Ø 應用服務上下文分布存儲
為了達到準實時的failover,以及按需調度服務等彈性,就必須保證服務的上下文數據不能本地持久化,而要分布式持久化到遠程,從而應用運行和位置無關。不怎么變的小數據可放在zookeeper中,大數據可借助于key value、hdfs、hbase等存儲。
Ø 化整為零管理
不要指望我們的云無所不能,無所不知;不要讓其做智能太高的事情,與其讓云告訴我們該做什么,不如我們告訴它該如何做。所以對于故障遷移、任務調度等差異性大,應用耦合性高的邏輯還是下放給應用自己去管理吧。
對外服務該如何做呢
當你真有了這么一套分布式體系架構后(即便沒有也可以對外服務,只不過運維成本很高罷了),對內服務搞定后(即便沒搞定也沒關系,對外也可以服務J——往往內部阻力更大),那么到底如何對外出賣服務呢?
在談服務方式之前,首先我們要清楚云計算服務的對象是誰?服務包含那些內容?
廣義上講任何互聯網服務都能納入云計算(至少他們這么宣傳),為了不陷入茫茫云海,我們收斂一下,只談一下俠義的云計算——出賣計算能力、存儲能力;那么顯然我們的服務對象就是第三方互聯網公司或者個人應用。
對外服務方式業界已經有兩個案例供我們借鑒。一個代表是亞馬遜的EC2 (服務stack中還有simpledb,s3,消息中間件等等);一個是google為代表的app engine(服務stack中有HRD等)。前者是基于虛擬機容器為外界提供計算、存儲服務;后者則是通過語言虛擬機+受限進程容器對外提供計算和存儲服務。
到底孰優?孰劣?
APP ENGINE和虛擬機比較
APP ENGINE和虛擬機(我們這里專指機器虛擬機如xen/kvm)概念上應該屬于一個范疇:資源沙盒;但實現差別很大。所謂尺有所長,寸有所短。它們也一樣,各自有自己的優勢,也有自己的不足。具體如何選擇,我們分析看看。
Ø 誰更輕,誰更重。
我們所謂輕是說系統資源使用更少,更有利于資源復用。搞操作系統的人應該都知道APP ENGINE相比虛擬機更輕,原因很簡單:
1. APP ENGINE不需要模擬硬件平臺,它作為宿主操作系統內的進程運行;而XEN需要模擬硬件平臺,需要截獲敏感性硬件指令轉換處理,也需要運行級上下文切換。
2. APP ENGINE更有利于資源復用,因為其不需要預先霸占資源(主要是內存資源),而是按需使用(你甚至可以突發性使用整個機器的內存);而XEN等虛擬機則需要預先霸占資源(雖然QOD等模式也開始學習按需使用內存,但超限使用內存還是很難——除非你愿意費勁去采用熱插拔技術;另外值得贊賞的是TMEM技術似乎可以避免預先霸占,但不幸的是它需要修改DOMU的內核中的內存分配例程)。
輕重就這些區別嗎? 其實不然,我個人認為系統虛擬機最重的是對網絡資源(mac地址ip地址)的使用!系統虛擬機每個都會霸占一個mac和ip地址,別把村長不當干部,以為虛擬的網絡地址不是真實地址。對于路由器、交換機等網絡設備而言,它們仍然會占用地址映射表等。一般路由器ip-mac表也就3000多項,用一個少一個,所以大規模系統使用虛擬機勢必要定制更多表項的路由器;另外,如果是大二層網中運行眾多虛擬機,則廣播風暴也是一個不得不考慮的麻煩。所以虛擬機對網絡設備來講更尤為“重。
Ø 誰更友好,誰更約束。
使用APP ENGINE的最大不便在于,你必須接受它的約束——資源訪問需要按照其規定的接口進行;不能自己啟進程等。這種不便使得APP ENGINE多是被個人票友所熱衷,而公司用戶沒有幾個。公司若要使用APP Engine則必須要修改自己已有程序、修改自己已有運維方式、更糟糕的是開發人員培訓或者招聘成本都要高很多(市場上找一個會Linux開發的人,要比找一個會app engine開發的人要容易的多)——當然這些不利因素對于公司內部使用倒不存在,所以google自己內部使用app engine到是可行(但我也聽說gmail也不再使用app engine了,難道內部都推不開嗎?)
機器虛擬機則對用戶很是友好,所有程序都可以不加修改的運行在機器虛擬機當中,如果實現二層虛擬子網,那么已有的管理軟件都可原封不動遷移過來——再次做一下廣告,我們cloudxy項目目標之一就是實現二層子網虛擬化。所以對于用戶而言,他們顯然更喜歡機器虛擬化方式的云計算服務。亞馬遜在美國的成功也證明了這點——注意一下,在美國成功不代表在中國也能成功,畢竟互聯網在中國還是暴利,所以沒有多少像樣的企業為了節約目的而使用你虛擬機租賃服務,另外在當今國內環境中,也沒有幾個企業敢于把自己核心數據托管到別人提供的虛擬機之上。
注:
除了xen/kvm機器虛擬機外,還有zone,vps等系統虛擬機,以及jvm、python等語言虛擬機、進程虛擬機qeum,甚至普通進程也可看虛擬機。從輕重角度將,機器虛擬機最重其次是系統虛擬機。
云計算生態圈
下來說的純粹是題外話了,都是個人觀點,不知所云:)
云計算如果僅僅是提供計算資源和存儲資源服務(如亞馬遜那樣),我個人認為只是一個初級形態,而且在中國可能沒多大前途。
個人認為真正理想的云計算應該是一個“圍繞數據服務的生態圈”,在數據周圍應聚集大量的第三方應用——他們使用數據同時又產生數據,從而數據越來越多、越來越有序;應用也越來越豐富、越來越專業——這就猶如滾雪球,良性循環,價值逐步放大。
偉大的企業一定是積累了足夠有價值的數據(網頁內容、買賣記錄、用戶關系等都屬于數據)。不管怎樣,要明白第三方企業入駐入你的云計算服務,首要是希望獲得你的數據或者流量(我認為前者更重要),而不是看重什么計算和存儲服務(互聯網暴利時代,機器成本目前還不是企業最緊迫的問題)。但如果在你的云環境中更有利于他們獲得數據和流量,那他們自然而然會接受將服務hosting到你的云中。
以ebay為例來說,長期積累的交易記錄就是其最有價值的數據,這些數據準確、有序、結構化強,非常有利于檢索、分析;假若再結合交易者信息,個性化服務則是舉手之勞(如果不涉及隱私的話);另外它還有很強的入口作用。這些無疑都是吸引第三方應用的重要因素,如果他們開放數據,又提供托管環境——托管環境中能更快訪問其數據,甚至還能提供統一的支付、用戶認證等服務,那么無疑第三方是愿意租用其計算和存儲服務的。而第三方應用,尤其那些數據分析應用所產生數據又可被其它應用所使用,則就進入了上面談到的滾雪球模式了:)
國內的百度、騰訊、阿里、新浪微博等幾個大佬們都有自己的數據和入口地位。百度搜索入口能力強,結構化數據弱一些,比較適合于咨詢類應用;騰訊游戲/sns類入口能力強,用戶關系數據強,適合游戲類應用;阿里電子商務內入口能力強,結構化商業數據豐富,適合于商務服務類應用;新浪微博用戶極度活躍、消息產生和傳播優勢明顯,也很適合做咨詢和游戲類應用。所以這幾家做云計算成功可能性最大,希望他們能抓住機會,取得成功。
不成熟的幾個斷言
Ø 專用系統必然比通用系統性能更高
Ø 網絡帶寬是當前云計算中的最短板
Ø 沒有能統一天下的云計算環境
Ø 云計算絕不等于虛擬機,虛擬機只不過是沙箱實現的一種。
Ø 絕對的實時調度難以在實際中做到,自動化管理可以期待。
Ø 萬兆網和SSD等新硬件的到來將帶來云計算架構的變革。