對于云服務(wù)來說,三分靠開發(fā),七分靠運維。云存儲究竟難在哪兒?為什么 HDFS,glusterfs,mogilefs 不能作為云存儲的基礎(chǔ)設(shè)施?本文基于對七牛云存儲首席架構(gòu)師李道兵帶來的《三分開發(fā),七分運維》的精彩分享的整理,希望大家能從中尋得答案。
我們?yōu)槭裁葱枰粋€公有云?
作為一個創(chuàng)業(yè)或者開公司也好,最基礎(chǔ) 的要解決幾個問題。第一個問題你的客戶是誰,簡單的說客戶就是有存儲需求的人。什么人有存儲需求呢?像一些應(yīng)用就有很多的圖片存儲需求,比如說需要把拍的 照片發(fā)到網(wǎng)上,存儲需求就很強,有很多做音頻、視頻的,比如說美拍,它就面臨一個很大的問題,用戶的視頻要放在哪里?
另外一個很大的需求就是說日志存儲,一個網(wǎng)站每天產(chǎn)生很多的日志,也有很大的價值。但是把它存哪里是一個大問題。
日志和富媒體都還面臨著另外一個問題,我需要有很強的運維功底,不夠強的話,維護(hù)起來成本比較高。特別是對創(chuàng)業(yè)團(tuán)隊來講,組建一個優(yōu)秀的運維團(tuán)隊是一個非常昂貴的事情。
別人去解決這個問題的時候,他們的成本究竟是多少呢?比如說存儲圖片,在我們學(xué)PHP的時候,就有一些超級簡單的解決方案,比如直接上傳到服務(wù)器的磁盤里邊。
這種情況你的文件會放在磁盤里面,在使用RAID5或者RAID10的情況下,可以保證在單個磁盤壞了的時候整個數(shù)據(jù)不丟,是不是這樣就可以了呢?至少還有如下幾個問題,第一個問題是宕機,特別是主板損壞或者內(nèi)存損壞的情況,在機器修好之前這部分?jǐn)?shù)據(jù)就不可訪問了,互聯(lián)網(wǎng)企業(yè)宕機造成的損失越來越大,用這種方案帶來的第一個問題是單點故障怎么解決?這是個很難接受的后果。
第二個問題是IOPS和吞吐量都很有限。IOPS的限制在你的磁盤。一般存圖片和音視頻不會使用SSD,如果做RAID5的話你能拿到 200~300的IOPS,RAID10能達(dá)到600左右,但如果你有大量的小圖片(比如縮略圖),這點 IOPS 就無法支撐你的業(yè)務(wù)了。另外一點是吞吐量,如果整個網(wǎng)站越做越大的時候,一些音視頻的下載很可能把你的機器壓跨,特別是在只配備了千兆網(wǎng)卡的情況下。萬兆網(wǎng)卡能好一些,但是對應(yīng)的成本很高。
最大的問題是容量有限,市面上能買的是4T盤,12塊盤加起來是48T,你做一個 RAID10后是24T。你的存儲存滿了之后,單機存儲方案就有問題了。存儲滿了這個方案就完全走不通了。所以說這種方案只適合一些實驗性質(zhì)的,自己玩一玩的東西還是很適合,如果你去創(chuàng)業(yè),開一個新公司,真正做一個服務(wù)的話,從最開頭你就要考慮這個東西存哪里合適,要怎么存。
glusterfs的問題
回到幾年前的話,那時候有一個很漂亮的方案的glusterfs,做的比較早,大概 2006年就應(yīng)用的比較多了。他有很多很炫的東西,像可以當(dāng)一個普通磁盤來掛載,你可以在上面創(chuàng)建目錄,也可以使用任何其他 POSIX API,所以你以前針對本地文件的所有程序不用做任何修改就可以放到上面去。第二個來講無中心的架構(gòu),機器數(shù)量不受限制。但是實際用下來缺點也很明顯。
第一個問題是無中心的架構(gòu)有兩個缺點是致命的,是所有無中心架構(gòu)都無法逃避的缺點,一上來你不會上一個很大的集群,會先上3臺或者6臺測試一下,當(dāng)你的容量不夠的時候,就會想到擴(kuò)容到12臺,基于客戶端Hash就會出現(xiàn)問題,之前一三五七放第1組,二四六八放第2組,現(xiàn)在變成一五放第1組,二六放第2組。剩下的三七要放到第3組,四八要放到第4組。你有一半的數(shù)據(jù)需要遷移,這個時候你整個系統(tǒng)就處于不可用的狀態(tài)。你知道搬數(shù)據(jù)特別是通過網(wǎng)絡(luò)搬數(shù)據(jù)是一件超級痛苦的事情,大家有空可以算一下,簡簡單單搬一個4T的盤透過千兆網(wǎng)搬的話是4萬秒,差不多是一天,這樣才是一塊盤。如果通過網(wǎng)絡(luò)搬一臺機器12塊盤的話,幾天就過去了。這種架構(gòu)導(dǎo)致你的整個系統(tǒng)是一個固定容量好說,如果你的系統(tǒng)容量不固定,在你擴(kuò)容的時候會超級痛苦。
第二個問題這種客戶端架構(gòu)會導(dǎo)致兩三臺機器結(jié)構(gòu)完全對稱,從一個方面來說比較好維護(hù),我這個數(shù)據(jù)的這一份知道在哪里,另外也知道在哪里。但是有一個問題,你第一塊磁盤壞了,你修復(fù)要多久?在對稱盤的情況下,第一塊磁盤修復(fù)了,我把這塊卸下來,安裝一模一樣好盤到當(dāng)前位置,拷貝出來數(shù)據(jù)。一塊4T要拷16小時,而且你還要考慮到在拷貝的過程中不要跟你的業(yè)務(wù)搶帶寬。在16個小時之內(nèi),你的第二塊盤不能壞,有沒有可能運氣超級不好的時候,第一塊壞了的話,沒有修復(fù)完成的時候,第二塊又壞掉了,這對你來講是災(zāi)難性的事件。
第二個是它自身的設(shè)計有些問題,數(shù)據(jù)鏈路非常長,所以小文件性能是超級差的。比如說幾十K級別的文件,在互聯(lián)網(wǎng)應(yīng)用里面,特別是針對圖片的一些應(yīng)用的話,幾十K是超級常用的東西。客戶上傳一些原始圖或者縮略圖等等,這些小文件的性能超級差。
第三個是要實現(xiàn)兼容,大概是40多個API,簡單的云存儲只需實現(xiàn)三到四個API就可以了。40多個API導(dǎo)致它的整個架構(gòu)非常復(fù)雜。
所以說對于我來講glusterfs只能適用于一些特殊領(lǐng)域,小規(guī)模、容量可預(yù)估的,同時你的程序很難改造到基于云存儲的API來實現(xiàn),比如買的是第三方提供的程序,這種情況下你用這個是最好的選擇。
mogilefs 的問題
互聯(lián)網(wǎng)企業(yè)的話,mogilefs用的比較多,中小網(wǎng)站存一些圖片等等的用得非常廣。優(yōu)點是有中心、擴(kuò)容和修復(fù)更方便。缺點是總條目數(shù)受中心限制,還有就是大文件上傳不方便。因為它的中心實際是一個數(shù)據(jù)庫,所以他的能力就受這個數(shù)據(jù)庫的能力限制。比如說mogilefs幾千萬條問題不大,再往上的數(shù)量級呢?幾億、十億,甚至更多的話就有點扛不住了。中國網(wǎng)民是4億人,如果每個人都來使用你的應(yīng)用的話,一百億的文件是一個可以很快達(dá)到的高度。在這個領(lǐng)域來說,整個數(shù)據(jù)庫會出現(xiàn)問題,會扛不住。
所以說mogilefs適用于文件數(shù)量不太多,幾千萬水平,總?cè)萘縋B往下的規(guī)模。訪問頻率在數(shù)據(jù)庫能扛住,同時不用考慮太多大文件的問題。
Hadoop 的問題
當(dāng)然說到存儲不得不提Hadoop的問題,他的優(yōu)點是超強的伸縮性,不用任何改動就可以上到1000臺規(guī)模,阿里在5000臺做過一些實驗。只不過他們現(xiàn)在遷移到自己的系統(tǒng),這個就慢慢地放棄掉了。
Hadoop拿來存文件有些什么問題呢?本身設(shè)計的目標(biāo)不是做文件存儲的。它是按照離線數(shù)據(jù)分析業(yè)務(wù)來設(shè)計的,可用性就低了。你在上面不停地取文件,大概有很小的一個概率,大概千分之一到千分之五的情況下是取不到的。對離線分析業(yè)務(wù)來講不是什么問題,取不到等三四秒重新做一遍就可以了。但是對在線應(yīng)用來講的話,圖刷不出來了,是一個紅叉,或者說音視頻播放不了,這都是很大的問題。
大概是兩個方面造成的,一個是Java語言本身的問題,另一個是hadoop數(shù)據(jù)在平衡時數(shù)據(jù)訪問會超時。
第二個是小文件支持不好,Hadoop的塊大小是64MB,你在上面直接存幾十K的文件,那么它的NameNode內(nèi)存會被用滿,可能你用十臺的話,就已經(jīng)到極限了。
混搭模型
就是說你做存儲的話,很多小的公司自己做存儲是基于這些。還有一些其他的,比如說Hbase、Hadoop+HBase等等這些,簡單思路就是把小文件拼成一個大文件。
你有足夠強的運維么?
前面提到這些存儲的局限性,其實更重要的問題是你怎么做好運維的工作,為什么要運維?一個軟件就可以了嗎?你的容量越大你需要解決的問題就很多。你的機器會掛,磁盤會滿,網(wǎng)絡(luò)滿,內(nèi)存不足。這個還跟你簡單的應(yīng)用層不一樣,應(yīng)用層的服務(wù)遇到問題很簡單把機器下線,把IP從nginx去掉,反向代理不到這臺機器來。如果應(yīng)用層做大再買機器就可以了。數(shù)據(jù)庫層面壓力過大怎么辦?分庫、分表以及機器本身的提升。用更好的磁盤、CPU來提升單臺數(shù)據(jù)的能力,這就是我們常規(guī)的應(yīng)用層和數(shù)據(jù)庫的伸縮辦法。
但是在存儲層就會面臨運維壓力會非常大,磁盤從你簡單的幾塊到達(dá)幾千塊的時候,簡單存1PB的數(shù)據(jù),數(shù)據(jù)要存3份,3個PB,數(shù)據(jù)盤按填充率75%計算,就需要一千塊4T磁盤。什么意思呢?考慮到磁盤壽命為3年多,那么平均每一天就有一塊磁盤會壞掉,這是你面新的問題。機器會壞,磁盤會壞,同時又熱點請求,磁盤滿、網(wǎng)絡(luò)滿,磁盤過滿內(nèi)存不足。體系大到這個程度的時候,你還有大量的交換機,你還要考慮交換機壞死的情況,網(wǎng)絡(luò)上面的故障也會出來。網(wǎng)線也會出事,可能會有壞掉,接口不好等等都會變成你的需求。機器多了還有一個額外的問題,如果出現(xiàn)安全更新,機器少的時候你可以手動來做。但是數(shù)量達(dá)到一百臺的時候就做不了,你就需要安全更新的運維方案。
一個想法,類似于我們?nèi)ベIEMC存儲一樣,你給我一個簡單的接口,賣給我一個盒子,然后你幫我把這些情況都解決好,不是說不可以,但是賣的很貴。但是有貴的道理,有些事情確實很難做,要不然所有東西有很高程度的冗余,你自己把細(xì)節(jié)測試的更全面,做的更好。
第二個來講你還得防止系統(tǒng)過敏,這種事情不是一個罕見的現(xiàn)象了。之前amazon東部機房有大面積宕機,原因是什么呢?是一些小問題,小問題修復(fù)起來造成了更大的問題。拿人來比喻就是是過敏,可能是一個小問題,但是由于它的一些修復(fù)機制放大了這個問題,最后導(dǎo)致整個網(wǎng)絡(luò)堵死,又觸發(fā)了很多磁盤備份的工作,導(dǎo)致壓力過大,最后整個機房的機器全部宕掉。
如果把所有的意外防范都做在程序里邊,也會導(dǎo)致軟件研發(fā)和周期非常長,架構(gòu)復(fù)雜度也大規(guī)模增加了。
這些問題帶來的是你在市面上根本找不到一個云存儲軟件是非常完美的,能夠大規(guī)模降低運維成本。同時你也很難找到足夠多足夠好的運維解決這個問題。
你需要更多基于云存儲的服務(wù)
另外一個需求是基于存儲的計算。比如說一個簡單做圖片的,圖片有iPhone、安卓的,不同客戶端都有不同的分辨率需求。為了節(jié)約流量,客戶端希望下載一個小的圖片而不去下載原圖,iPhone和安卓要面臨分辨率的問題,你的產(chǎn)品經(jīng)理和設(shè)計師會突然說之前覺得300很合適。但是決定加一個邊框,那么300的寬度就要變成298。你會發(fā)現(xiàn)你要把所有圖片重新做一下縮放,這個工作壓力非常大。所以你就希望有一些輔助的系統(tǒng)幫你做好這個事情,比如說你希望能有人能幫你搞定縮放、水印、原圖保護(hù)。
類似的音視頻領(lǐng)域有轉(zhuǎn)碼、切片、合成、快速預(yù)覽的需求。有些客戶還有自定義需求,比如美顏相機、人臉識別、數(shù)據(jù)統(tǒng)計。對于私有存儲方案就很麻煩了,但是你用一個公有云就可以了。
單機房100PB的挑戰(zhàn)
接下來講講云存儲對我們來講我們面臨的挑戰(zhàn)是什么?單機房100PB的挑戰(zhàn)是我們現(xiàn)在需要考慮的事情。就是說我們稍微細(xì)算一下,100PB意味著什么?4000臺存儲計算的話,不考慮冗余的情況下每臺承擔(dān)25TB的容量。考慮3份冗余后它要承擔(dān)大概75TB,4T乘12塊盤是48T,是不夠的。我們需要引入新的存儲方式,減少冗余。
在200KB的文件平均大小情況下,原數(shù)據(jù)條目是五千億條。怎么做好穩(wěn)定的增刪查改工作,是我們需要考慮的問題。
元數(shù)據(jù)庫的壓力不僅是維護(hù)的問題,更重要的是扛住100W每秒的請求頻率,這是數(shù)據(jù)庫怎么扛住的問題。
除了這些還有前面提到的,比如說機器、網(wǎng)絡(luò)硬件、機房的出入口等等都會有問題,這些問題怎么解決才是我們考慮比較多的一個問題。
在單機房100PB的挑戰(zhàn)里面,架構(gòu)做的東西不太多。對于架構(gòu)來講,我們能做好的就是幾件事情,第一個每個組件都是高可用,可伸縮的。同時,我的組件能輕易的從10個伸縮到100個甚至到4k、5k都沒有問題。在設(shè)計階段高可用、可伸縮都要作為一個必選項來考慮。
第二個是保持每個遠(yuǎn)程調(diào)用都是可重入的,最簡單的拿交易做例子,什么是不可重入?給賬戶添加一百塊錢的API調(diào)用是不可以重入的,請求對方?jīng)]有返回再發(fā)一次就不合適了,有可能你給用戶一百塊,也有可能給用戶二百塊。可重入的加錢API長什么樣呢?如果賬戶版本是21的話,給它的賬戶添加一百塊錢,并且把版本改為22,重新調(diào)一次的話要不然它成功,要不然它告訴我對方的版本不變。我根據(jù)版本是否變化去確認(rèn)我們之前成功還是不成功,這是可重入的概念。
我們這邊不涉及金錢的交易,所以很多時候會比這種簡單一點。
第三點網(wǎng)絡(luò)也是不可信的,傳過來一個文件,這個文件是否正確,我們?nèi)绾蝸肀WC呢?如果我們?nèi)萑体e誤文件的話,客戶那邊就會給我們大量的抱怨。而且由于我們有緩存存在,這個問題會一直錯下去,直到緩存過期。所以對我們來講所有網(wǎng)絡(luò)傳輸都需要做校驗,架構(gòu)層面做到這幾點,會保證你不會出一些低級的錯誤。
比較難的是規(guī)模擴(kuò)大了之后怎么辦?來自墨菲定律的詛咒:凡是可能發(fā)生的都會發(fā)生,所有你想得到的事情都會發(fā)生,只是發(fā)生在哪一天而已。
墨菲定律的詛咒第一個是多磁盤故障,常規(guī)情況一般是一塊磁盤壞了怎么修復(fù)。在量特別大的情況下你就面臨一個問題,兩塊磁盤一起壞會發(fā)生什么事情?多塊磁盤一起壞發(fā)生什么事情?如果其他機器屬于維護(hù)的狀態(tài)你又應(yīng)該怎么做?
第二個是交換機故障,在常規(guī)的做設(shè)計的時候,一般不會去考慮這個問題。但是在做存儲的時候,這就變成你必須考慮的問題,你要仔細(xì)的給你存儲做一些分組。分組的目的是這臺宕了,怎么做到客戶完全無感知。不要把一份數(shù)據(jù)的所有備份都在同一個交換機下面,這是我們要確保的東西。
第三個是人為失誤,運維的工作量大就會有一些人為失誤。怎么確保即使操作失誤有不會影響你的系統(tǒng),這是我們更多要注意的一個方向。
我們能做到什么呢?多預(yù)案。針對你的每樣事情你需要有一個預(yù)案,單磁盤壞了你怎么處理,多磁盤壞了怎么處理,交換機壞了整個流程怎么處理的?這些東西不要寫進(jìn)你的預(yù)案里面,在運維發(fā)生報警的時候,打開預(yù)案一步一步的往下操作。
第二個是多演習(xí),讓事故處理常態(tài)化,我們要有一個很大的測試集群,像我們前面提到的一些故障我們都會做一些定期或者不定期的演習(xí)。讓大家能夠了解這些東西會有哪些我們想到的事故。
第三個常規(guī)的數(shù)據(jù)處理一鍵化、自動化。更多的是我前面提到的防過敏,當(dāng)有人在里面的時候,這種事故處理也許慢了一分兩分鐘。但是好處是通過人為介入到這里,整個事故不會擴(kuò)大化,會讓它停掉,避免大規(guī)模的出現(xiàn)錯誤。
總結(jié)一下,自建存儲的缺點是運維成本高,便宜一點的運維人員一年也要15w左右,加上機器成本大概30w。如果你買100TB的云存儲話,也就是15w左右,所以購買云服務(wù)更劃算一些。
常規(guī)解決方案存在適用領(lǐng)域狹窄的問題,不夠通用。也就是你今天的業(yè)務(wù)是圖片,用mogilefs搞定了,之后想做視頻,mogilefs就不行了,又得找新方案。
最后推薦兩本書,KK的《科技想要什么》,以及Eric Ries的 《THE LEAN STARTUP》。第一本講了很多趨勢方面的東西,第二本講了在創(chuàng)業(yè)過程中怎么快速試錯,怎么快速讓你的用戶增長起來,在這方面的東西非常值得一看。