淘寶技術(shù)發(fā)展
目錄
一、引言
四、淘寶技術(shù)發(fā)展(Java時(shí)代:脫胎換骨)
五、淘寶技術(shù)發(fā)展(Java時(shí)代:堅(jiān)若磐石)
六、淘寶技術(shù)發(fā)展(Java時(shí)代:創(chuàng)造技術(shù)-TFS)
七、淘寶技術(shù)發(fā)展(分布式時(shí)代:服務(wù)化)
作者:趙超
光棍節(jié)的狂歡
“時(shí)間到,開搶!”坐在電腦前早已等待多時(shí)的小美一看時(shí)間已到 2011 年 11 月 11 日零時(shí),便迫不及待地投身于淘寶商城一年一度的大型網(wǎng)購促銷活動(dòng) —— “淘寶雙11購物狂歡節(jié)”。小美打開早已收藏好的寶貝 —— 某品牌的雪地靴,飛快的點(diǎn)擊購買,付款,一回頭發(fā)現(xiàn) 3000 雙靴子已被搶購一空。
小美跳起來,大叫一聲“歐耶!”
小美不知道,就在 11 日零點(diǎn)過后的這一分鐘內(nèi),全國有 342 萬人和她一起涌入淘寶商城。當(dāng)然,她更不知道,此時(shí)此刻,在淘寶杭州的一間辦公室里,燈火通明,這里是“戰(zhàn)時(shí)指揮部”,淘寶技術(shù)部的一群工程師,正在緊盯著網(wǎng)站的流量和交易數(shù)據(jù)。白板上是他們剛剛下的注,賭誰能最準(zhǔn)確地猜中流量峰值和全天的交易總額。他們的手邊放著充足的食物和各類提神的飲料。
一陣急促的電話聲響起來,是前線部門詢問數(shù)據(jù)的,工程師大聲報(bào)著:“第 1 分鐘,進(jìn)入淘寶商城的會(huì)員有 342 萬”。過一會(huì)工程師主動(dòng)拿起電話:“交易額超過 1 億了,現(xiàn)在是第 8 分鐘。”接下來,“第 21 分鐘,剛突破 2 億”?!暗?32 分鐘,3 億了”?!暗?1 個(gè)小時(shí),4.39 億”。這些數(shù)據(jù)隨后出現(xiàn)在微博上,引起一片驚呼。
“完蛋了!”突然有人大喝一聲,所有的眼睛都緊張的盯著他,只見他撓撓頭,嘿嘿的笑道“我賭的少了,20 億輕松就能過了,我再加 5 億”,他跑去白板邊上把自己的賭注擦去,寫上 25,接下來有人寫上 28,有人寫上 30,有人跑到微博上開下盤口,同事們紛紛轉(zhuǎn)載下注。接下來的這 24 個(gè)小時(shí),戰(zhàn)時(shí)指揮部的工程師們都不能休息,他們盯著網(wǎng)站的各種監(jiān)控指標(biāo),適時(shí)的調(diào)整機(jī)器和增減功能。頂住第一波高峰之后,這些人開始忙里偷閑的給自己買東西,大家互相交流著哪家買的移動(dòng)硬盤靠譜,哪家衣服適合自己的女朋友,不時(shí)的有人哀嚎寶貝被人搶了、信用卡額度不夠了。同時(shí),旁邊白板上的賭注越下越大。
11 月 11 日,這個(gè)棍子最多的日子被網(wǎng)民自我調(diào)侃的變成了一個(gè)節(jié)日 —— “光棍節(jié)”。而淘寶網(wǎng)又用瘋狂的折扣促銷給它賦予了另外一個(gè)意義 —— “購物狂歡節(jié)”。2011 年 11 月 11 日這一天,淘寶商城與淘寶網(wǎng)交易額之和突破 52 億,這個(gè)數(shù)字是“購物天堂”香港一天零售總額 8.5 億的 6 倍。
網(wǎng)民感受到的是瘋搶的喜悅,而網(wǎng)站的技術(shù)人員感受到的卻是“壓力山大”。就如同你家辦酒席,宴請(qǐng)左鄰右舍,這個(gè)辦起來容易。倘若宴請(qǐng)十里八鄉(xiāng)所有的人,吃飯的人自然開心,但卻不是一般人家能夠辦得起來的。能辦得起來如此盛宴者,需要強(qiáng)大的財(cái)力物力、組織能力、技術(shù)實(shí)力(例如做這么多菜,你的炒鍋一定要是“分布式的”、“可復(fù)制的”、“可擴(kuò)展的”,洗菜切菜要有“工作流引擎”,上菜的路徑要用圖論來計(jì)算出來,甚至連廚房的下水道都要重新設(shè)計(jì))。
淘寶能夠舉辦如此盛宴,網(wǎng)站的技術(shù)實(shí)力可見一斑。淘寶網(wǎng)擁有全國最大的 Hadoop 分布式計(jì)算集群之一,日新增數(shù)據(jù) 50TB,有 40PB 海量數(shù)據(jù)存儲(chǔ)。分布在全國各地 80 多個(gè)節(jié)點(diǎn)的 CDN 網(wǎng)絡(luò),支持的流量超過 800Gbps。淘寶的搜索引擎能夠?qū)?shù)十億的商品數(shù)據(jù)進(jìn)行實(shí)時(shí)搜索,另外還擁有自主研發(fā)的文件存儲(chǔ)系統(tǒng)和緩存系統(tǒng),以及 Java 中間件和消息中間件系統(tǒng),這一切組成了一個(gè)龐大的電子商務(wù)操作系統(tǒng)。另外從商業(yè)數(shù)據(jù)上來看,Amazon 的財(cái)報(bào)顯示 2011 年完成了大約 480 億美金的交易額,eBay 2011 年財(cái)報(bào)全年完成了大約 600 億美金的交易額(不包括其獨(dú)立的汽車交易平臺(tái))。不管從交易額、商品數(shù)量、同比增速等指標(biāo)上看,淘寶網(wǎng)均遠(yuǎn)超于此,是目前全球最大的電子商務(wù)平臺(tái)。(由于淘寶非上市公司,未公布2011年業(yè)績,以上內(nèi)容來自淘寶網(wǎng)技術(shù)副總裁@_行癲?的微博)
以上這些技術(shù)數(shù)據(jù)可能已經(jīng)讓一些同學(xué)產(chǎn)生不適的感覺,為了讓更多的人讀懂這本書,我們從技術(shù)的角度來看,小美訪問淘寶網(wǎng)的時(shí)候,網(wǎng)站上發(fā)生了什么事情。參考資料:《技術(shù)普及帖:你剛才在淘寶上買了一件東西》,來自南京郵電大學(xué)孫放同學(xué)。
為了有個(gè)更直觀的對(duì)比,我們說一個(gè)同行,他在 2011 年光棍節(jié)之前做促銷,流量上去之后,達(dá)到 12Gbps(他們有這么大的流量,老板很高興,在微博上面說了這個(gè)數(shù)據(jù)),這時(shí)候流量達(dá)到了極限,網(wǎng)站幾乎掛掉,用戶無法下訂單。而淘寶網(wǎng)光棍節(jié)當(dāng)天網(wǎng)絡(luò)的流量最高達(dá)到 800多Gbps,帶給各家銀行和快遞公司的流量也讓他們壓力山大,如臨大敵(后來,他們以能夠撐住淘寶帶來的流量為榮而到處宣傳)。另外如果你在網(wǎng)上購買過火車票的話,更能體會(huì)到網(wǎng)站能支持多大的流量有多重要。但這不是一朝一夕做出來的,也不是有錢就能辦到的。
以上對(duì)比的這些網(wǎng)站,也許讀者很容易就猜到是哪一家,這里拿出來作對(duì)比,絕對(duì)沒有嘲笑人家的意思,采用通常的網(wǎng)站技術(shù)方案,能做到這種程度已經(jīng)不錯(cuò)了。任何網(wǎng)站的發(fā)展都不是一蹴而就的,在什么樣的階段采用什么樣的技術(shù)。在發(fā)展的過程中網(wǎng)站會(huì)遇到各種各樣的問題和業(yè)務(wù)帶來的壓力,正是這些原因才推動(dòng)著技術(shù)的進(jìn)步和發(fā)展,而技術(shù)的發(fā)展又會(huì)反過來促進(jìn)業(yè)務(wù)的更大提升。二者互為因果,相互促進(jìn)。如今淘寶網(wǎng)的流量已經(jīng)是全球排名第12、國內(nèi)排名第3(美國的 eBay 全球排名23,國內(nèi)前兩名是百度和騰訊)。淘寶網(wǎng)的系統(tǒng)也從使用一臺(tái)服務(wù)器,到采用萬臺(tái)以上的服務(wù)器。本書就為大家描述淘寶網(wǎng)在整個(gè)發(fā)展過程中,所有的主動(dòng)和被動(dòng)的技術(shù)變革的前因后果,這由很多有趣的故事組成。
正如同很多人或組織成功了以后,就會(huì)為自己的出身編造一個(gè)美麗的傳說。淘寶網(wǎng)的出身,網(wǎng)上也有非常多的傳說,下面我們就從它的出生開始講起。
2003 年 4 月 7 日,馬云,在杭州,成立了一個(gè)神秘的組織。他叫來十位員工,要他們簽了一份協(xié)議,這份協(xié)議要求他們立刻離開阿里巴巴,去做一個(gè)神秘的項(xiàng)目。這個(gè)項(xiàng)目要求絕對(duì)保密,老馬戲稱“連說夢(mèng)話被老婆聽到都不行,誰要是透漏出去,我將追殺到天涯海角”。這份協(xié)議是英文版的,匆忙之間,大多數(shù)人根本來不及看懂,但出于對(duì)老馬的信任,都卷起鋪蓋離開了阿里巴巴。
他們?nèi)チ艘粋€(gè)神秘的據(jù)點(diǎn) —— 湖畔花園小區(qū)的一套未裝修的房子里,房子的主人是馬云。這伙人剛進(jìn)去的時(shí)候,馬云給他們布置了一個(gè)任務(wù),就是在最短的時(shí)間內(nèi)做出一個(gè)個(gè)人對(duì)個(gè)人(C2C)的商品交易的網(wǎng)站?,F(xiàn)在出一個(gè)問題考考讀者,看你適不適合做淘寶的創(chuàng)業(yè)團(tuán)隊(duì)。親,要是讓你來做,你怎么做?
在說出這個(gè)答案之前,容我先賣個(gè)關(guān)子,介紹一下這個(gè)創(chuàng)業(yè)團(tuán)隊(duì)的成員:三個(gè)開發(fā)工程師(虛竹、三豐、多?。⒁粋€(gè)UED(二當(dāng)家)、三個(gè)運(yùn)營(小寶、阿珂、破天)、一個(gè)經(jīng)理(財(cái)神)、還有就是馬云和他的秘書。當(dāng)時(shí)對(duì)整個(gè)項(xiàng)目組來說壓力最大的就是時(shí)間,怎么在最短的時(shí)間內(nèi)把一個(gè)從來就沒有的網(wǎng)站從零開始建立起來?了解淘寶歷史的人知道淘寶是在 2003 年 5 月 10 日上線的,這之間只有一個(gè)月。要是你在這個(gè)團(tuán)隊(duì)里,你怎么做?我們的答案就是:買一個(gè)來。
買一個(gè)網(wǎng)站顯然比做一個(gè)網(wǎng)站要省事一些,但是他們的夢(mèng)想可不是做一個(gè)小網(wǎng)站而已,要做大,就不是隨便買個(gè)就行的,要有比較低的維護(hù)成本,要能夠方便的擴(kuò)展和二次開發(fā)。那接下來就是第二個(gè)問題:買一個(gè)什么樣的網(wǎng)站?答案是:輕量一點(diǎn)的,簡單一點(diǎn)的,于是買了這樣一個(gè)架構(gòu)的網(wǎng)站:LAMP(Linux+Apache+MySQL+PHP)。這個(gè)直到現(xiàn)在還是一個(gè)很常用的網(wǎng)站架構(gòu)模型。這種架構(gòu)的優(yōu)點(diǎn)是:無需編譯,發(fā)布快速,PHP功能強(qiáng)大,能做從頁面渲染到數(shù)據(jù)訪問所有的事情,而且用到的技術(shù)都是開源的,免費(fèi)。
當(dāng)時(shí)我們是從一個(gè)美國人那里買來的一個(gè)網(wǎng)站系統(tǒng),這個(gè)系統(tǒng)的名字叫做 PHPAuction(他們的官方網(wǎng)站?http://www.phpauction.net,這個(gè)名字很直白,一眼就看出來這個(gè)系統(tǒng)是用什么語言做的、是干什么用的),PHPAuction有好幾個(gè)版本,我們買的是最高版的,功能比較多,而且最重要的是對(duì)方提供了源代碼。最高版比較貴,花了我們 2000 美金(貌似現(xiàn)在降價(jià)了,只要 946 美元)。買來之后不是直接就能用的,需要很多本地化的修改,例如頁面模板改的漂亮一點(diǎn),頁頭頁腳加上自己的站點(diǎn)簡介等,其中最有技術(shù)含量的是對(duì)數(shù)據(jù)庫進(jìn)行了一個(gè)修改。原來是從一個(gè)數(shù)據(jù)庫進(jìn)行所有的讀寫操作,拿過來之后多隆把它給拆分成一個(gè)主庫、兩個(gè)從庫,讀寫分離。這么做的好處有幾點(diǎn):存儲(chǔ)容量增加了,有了備份,使得安全性增加了,讀寫分離使得讀寫效率提升了。這樣整個(gè)系統(tǒng)的架構(gòu)就如下圖所示:
其中 Pear DB 是一個(gè) PHP 模塊,負(fù)責(zé)數(shù)據(jù)訪問層。另外也用開源的論壇系統(tǒng) PHPBB(http://www.phpbbchina.com?)搭建了一個(gè)小的論壇社區(qū),虛竹負(fù)責(zé)機(jī)器采購、配置、架設(shè)等,三豐和多隆負(fù)責(zé)編碼,他們把交易系統(tǒng)和論壇系統(tǒng)的用戶信息打通,給運(yùn)營人員開發(fā)出后臺(tái)管理(admin系統(tǒng))的功能,把交易類型從只有拍賣這一種增加為拍賣、一口價(jià)、求購商品、海報(bào)商品(意思是還沒推出的商品,先掛個(gè)海報(bào)出來)這四種。(PHPAuction 只有拍賣的交易,Auction 即拍賣的意思。@_行癲在微博中提到:今天 eBay 所有交易中拍賣交易仍然占了 40%,而在中國,此種模式在淘寶幾乎從一開始就未能占據(jù)優(yōu)勢,如今在主流的交易中幾乎可以忽略不計(jì)。背后的原因一直令人費(fèi)解。我大致可以給出其中一種解釋,eBay 基本在發(fā)達(dá)國家展開業(yè)務(wù),制造業(yè)外包后,電子商務(wù)的基本群體大多只能表現(xiàn)為零散的個(gè)體間交易。)
在經(jīng)歷了另外一些有趣的事情之后(這些有趣的事情包括“淘寶”這個(gè)名字的由來,員工花名的由來等等,由于本書主要描述技術(shù)方面的故事,對(duì)這些有興趣的可以去網(wǎng)上找),網(wǎng)站開始上線運(yùn)行了。
在接下來的大半年時(shí)間里,這個(gè)網(wǎng)站迅速顯示出了它的生機(jī)。這里有必要提一下當(dāng)時(shí)的市場環(huán)境,非典(SARS)的肆虐使得大家都不敢出門,尤其是去商場之類人多的地方。另外在神州大地上最早出現(xiàn)的 C2C 網(wǎng)站易趣也正忙的不亦樂乎,2002 年 3 月,eBay 以 3000 萬美元收購了易趣公司 33% 的股份,2003 年 6 月以 1.5 億美元收購了易趣公司剩余 67% 的股份。當(dāng)時(shí)淘寶網(wǎng)允許買賣雙方留下聯(lián)系方式,允許同城交易,整個(gè)操作過程簡單輕松。而 eBay 為了收取交易傭金,是禁止這么做的,這必然增加了交易過程的難度。而且 eBay 為了全球統(tǒng)一,把易趣原來的系統(tǒng)替換成了美國 eBay 的系統(tǒng),用戶體驗(yàn)一下子全變了,操作起來非常麻煩,這等于是把積累的用戶拱手送給了淘寶。為了不引起 eBay 的注意,淘寶網(wǎng)在 2003 年里一直聲稱自己是一個(gè)“個(gè)人網(wǎng)站”。由于這個(gè)創(chuàng)業(yè)團(tuán)隊(duì)強(qiáng)大的市場開拓和運(yùn)營能力,淘寶網(wǎng)發(fā)展的非常迅猛,2003 年底就吸引了注冊(cè)用戶XXX,最高每日 31 萬PV,從 5 月到年底成交額 4000 萬。這沒有引起 eBay 的注意,卻引起了阿里巴巴內(nèi)部很多員工的注意,他們覺得這個(gè)網(wǎng)站以后會(huì)成為阿里巴巴強(qiáng)勁的對(duì)手。甚至有人在內(nèi)網(wǎng)發(fā)帖,忠告管理層要警惕這個(gè)剛剛起步的網(wǎng)站,但管理層似乎無動(dòng)于衷。(這個(gè)團(tuán)隊(duì)的保密工作做的真好)
在市場和運(yùn)營的后方,淘寶網(wǎng)的技術(shù)團(tuán)隊(duì)也在快速的做著系統(tǒng)的改進(jìn)和創(chuàng)新。這里還有個(gè)有趣的故事,eBay 和易趣早期都有員工在論壇上響應(yīng)用戶的需求,eBay 的論壇用粉紅色背景來區(qū)分員工的發(fā)言,易趣的員工在論壇上昵稱都選各種豆豆,例如黃豆豆、蠶豆豆等。淘寶在討論運(yùn)營策略的時(shí)候提到這個(gè)問題,要求所有的員工都去論壇上回答用戶的問題。最早回答問題的任務(wù)落在小寶頭上,那我們用什么名字好呢?“淘淘”?“寶寶”?小寶都不滿意,太女性化了。討論了很久之后,小寶靈光乍現(xiàn),干脆取個(gè)名字叫“小寶”吧,小寶帶七個(gè)老婆來開店,迎接各位客官,很有故事性。于是很多武俠小說中的人物開始在論壇中行俠仗義,這些昵稱下面標(biāo)志著“淘寶店小二”,他們回答著各種各樣的問題,快速響應(yīng)著用戶的各種需求。如果是技術(shù)上能解決的,幾個(gè)人商量一下,馬上就開發(fā)、測試、發(fā)布上線。反過來對(duì)比一下,易趣被 eBay 收購之后,系統(tǒng)更換成了全球通用的版本,響應(yīng)用戶的一個(gè)需求需要層層審批,反應(yīng)速度自然慢了下來。
當(dāng)時(shí)淘寶第一個(gè)版本的系統(tǒng)里面已經(jīng)包含了商品發(fā)布、管理、搜索、商品詳情、出價(jià)購買、評(píng)價(jià)投訴、我的淘寶這些功能(現(xiàn)在主流程中也是這些模塊。在 2003 年 10 月增加了一個(gè)功能節(jié)點(diǎn):“安全交易”,這個(gè)是支付寶的雛形)。隨著用戶需求和流量的不斷增長,系統(tǒng)上面做了很多的日常改進(jìn),服務(wù)器由最初的一臺(tái)變成了三臺(tái),一臺(tái)負(fù)責(zé)發(fā)送 email、一臺(tái)負(fù)責(zé)運(yùn)行數(shù)據(jù)庫、一臺(tái)負(fù)責(zé)運(yùn)行 Web App。過一段時(shí)間之后,商品搜索的功能占用數(shù)據(jù)庫資源太大了(用like搜索的,很慢),又從阿里巴巴中文站搬過來他們的搜索引擎 iSearch,起初 iSearch 索引的文件放在硬盤上,隨著數(shù)據(jù)量的增長,又采購了 NetApp 服務(wù)器放置 iSearch。
如此快節(jié)奏的工作,其實(shí)大家都累得不行,有人就提議大家隨時(shí)隨地的鍛煉身體,可是外面 SARS 橫行,在一個(gè)一百多方的房子里,怎么鍛煉呢?高挑美女阿珂提議大家練習(xí)提臀操,這個(gè)建議遭到男士的一致反對(duì),后來虛竹就教大家練習(xí)倒立,這個(gè)大家都能接受。于是這個(gè)倒立的傳統(tǒng)一直延續(xù)至今,和花名文化、武俠文化一并傳承了下來。
隨著訪問量和數(shù)據(jù)量的飛速上漲,問題很快就出來了,第一個(gè)問題出現(xiàn)在數(shù)據(jù)庫上。MySQL 當(dāng)時(shí)是第 4 版的,我們用的是默認(rèn)的存儲(chǔ)引擎 MyISAM,這種類型讀數(shù)據(jù)的時(shí)候會(huì)把表鎖?。ㄎ覀冎?Oracle 在寫數(shù)據(jù)的時(shí)候會(huì)有行鎖,讀數(shù)據(jù)的時(shí)候是沒有的),尤其是主庫往從庫上面寫數(shù)據(jù)的時(shí)候,會(huì)對(duì)主庫產(chǎn)生大量的讀操作,使得主庫性能急劇下降。這樣在高訪問量的時(shí)候,數(shù)據(jù)庫撐不住了。另外,當(dāng)年的 MySQL 不比如今的 MySQL,在數(shù)據(jù)的容量和安全性方面也有很多先天的不足(和 Oracle 相比)。
淘寶網(wǎng)作為個(gè)人網(wǎng)站發(fā)展的時(shí)間其實(shí)并不長,由于它太引人注目了,馬云在 2003 年 7 月就宣布了這個(gè)是阿里巴巴旗下的網(wǎng)站,隨后在市場上展開了很成功的運(yùn)作。最著名的就是利用中小網(wǎng)站來做廣告,突圍 eBay 在門戶網(wǎng)站上對(duì)淘寶的廣告封鎖。上網(wǎng)比較早的人應(yīng)該還記得那些在右下角的彈窗和網(wǎng)站腰封上一閃一閃的廣告。市場部那位到處花錢買廣告的家伙,太能花錢了,一出手就是幾百萬,他被我們稱為“大少爺”。
“大少爺”們做的廣告,帶來的就是迅速上漲的流量和交易量。在 2003 年底,MySQL 已經(jīng)撐不住了,技術(shù)的替代方案非常簡單,就是換成 Oracle。換 Oracle 的原因除了它容量大、穩(wěn)定、安全、性能高之外,還有人才方面的原因。在 2003 年的時(shí)候,阿里巴巴已經(jīng)有一支很強(qiáng)大的 DBA 團(tuán)隊(duì)了,有馮春培、汪海(七公)這樣的人物,后來還有馮大輝(@fenng)、陳吉平(拖雷)。這樣的人物牛到什么程度呢?Oracle 給全球的技術(shù)專家頒發(fā)一些頭銜,其中最高級(jí)別的叫 ACE(就是撲克牌的“尖兒”,夠大的吧),被授予這個(gè)頭銜的人目前全球也只有 300 多名(名單在這里:?http://apex.oracle.com/pls/otn/f?p=19297:3?),當(dāng)年全球只有十幾名。有如此強(qiáng)大的技術(shù)后盾,把 MySQL 換成 Oracle 是順理成章的事情。
但更換數(shù)據(jù)庫不是只換個(gè)庫就可以的,訪問方式,SQL 語法都要跟著變,最重要的一點(diǎn)是,Oracle 并發(fā)訪問能力之所以如此強(qiáng)大,有一個(gè)關(guān)鍵性的設(shè)計(jì) —— 連接池。但對(duì)于 PHP 語言來說它是放在 Apache 上的,每一個(gè)請(qǐng)求都會(huì)對(duì)數(shù)據(jù)庫產(chǎn)生一個(gè)連接,它沒有連接池這種功能(Java 語言有 Servlet 容器,可以存放連接池)。那如何是好呢?這幫人打探到 eBay 在 PHP 下面用了一個(gè)連接池的工具,是 BEA 賣給他們的。我們知道 BEA 的東西都很貴,我們買不起,于是多隆在網(wǎng)上尋尋覓覓,找到一個(gè)開源的連接池代理服務(wù) SQLRelay(?http://sourceforge.jp/projects/freshmeat_sqlrelay?),這個(gè)東西能夠提供連接池的功能,多隆對(duì)它進(jìn)行了一些功能改進(jìn)之后就拿來用了。這樣系統(tǒng)的架構(gòu)就變成了如下的樣子:
數(shù)據(jù)一開始是放在本地的,DBA 們對(duì) Oracle 做調(diào)優(yōu)的工作,也對(duì) SQL 進(jìn)行調(diào)優(yōu)。后來數(shù)據(jù)量變大了,本地存儲(chǔ)不行了。買了 NAS(Network Attached Storage:網(wǎng)絡(luò)附屬存儲(chǔ)),NetApp 的 NAS 存儲(chǔ)作為了數(shù)據(jù)庫的存儲(chǔ)設(shè)備,加上 Oracle RAC(Real Application Clusters,實(shí)時(shí)應(yīng)用集群)來實(shí)現(xiàn)負(fù)載均衡。七公說這實(shí)際上是走了一段彎路,NAS 的 NFS(Network File System)協(xié)議傳輸?shù)难舆t很嚴(yán)重,但那時(shí)侯不懂。后來采購了 Dell 和 EMC 合作的 SAN 低端存儲(chǔ),性能一下子提升了 10 幾倍,這才比較穩(wěn)定了。再往后來數(shù)據(jù)量更大了,存儲(chǔ)的節(jié)點(diǎn)一拆二、二拆四,RAC 又出問題了。這才踏上了購買小型機(jī)的道路。在那段不穩(wěn)定的時(shí)間里,七公曾經(jīng)在機(jī)房住了 5 天 5 夜。
替換完數(shù)據(jù)庫,時(shí)間到了 2004 年春天,俗話說“春宵一刻值千金”,但這些人的春宵卻不太好過了。他們?cè)诎褦?shù)據(jù)的連接放在 SQLRelay 之后就噩夢(mèng)不斷,這個(gè)代理服務(wù)經(jīng)常會(huì)死鎖,如同之前的 MySQL 死鎖一樣。雖然多隆做了很多修改,但當(dāng)時(shí)那個(gè)版本內(nèi)部處理的邏輯不對(duì),問題很多,唯一解決的辦法就是“重啟”它的服務(wù)。這在白天還好,連接上機(jī)房的服務(wù)器,把進(jìn)程殺掉,然后開啟就可以了,但是最痛苦的是它在晚上也要死掉,于是工程師們不得不 24 小時(shí)開著手機(jī),一旦收到“ SQLRelay 進(jìn)程掛起”的短信,就從春夢(mèng)中醒來,打開電腦,連上機(jī)房,重啟服務(wù)。后來干脆每天睡覺之前先重啟一下。做這事最多的據(jù)說是三豐,他現(xiàn)在是淘寶網(wǎng)的總裁。現(xiàn)在我們知道,任何牛B的人物,都有一段苦B的經(jīng)歷。
微博上有人說“好的架構(gòu)是進(jìn)化來的,不是設(shè)計(jì)來的”。的確如此,其實(shí)還可以再加上一句“好的功能也是進(jìn)化來的,不是設(shè)計(jì)來的”。在架構(gòu)的進(jìn)化過程中,業(yè)務(wù)的進(jìn)化也非常迅猛。最早的時(shí)候,買家打錢給賣家都是通過銀行轉(zhuǎn)賬匯款,有些騙子收了錢卻不發(fā)貨,這是一個(gè)很嚴(yán)重的問題。然后這伙人研究了 PayPal 的支付方式,發(fā)現(xiàn)也不能解決問題。后來這幾個(gè)聰明的腦袋又想到了“擔(dān)保交易”這種第三方托管資金的辦法。于是在 2003 年 10 月,淘寶網(wǎng)上面上線了一個(gè)功能,叫做“安全交易”,賣家選擇支持這種功能的話,買家會(huì)把錢交給淘寶網(wǎng),等他收到貨之后,淘寶網(wǎng)再把錢給賣家。這就是現(xiàn)在的支付寶,在前兩天(2012.2.21)年會(huì)上,支付寶公布 2011 年的交易筆數(shù)已經(jīng)是 PayPal 的兩倍。這個(gè)劃時(shí)代的創(chuàng)新,其實(shí)就是在不斷的思索過程中的一個(gè)靈光乍現(xiàn)。
當(dāng)時(shí)開發(fā)“安全交易”功能的是茅十八和他的徒弟苗人鳳(茅十八開發(fā)到一半去上海讀 MBA 去了,苗人鳳現(xiàn)在是支付寶的首席業(yè)務(wù)架構(gòu)師),開發(fā)跟銀行網(wǎng)關(guān)對(duì)接的功能的是多隆。當(dāng)時(shí)多數(shù)銀行的網(wǎng)站已經(jīng)支持在線支付了,但多隆告訴我,他們的網(wǎng)關(guān)五花八門,用什么技術(shù)的都有,必須一家一家去接。而且他們不保證用戶付錢了就一定扣款成功、不保證扣款成功了就一定通知淘寶、不保證通知淘寶了就一定能通知到、不保證通知到了就不重復(fù)通知。這害苦了苗人鳳,他必須每天手工核對(duì)賬單,對(duì)不齊的話就一定是有人的錢找不到地方了,少一分錢都睡不著覺。另外他為了測試這些功能,去杭州所有的銀行都辦理了一張銀行卡。一堆銀行卡擺在桌子上,不知道的人還以為這個(gè)家伙一定很有錢,其實(shí)里面都只是十塊八塊的。現(xiàn)在我們?cè)僖淮沃?,任何牛B的人物,都必須有一段苦B的經(jīng)歷。
有人說淘寶打敗易趣(eBay 中國)是靠免費(fèi),其實(shí)這只是原因之一。如果說和易趣過招第一招是免費(fèi)的話,這讓用戶沒有門檻就愿意來,那第二招就是“安全支付”,這讓用戶放心付款,不必?fù)?dān)心被騙。在武俠小說中真正的高手飛花摘葉即可傷人,他們不會(huì)局限于一招兩招,一旦出手,連綿不絕。而淘寶的第三招就是“旺旺”,讓用戶在線溝通。其實(shí)淘寶旺旺也不是自己生出來的,是從阿里巴巴的“貿(mào)易通”復(fù)制過來的。從 2004 年 3 月開始,“叮咚、叮咚”這個(gè)經(jīng)典的聲音就回蕩在所有淘寶買家和賣家的耳邊,“親,包郵不?”,“親,把零頭去掉行不?”,這親切的砍價(jià)聲造就了后來的“淘寶體”。有人說中國人就是愛砍價(jià),雖然筆者體會(huì)不到砍價(jià)成功后有多少成就感,但每次我去菜市場,看到大媽們砍價(jià)砍得天昏地暗,那滿足的勁頭堪比撿到了錢,我就深刻的理解了淘寶旺旺在交易過程中的價(jià)值。我猜 eBay 也體會(huì)不到砍價(jià)的樂趣,他們一直不允許買賣雙方在線聊天,收購了 skype 之后也沒有用到電子商務(wù)中去。
旺旺在推出來沒多久,就惹了一個(gè)法律方面的麻煩。有個(gè)做雪餅的廠家找上門來,說我們侵權(quán)了,他們家的雪餅很好吃,牛奶也做得不錯(cuò),我們都很喜歡。然后我們就在旺旺的前面加了兩個(gè)字,叫做“淘寶旺旺”。在那個(gè)野蠻生長的階段,其實(shí)很多產(chǎn)品都是想到什么就做什么,例如我們還搭建過一個(gè)聊天室,但似乎淘寶網(wǎng)不是一個(gè)閑聊的地方,這個(gè)聊天室門可羅雀,一段時(shí)間后就關(guān)閉掉了。
SQLRelay 的問題搞得三豐他們很難睡個(gè)囫圇覺,那一年開半年會(huì)的時(shí)候,公司特地給三豐頒了一個(gè)獎(jiǎng)項(xiàng),對(duì)他表示深切的安慰。但不能總這樣啊,于是,2004 年的上半年開始,整個(gè)網(wǎng)站就開始了一個(gè)脫胎換骨的手術(shù)。
四、淘寶技術(shù)發(fā)展(Java時(shí)代:脫胎換骨)
我的師父黃裳@岳旭強(qiáng)曾經(jīng)說過,“好的架構(gòu)圖充滿美感”,一個(gè)架構(gòu)好不好,從審美的角度就能看得出來。后來我看了很多系統(tǒng)的架構(gòu),發(fā)現(xiàn)這個(gè)言論基本成立。那么反觀淘寶前面的兩個(gè)版本的架構(gòu),你看哪個(gè)比較美?
顯然第一個(gè)比較好看,后面那個(gè)顯得頭重腳輕,這也注定了它不是一個(gè)穩(wěn)定的版本,只存活了不到半年的時(shí)間。2004 年初,SQL Relay 的問題解決不了,數(shù)據(jù)庫必須要用 Oracle,那從哪里動(dòng)刀?只有換開發(fā)語言了。換什么語言好呢?Java。Java 是當(dāng)時(shí)最成熟的網(wǎng)站開發(fā)語言,它有比較良好的企業(yè)開發(fā)框架,被世界上主流的大規(guī)模網(wǎng)站普遍采用,另外有 Java 開發(fā)經(jīng)驗(yàn)的人才也比較多,后續(xù)維護(hù)成本會(huì)比較低。
到 2004 年上半年,淘寶網(wǎng)已經(jīng)運(yùn)行了一年的時(shí)間,這一年積累了大量的用戶,也快速的開發(fā)了很多功能,當(dāng)時(shí)這個(gè)網(wǎng)站已經(jīng)很龐大了,而且新的需求還在源源不斷的過來。把一個(gè)龐大的網(wǎng)站的開發(fā)語言換掉,無異于脫胎換骨,在換的過程中還不能拖慢業(yè)務(wù)的發(fā)展,這無異于邊換邊跑,對(duì)時(shí)間和技術(shù)能力的要求都非常高。做這樣的手術(shù),需要請(qǐng)第一流的專家來主刀?,F(xiàn)在再考一下讀者,如果你在這個(gè)創(chuàng)業(yè)團(tuán)隊(duì)里面,請(qǐng)什么樣的人來做這事?我們的答案是請(qǐng) Sun 的人。沒錯(cuò),就是創(chuàng)造 Java 語言的那家公司,世界上沒有比他們更懂 Java 的了。除此之外,還有一個(gè)不為人知的原因,……(此處和諧掉 200 字,完整版見 aliway)
這幫 Sun 的工程師的確很強(qiáng)大,在筆者 2004 年底來淘寶的時(shí)候,他們還在,有幸跟他們共事了幾個(gè)月。現(xiàn)在擺在他們面前的問題是用什么辦法把一個(gè)龐大的網(wǎng)站從 PHP 語言遷移到 Java?而且要求在遷移的過程中,不停止服務(wù),原來系統(tǒng)的 bugfix 和功能改進(jìn)不受影響。親,你要是架構(gòu)師,你怎么做?有人的答案是寫一個(gè)翻譯器,如同把中文翻譯成英文一樣,自動(dòng)翻譯。我只能說你這個(gè)想法太超前了,換個(gè)說法就是“too simple, sometimes naive”。當(dāng)時(shí)沒有,現(xiàn)在也沒有人能做到。他們的大致方案是給業(yè)務(wù)分模塊,一個(gè)模塊一個(gè)模塊的替換。如用戶模塊,老的 member.taobao.com 繼續(xù)維護(hù),不添加新功能,新的功能先在新的模塊上開發(fā),跟老的共用一個(gè)數(shù)據(jù)庫,開發(fā)完畢之后放到不同的應(yīng)用集群上,另開個(gè)域名 member1.taobao.com,同時(shí)替換老的功能,替換一個(gè),把老的模塊上的功能關(guān)閉一個(gè),逐漸的把用戶引導(dǎo)到 member1.taobao.com,等所有功能都替換完畢之后,關(guān)閉 member.taobao.com。后來很長時(shí)間里面都是在用 member1 這樣奇怪的域名,兩年后有另外一家互聯(lián)網(wǎng)公司開始做電子商務(wù)了,我們發(fā)現(xiàn)他們的域名也叫 member1.xx.com、auction1.xx.com……
說了開發(fā)模式,再說說用到的 Java MVC 框架,當(dāng)時(shí)的 Struts 1.x 是用的比較多的框架,但是用過 WebWork 和 Struts 2 的同學(xué)可能知道,Struts 1.x 在多人協(xié)作方面有很多致命的弱點(diǎn),由于沒有一個(gè)輕量框架作為基礎(chǔ),因此很難擴(kuò)展,這樣架構(gòu)師對(duì)于基礎(chǔ)功能和全局功能的控制就很難做到。而阿里巴巴的 18 個(gè)創(chuàng)始人之中,有個(gè)架構(gòu)師,在 Jakarta Turbine 的基礎(chǔ)上,做了很多擴(kuò)展,打造了一個(gè)阿里巴巴自己用的 MVC 框架 WebX (http://www.openwebx.org/docs/Webx3_Guide_Book.html),這個(gè)框架易于擴(kuò)展,方便組件化開發(fā),它的頁面模板支持 JSP 和 Velocity 等、持久層支持 iBATIS?和 Hibernate 等、控制層可以用 EJB 和 Spring(Spring 是后來才有的)。項(xiàng)目組選擇了這個(gè)強(qiáng)大的框架,這個(gè)框架如果當(dāng)時(shí)開源了,也許就沒有 WebWork 和 Struts 2 什么事了。另外,當(dāng)時(shí) Sun 在全世界大力推廣他們的 EJB,雖然淘寶的架構(gòu)師認(rèn)為這個(gè)東東用不到,但他們還是極力堅(jiān)持。在經(jīng)歷了很多次的技術(shù)討論、爭論和爭吵之后,這個(gè)系統(tǒng)的架構(gòu)就變成了下圖的樣子:
Java 應(yīng)用服務(wù)器是 Weblogic,MVC 框架是 WebX、控制層用了 EJB、持久層是 iBATIS,另外為了緩解數(shù)據(jù)庫的壓力,商品查詢和店鋪查詢放在搜索引擎上面。這個(gè)架構(gòu)圖是不是好看了一點(diǎn)了,親?
這幫 Sun 的工程師開發(fā)完淘寶的網(wǎng)站之后,又做了一個(gè)很牛的網(wǎng)站,叫“支付寶”。
其實(shí)在任何時(shí)候,開發(fā)語言本身都不是系統(tǒng)的瓶頸,業(yè)務(wù)帶來的壓力更多的是壓到了數(shù)據(jù)和存儲(chǔ)上。上面一篇也說到,MySQL 撐不住了之后換 Oracle,Oracle 的存儲(chǔ)一開始在本機(jī)上,后來在 NAS 上,NAS 撐不住了用 EMC 的 SAN 存儲(chǔ),再然后 Oracle 的 RAC 撐不住了,數(shù)據(jù)的存儲(chǔ)方面就不得不考慮使用小型機(jī)了。在 2004 年的夏天,DBA 七公、測試工程師郭芙和架構(gòu)師行癲,踏上了去北京測試小型機(jī)的道路。他們帶著小型機(jī)回來的時(shí)候,我們像歡迎領(lǐng)袖一樣的歡迎他們,因?yàn)槟莻€(gè)是我們最值錢的設(shè)備了,價(jià)格表上的數(shù)字嚇?biāo)廊?。小型機(jī)買回來之后我們爭相合影,然后 Oracle 就跑在了小型機(jī)上,存儲(chǔ)方面從 EMC 低端 cx 存儲(chǔ)到 Sun oem hds 高端存儲(chǔ),再到 EMC dmx 高端存儲(chǔ),一級(jí)一級(jí)的往上跳。
到現(xiàn)在為止,我們已經(jīng)用上了 IBM 的小型機(jī)、Oracle 的數(shù)據(jù)庫、EMC 的存儲(chǔ),這些東西都是很貴的,那些年可以說是花錢如流水啊。有人說過“錢能解決的問題,就不是問題”,但隨著淘寶網(wǎng)的發(fā)展,在不久以后,錢已經(jīng)解決不了我們的問題了?;ㄥX買豪華的配置,也許能支持 1 億 PV 的網(wǎng)站,但淘寶網(wǎng)的發(fā)展實(shí)在是太快了,到了 10 億怎么辦?到了百億怎么辦?在 N 年以后,我們不得不創(chuàng)造技術(shù),解決這些只有世界頂尖的網(wǎng)站才會(huì)遇到的問題。后來我們?cè)陂_源軟件的基礎(chǔ)上進(jìn)行自主研發(fā),一步一步的把 IOE(IBM 小型機(jī)、Oracle、EMC 存儲(chǔ))這幾個(gè)“神器”都去掉了。這就如同在《西游記》里面,妖怪們拿到神仙的兵器會(huì)非常厲害,連猴子都能夠打敗,但最牛的神仙是不用這些神器的,他們揮一揮衣袖、翻一下手掌就威力無比。去 IOE 這一部分會(huì)在最后一個(gè)章節(jié)里面講,這里先埋個(gè)千里伏筆。
欲知后事如何,且聽下回分解。
五、淘寶技術(shù)發(fā)展(Java時(shí)代:堅(jiān)若磐石)
已經(jīng)有讀者在迫不及待的問怎么去掉了 IOE,別急,在去掉 IOE 之前還有很長的路要走。行癲他們買回來小型機(jī)之后,我們用上了 Oracle,七公帶著一幫 DBA 在優(yōu)化 SQL 和存儲(chǔ),行癲帶著幾個(gè)架構(gòu)師在研究數(shù)據(jù)庫的擴(kuò)展性。Oracle 本身是一個(gè)封閉的系統(tǒng),用 Oracle 怎么做擴(kuò)展?用現(xiàn)在一個(gè)時(shí)髦的說法就是做“分庫分表”。
我們知道一臺(tái) Oracle 的處理能力是有上限的,它的連接池有數(shù)量限制,查詢速度跟容量成反比。簡單的說,在數(shù)據(jù)量上億、查詢量上億的時(shí)候,就到它的極限了。要突破這種極限,最簡單的方式就是多用幾個(gè) Oracle 數(shù)據(jù)庫。但一個(gè)封閉的系統(tǒng)做擴(kuò)展,不像分布式系統(tǒng)那樣輕松。我們把用戶的信息按照 ID 來放到兩個(gè)數(shù)據(jù)庫里面(DB1/DB2),把商品的信息跟著賣家放在兩個(gè)對(duì)應(yīng)的數(shù)據(jù)庫里面,把商品類目等通用信息放在第三個(gè)庫里面(DBcommon)。這么做的目的除了增加了數(shù)據(jù)庫的容量之外,還有一個(gè)就是做容災(zāi),萬一一個(gè)數(shù)據(jù)庫掛了,整個(gè)網(wǎng)站上還有一半的數(shù)據(jù)能操作。
數(shù)據(jù)庫這么分了之后,應(yīng)用程序有麻煩了,如果我是一個(gè)買家,買的商品有 DB1 的也有 DB2 的,要查看“我已買到的寶貝”的時(shí)候,應(yīng)用程序怎么辦?必須到兩個(gè)數(shù)據(jù)庫里面分別查詢出來對(duì)應(yīng)的商品。要按時(shí)間排序怎么辦?兩個(gè)庫里面“我已買到的寶貝”全部查出來在應(yīng)用程序里面做合并。還有分頁怎么處理?關(guān)鍵字查詢?cè)趺刺幚??這些東西交給程序員來做的話會(huì)很悲催,于是行癲在淘寶的第一個(gè)架構(gòu)上的作品就來解決了這個(gè)問題,他寫了一個(gè)數(shù)據(jù)庫路由的框架 DBRoute,這個(gè)框架在淘寶的 Oracle 時(shí)代一直在使用。后來隨著業(yè)務(wù)的發(fā)展,這種分庫的第二個(gè)目的 —— 容災(zāi)的效果就沒有達(dá)到。像評(píng)價(jià)、投訴、舉報(bào)、收藏、我的淘寶等很多地方,都必須同時(shí)連接 DB1 和 DB2,哪個(gè)庫掛了都會(huì)導(dǎo)致整個(gè)網(wǎng)站掛掉。
上一篇說過,采用 EJB 其實(shí)是和 Sun 的工程師妥協(xié)的結(jié)果,在他們走了之后,EJB 也逐漸被冷落了下來。在 2005、2006年的時(shí)候,Spring 大放異彩,正好利用 Spring 的反射(IoC)模式替代了 EJB 的工廠模式,給整個(gè)系統(tǒng)精簡了很多代碼。
上一篇還說過,為了減少數(shù)據(jù)庫的壓力,提高搜索的效率,我們引入了搜索引擎。隨著數(shù)據(jù)量的繼續(xù)增長,到了 2005 年,商品數(shù)有 1663 萬,PV 有 8931 萬,注冊(cè)會(huì)員有 1390 萬,這給數(shù)據(jù)和存儲(chǔ)帶來的壓力依然山大,數(shù)據(jù)量大,性能就慢。親,還有什么辦法能提升系統(tǒng)的性能?一定還有招數(shù)可以用,這就是緩存和 CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))。
你可以想象,九千萬的訪問量,有多少是在商品詳情頁面?訪問這個(gè)頁面的時(shí)候,數(shù)據(jù)全都是只讀的(全部從數(shù)據(jù)庫里面讀出來,不寫入數(shù)據(jù)庫),如果把這些讀操作從數(shù)據(jù)庫里面移到內(nèi)存里,數(shù)據(jù)庫將會(huì)多么的感激涕零。在那個(gè)時(shí)候我們的架構(gòu)師多隆大神,找到了一個(gè)基于 Berkeley DB 的開源的緩存系統(tǒng),把很多不太變動(dòng)的只讀信息放了進(jìn)去。其實(shí)最初這個(gè)緩存系統(tǒng)還比較弱,我們并沒有把整個(gè)商品詳情都放在里面,一開始把賣家的信息放里面,然后把商品屬性放里面,商品詳情這個(gè)字段太大,放進(jìn)去受不了。說到商品詳情,這個(gè)字段比較恐怖,有人統(tǒng)計(jì)過,淘寶商品詳情打印出來平均有 5 米長,在系統(tǒng)里面其實(shí)放在哪里都不招人待見。筆者清楚的記得,我來淘寶之后擔(dān)任項(xiàng)目經(jīng)理做的第一個(gè)項(xiàng)目就是把商品詳情從商品表里面給移出來。這個(gè)字段太大了,查詢商品信息的時(shí)候很多都不需要查看詳情,它跟商品的價(jià)格、運(yùn)費(fèi)這些放在一個(gè)表里面,拖慢了整個(gè)表的查詢速度。在 2005 年的時(shí)候,我把商品詳情放在數(shù)據(jù)庫的另外一張表里面,再往后這個(gè)大字段被從數(shù)據(jù)庫里面請(qǐng)了出來,這也讓數(shù)據(jù)庫再一次感激涕零。
到現(xiàn)在為止,整個(gè)商品詳情的頁面都在緩存里面了,眼尖的讀者可能會(huì)發(fā)現(xiàn)現(xiàn)在的商品詳情不全是“只讀”的信息了,這個(gè)頁面上有個(gè)信息叫“瀏覽量”,這個(gè)數(shù)字每刷新一次頁面就要“寫入”數(shù)據(jù)庫一次,這種高頻度實(shí)時(shí)更新的數(shù)據(jù)能用緩存嗎?如果不用緩存,一天幾十億的寫入,數(shù)據(jù)庫會(huì)怎么樣?一定會(huì)掛掉。那怎么辦?親……先不回答你(下圖不是廣告,讓你看看瀏覽量這個(gè)數(shù)據(jù)在哪里)
CDN 這個(gè)工作相對(duì)比較獨(dú)立,跟別的系統(tǒng)一樣,一開始我們也是采用的商用系統(tǒng)。后來隨著流量的增加,商用的系統(tǒng)已經(jīng)撐不住了,LVS 的創(chuàng)始人章文嵩博士帶人搭建了淘寶自己的 CDN 網(wǎng)絡(luò)。在本文的引言中我說過淘寶的 CDN 系統(tǒng)支撐了 800Gbps 以上的流量,作為對(duì)比我們可以看一下國內(nèi)專業(yè)做 CDN 的上市公司 ChinaCache 的介紹 —— “ChinaCache……是中國第一的專業(yè) CDN 服務(wù)提供商,向客戶提供全方位網(wǎng)絡(luò)內(nèi)容快速分布解決方案。作為首家獲信產(chǎn)部許可的 CDN 服務(wù)提供商,目前 ChinaCache 在全國 50 多個(gè)大中城市擁有近 300 個(gè)節(jié)點(diǎn),全網(wǎng)處理能力超過 500Gbps,其 CDN 網(wǎng)絡(luò)覆蓋中國電信、中國網(wǎng)通、中國移動(dòng)、中國聯(lián)通、中國鐵通和中國教育科研網(wǎng)等各大運(yùn)營商?!?—— 這樣你可以看得出淘寶在 CDN 上面的實(shí)力,這在全世界都是數(shù)一數(shù)二的。另外因?yàn)?CDN 需要大量的服務(wù)器,要消耗很多能源(消耗多少?在前兩年我們算過一筆帳,淘寶上產(chǎn)生一個(gè)交易,消耗的電足以煮熟 4 個(gè)雞蛋)。這兩年章文嵩的團(tuán)隊(duì)又在研究低功耗的服務(wù)器,在綠色計(jì)算領(lǐng)域也做了很多開創(chuàng)性的工作。淘寶 CDN 的發(fā)展需要專門一個(gè)章節(jié)來講,想先睹為快的可以看一下筆者對(duì)章文嵩的專訪。
回想起剛用緩存那段時(shí)間,筆者還是個(gè)小菜鳥,有一個(gè)經(jīng)典的錯(cuò)誤常常犯,就是數(shù)據(jù)庫的內(nèi)容更新的時(shí)候,忘記通知緩存系統(tǒng),結(jié)果在測試的時(shí)候就發(fā)現(xiàn)我改過的數(shù)據(jù)怎么在頁面上沒變化呢。后來做了一些頁面上的代碼,修改 CSS 和 JS 的時(shí)候,用戶本地緩存的信息沒有更新,頁面上也會(huì)亂掉,在論壇上被人說的時(shí)候,我告訴他用 Ctrl+F5 刷新頁面,然后趕緊修改腳本文件的名稱,重新發(fā)布頁面。學(xué)會(huì)用 Ctrl+F5 的會(huì)員對(duì)我佩服的五體投地,我卻慚愧的無地自容。
有些技術(shù)的發(fā)展是順其自然的,有些卻是突如其來的。到 2007 年的時(shí)候,我們已經(jīng)有幾百臺(tái)應(yīng)用服務(wù)器了,這上面的 Java 應(yīng)用服務(wù)器是 WebLogic,而 WebLogic 是非常貴的,比這些服務(wù)器本身都貴。有一段時(shí)間多隆研究了一下 JBoss,說我們換掉 WebLogic 吧,于是又省下了不少銀兩。那一年,老馬舉辦了第一屆的“網(wǎng)俠大會(huì)”,會(huì)上來的大俠中有一位是上文提到的章文嵩,還有一位曾經(jīng)在 JBoss 團(tuán)隊(duì)工作,我們也把這位大俠留下了,這樣我們用起 JBoss 更加有底氣了。
這些雜七雜八的修改,我們對(duì)數(shù)據(jù)分庫、放棄 EJB、引入 Spring、加入緩存、加入 CDN、采用開源的 JBoss,看起來沒有章法可循,其實(shí)都是圍繞著提高容量、提高性能、節(jié)約成本來做的,由于這些不算大的版本變遷,我們姑且叫它 2.1 版吧,這個(gè)版本從構(gòu)圖上來看有 3 只腳,是不是穩(wěn)定了很多?
架構(gòu)圖如下:
六、淘寶技術(shù)發(fā)展(Java時(shí)代:創(chuàng)造技術(shù)-TFS)
在講淘寶文件系統(tǒng) TFS 之前,先回顧一下上面幾個(gè)版本。1.0 版的 PHP 系統(tǒng)運(yùn)行了將近一年的時(shí)間(2003.05~2004.01);后來數(shù)據(jù)庫變成 Oracle 之后(2004.01~2004.05,叫 1.1 版本吧),不到半年就把開發(fā)語言轉(zhuǎn)換為 Java 系統(tǒng)了(2004.02~2005.03,叫2.0版本);進(jìn)行分庫、加入緩存、CDN之后我們叫它 2.1 版本(2004.10~2007.01)。這中間有些時(shí)間的重合,因?yàn)楹芏嗉軜?gòu)的演化并沒有明顯的時(shí)間點(diǎn),它是逐步進(jìn)化而來的。
在描述 2.1 版本的時(shí)候我寫的副標(biāo)題是“堅(jiān)若磐石”,這個(gè)“堅(jiān)若磐石”是因?yàn)檫@個(gè)版本終于穩(wěn)定下來了,在這個(gè)版本的系統(tǒng)上,淘寶網(wǎng)運(yùn)行了兩年多的時(shí)間。這期間有很多優(yōu)秀的人才加入,也開發(fā)了很多優(yōu)秀的產(chǎn)品,例如支付寶認(rèn)證系統(tǒng)、招財(cái)進(jìn)寶項(xiàng)目、淘寶旅行、淘寶彩票、淘寶論壇等等。甚至在團(tuán)購網(wǎng)站風(fēng)起云涌之前,淘寶網(wǎng)在 2006 年就推出了團(tuán)購的功能,只是淘寶網(wǎng)最初的團(tuán)購功能是買家發(fā)起的,達(dá)到賣家指定的數(shù)量之后,享受比一口價(jià)更低的價(jià)格,這個(gè)功能看起來是結(jié)合了淘寶一口價(jià)和荷蘭拍的另一種交易模式,但不幸沒有支撐下去。
在這些產(chǎn)品和功能的最底層,其實(shí)還是商品的管理和交易的管理這兩大功能。這兩大功能在 2.1 版本里面都有很大的變化。商品的管理起初是要求賣家選擇 7 天到期還是 14 天到期,到期之后就要下架,必須重新發(fā)布才能上架,上架之后就變成了新的商品信息(ID變過了)。另外如果這個(gè)期間內(nèi)成交了,之后再有新貨,必須發(fā)布一個(gè)新的商品信息。這么做有幾個(gè)原因,一是參照拍賣商品的時(shí)間設(shè)置,要在某日期前結(jié)束掛牌;二是搜索引擎不知道同樣的商品哪個(gè)排前面,那就把掛牌時(shí)間長的排前面,這樣就必須在某個(gè)時(shí)間把老的商品下架掉,不然它老排在前面;第三是成交信息和商品 ID 關(guān)聯(lián),這個(gè)商品如果多次編輯還是同一個(gè) ID 的話,成交記錄里面的商品信息會(huì)變來變?nèi)?;還有一個(gè)不為人知的原因,我們的存儲(chǔ)有限,不能讓所有的商品老存放在主庫里面。這種處理方式簡單粗暴,但還算是公平。不過這樣很多需求都無法滿足,例如同樣的商品,我上一次銷售的時(shí)候很多好評(píng)都沒法在下一個(gè)商品上體現(xiàn)出來;再例如我買過的商品結(jié)束后只看到交易的信息,不知道賣家還有沒有再賣了。后來基于這些需求,我們?cè)?2006 年下半年把商品和交易拆開。一個(gè)商家的一種商品有個(gè)唯一的 ID,上下架都是同一個(gè)商品。那么如果賣家改價(jià)格、庫存什么的話,已成交的信息怎么處理?那就在買家每交易一次的時(shí)候,都記錄下商品的快照信息,有多少次交易就有多少個(gè)快照。這樣買賣雙方比較爽了,給系統(tǒng)帶來了什么?存儲(chǔ)的成本大幅度上升了!
存儲(chǔ)的成本高到什么程度呢?數(shù)據(jù)庫方面提到過用了 IOE,一套下來就是千萬級(jí)別的,那幾套下來就是??。另外淘寶網(wǎng)還有很多文件需要存儲(chǔ),我們有哪些文件呢?最主要的就是圖片、商品描述、交易快照,一個(gè)商品要包含幾張圖片和一長串的描述信息,而每一張圖片都要生成幾張規(guī)格不同的縮略圖。在 2010 年,淘寶網(wǎng)的后端系統(tǒng)上保存著 286 億個(gè)圖片文件。圖片在交易系統(tǒng)中非常重要,俗話說“一張好圖勝千言”、“無圖無真相”,淘寶網(wǎng)的商品照片,尤其是熱門商品,圖片的訪問流量是非常大的。淘寶網(wǎng)整體流量中,圖片的訪問流量要占到 90% 以上。且這些圖片平均大小為 17.45 KB,小于 8K 的圖片占整體圖片數(shù)量 61%,占整體系統(tǒng)容量的 11%。這么多的圖片數(shù)據(jù)、這么大的訪問流量,給淘寶網(wǎng)的系統(tǒng)帶來了巨大的挑戰(zhàn)。眾所周知,對(duì)于大多數(shù)系統(tǒng)來說,最頭疼的就是大規(guī)模的小文件存儲(chǔ)與讀取,因?yàn)榇蓬^需要頻繁的尋道和換道,因此在讀取上容易帶來較長的延時(shí)。在大量高并發(fā)訪問量的情況下,簡直就是系統(tǒng)的噩夢(mèng)。我們?cè)撛趺崔k?
同樣的套路,在某個(gè)規(guī)模以下,采用現(xiàn)有的商業(yè)解決方案,達(dá)到某種規(guī)模之后,商業(yè)的解決方案無法滿足,只有自己創(chuàng)造解決方案了。對(duì)于淘寶的圖片存儲(chǔ)來說,轉(zhuǎn)折點(diǎn)在 2007 年。這之前,一直采用的商用存儲(chǔ)系統(tǒng),應(yīng)用 NetApp 公司的文件存儲(chǔ)系統(tǒng)。隨著淘寶網(wǎng)的圖片文件數(shù)量以每年 2 倍(即原來 3 倍)的速度增長,淘寶網(wǎng)后端 NetApp 公司的存儲(chǔ)系統(tǒng)也從低端到高端不斷遷移,直至 2006 年,即使是 NetApp 公司最高端的產(chǎn)品也不能滿足淘寶網(wǎng)存儲(chǔ)的要求。從 2006 年開始,淘寶網(wǎng)決定自己開發(fā)一套針對(duì)海量小文件存儲(chǔ)的文件系統(tǒng),用于解決自身圖片存儲(chǔ)的難題。這標(biāo)志著淘寶網(wǎng)從使用技術(shù)到了創(chuàng)造技術(shù)的階段。
2007年之前的圖片存儲(chǔ)架構(gòu)如下圖:
章文嵩博士總結(jié)了幾點(diǎn)商用存儲(chǔ)系統(tǒng)的局限和不足:
首先是商用的存儲(chǔ)系統(tǒng)沒有對(duì)小文件存儲(chǔ)和讀取的環(huán)境進(jìn)行有針對(duì)性的優(yōu)化;其次,文件數(shù)量大,網(wǎng)絡(luò)存儲(chǔ)設(shè)備無法支撐;另外,整個(gè)系統(tǒng)所連接的服務(wù)器也越來越多,網(wǎng)絡(luò)連接數(shù)已經(jīng)到達(dá)了網(wǎng)絡(luò)存儲(chǔ)設(shè)備的極限。此外,商用存儲(chǔ)系統(tǒng)擴(kuò)容成本高,10T的存儲(chǔ)容量需要幾百萬,而且存在單點(diǎn)故障,容災(zāi)和安全性無法得到很好的保證。
談到在商用系統(tǒng)和自主研發(fā)之間的經(jīng)濟(jì)效益對(duì)比,章文嵩博士列舉了以下幾點(diǎn)經(jīng)驗(yàn):
1. 商用軟件很難滿足大規(guī)模系統(tǒng)的應(yīng)用需求,無論存儲(chǔ)還是 CDN 還是負(fù)載均衡,因?yàn)樵趶S商實(shí)驗(yàn)室端,很難實(shí)現(xiàn)如此大的數(shù)據(jù)規(guī)模測試。
2. 研發(fā)過程中,將開源和自主開發(fā)相結(jié)合,會(huì)有更好的可控性,系統(tǒng)出問題了,完全可以從底層解決問題,系統(tǒng)擴(kuò)展性也更高。
3. 在一定規(guī)模效應(yīng)基礎(chǔ)上,研發(fā)的投入都是值得的。上圖是一個(gè)自主研發(fā)和購買商用系統(tǒng)的投入產(chǎn)出比對(duì)比,實(shí)際上,在上圖的交叉點(diǎn)左邊,購買商用系統(tǒng)都是更加實(shí)際和經(jīng)濟(jì)性更好的選擇,只有在規(guī)模超過交叉點(diǎn)的情況下,自主研發(fā)才能收到較好的經(jīng)濟(jì)效果。實(shí)際上,規(guī)?;_(dá)到如此程度的公司其實(shí)并不多,不過淘寶網(wǎng)已經(jīng)遠(yuǎn)遠(yuǎn)超過了交叉點(diǎn)。
4. 自主研發(fā)的系統(tǒng)可在軟件和硬件多個(gè)層次不斷的優(yōu)化。
歷史總是驚人的巧合,在我們準(zhǔn)備研發(fā)文件存儲(chǔ)系統(tǒng)的時(shí)候,Google 走在了前面,2007 年他們公布了 GFS( Google File System )的設(shè)計(jì)論文,這給我們帶來了很多借鑒的思路。隨后我們開發(fā)出了適合淘寶使用的圖片存儲(chǔ)系統(tǒng)TFS(Taobao File System)。3年之后,我們發(fā)現(xiàn)歷史的巧合比我們想象中還要神奇,幾乎跟我們同時(shí),中國的另外一家互聯(lián)網(wǎng)公司也開發(fā)了他們的文件存儲(chǔ)系統(tǒng),甚至取的名字都一樣 —— TFS,太神奇了?。ú虏率悄募遥浚?/p>
2007 年 6 月,TFS 正式上線運(yùn)營。在生產(chǎn)環(huán)境中應(yīng)用的集群規(guī)模達(dá)到了 200 臺(tái) PC Server(146G*6 SAS 15K Raid5),文件數(shù)量達(dá)到上億級(jí)別;系統(tǒng)部署存儲(chǔ)容量:140TB;實(shí)際使用存儲(chǔ)容量: 50TB;單臺(tái)支持隨機(jī)IOPS200+,流量 3MBps。
要講 TFS 的系統(tǒng)架構(gòu),首先要描述清楚業(yè)務(wù)需求,淘寶對(duì)圖片存儲(chǔ)的需求大概可以描述如下:
文件比較?。徊l(fā)量高;讀操作遠(yuǎn)大于寫操作;訪問隨機(jī);沒有文件修改的操作;要求存儲(chǔ)成本低;能容災(zāi)能備份。應(yīng)對(duì)這種需求,顯然要用分布式存儲(chǔ)系統(tǒng);由于文件大小比較統(tǒng)一,可以采用專有文件系統(tǒng);并發(fā)量高,讀寫隨機(jī)性強(qiáng),需要更少的 IO 操作;考慮到成本和備份,需要用廉價(jià)的存儲(chǔ)設(shè)備;考慮到容災(zāi),需要能平滑擴(kuò)容。
參照 GFS 并做了適度的優(yōu)化之后,TFS 1.0 版的架構(gòu)圖如下:
從上面架構(gòu)圖上看:集群由一對(duì) Name Server 和多臺(tái) Data Serve r構(gòu)成,Name Server 的兩臺(tái)服務(wù)器互為雙機(jī),就是集群文件系統(tǒng)中管理節(jié)點(diǎn)的概念。
在這個(gè)架構(gòu)中:
? 每個(gè) Data Server 運(yùn)行在一臺(tái)普通的 Linux 主機(jī)上
? 以 block 文件的形式存放數(shù)據(jù)文件(一般64M一個(gè)block )
? block 存多份保證數(shù)據(jù)安全
? 利用 ext3 文件系統(tǒng)存放數(shù)據(jù)文件
? 磁盤 raid5 做數(shù)據(jù)冗余
? 文件名內(nèi)置元數(shù)據(jù)信息,用戶自己保存 TFS 文件名與實(shí)際文件的對(duì)照關(guān)系 – 使得元數(shù)據(jù)量特別小。
淘寶 TFS 文件系統(tǒng)在核心設(shè)計(jì)上最大的取巧的地方就在,傳統(tǒng)的集群系統(tǒng)里面元數(shù)據(jù)只有 1 份,通常由管理節(jié)點(diǎn)來管理,因而很容易成為瓶頸。而對(duì)于淘寶網(wǎng)的用戶來說,圖片文件究竟用什么名字來保存實(shí)際上用戶并不關(guān)心,因此TFS 在設(shè)計(jì)規(guī)劃上考慮在圖片的保存文件名上暗藏了一些元數(shù)據(jù)信息,例如圖片的大小、時(shí)間、訪問頻次等等信息,包括所在的邏輯塊號(hào)。而在元數(shù)據(jù)上,實(shí)際上保存的信息很少,因此元數(shù)據(jù)結(jié)構(gòu)非常簡單。僅僅只需要一個(gè) fileID,能夠準(zhǔn)確定位文件在什么地方。
由于大量的文件信息都隱藏在文件名中,整個(gè)系統(tǒng)完全拋棄了傳統(tǒng)的目錄樹結(jié)構(gòu),因?yàn)槟夸洏溟_銷最大。拿掉后,整個(gè)集群的高可擴(kuò)展性極大提高。實(shí)際上,這一設(shè)計(jì)理念和目前業(yè)界的“對(duì)象存儲(chǔ)”較為類似,淘寶網(wǎng) TFS 文件系統(tǒng)已經(jīng)更新到 1.3 版本,在生產(chǎn)系統(tǒng)的性能已經(jīng)得到驗(yàn)證,且不斷得到了完善和優(yōu)化,淘寶網(wǎng)目前在對(duì)象存儲(chǔ)領(lǐng)域的研究已經(jīng)走在前列。
在 TFS 上線之前,淘寶網(wǎng)每個(gè)商品只允許上傳一張圖片,大小限定在 120K 之內(nèi),在商品詳情里面的圖片必須使用外站的服務(wù)。那時(shí)侯發(fā)布一件商品確實(shí)非常麻煩,筆者曾經(jīng)想賣一臺(tái)二手電腦,先把照片上傳到 Google 相冊(cè),在發(fā)布到淘寶網(wǎng)之后發(fā)現(xiàn) Google 相冊(cè)被墻了,我的圖片別人看不到,當(dāng)時(shí)郁悶的不行。TFS 上線后,商品展示圖片開放到 5 張,商品描述里面的圖片也可以使用淘寶的圖片服務(wù),到現(xiàn)在為止,淘寶網(wǎng)給每個(gè)用戶提供了 1G 的圖片空間,這下大家都滿足了。技術(shù)和業(yè)務(wù)就是這么互相用力的推動(dòng)著,業(yè)務(wù)滿足不了的時(shí)候,技術(shù)必須創(chuàng)新,技術(shù)創(chuàng)新之后,業(yè)務(wù)有了更大的發(fā)展空間。
1.3 版本的架構(gòu)見阿里味(阿里巴巴內(nèi)網(wǎng))??
七、淘寶技術(shù)發(fā)展(分布式時(shí)代:服務(wù)化)
在系統(tǒng)發(fā)展的過程中,架構(gòu)師的眼光至關(guān)重要,作為程序員,把功能實(shí)現(xiàn)即可,但作為架構(gòu)師,要考慮系統(tǒng)的擴(kuò)展性、重用性,這種敏銳的感覺,有人說是一種代碼潔癖。淘寶早期有幾個(gè)架構(gòu)師具備了這種感覺。一指開發(fā)的 Webx 是一個(gè)擴(kuò)展性很強(qiáng)的框架,行癲在這個(gè)框架上插入了數(shù)據(jù)分庫路由的模塊、session 框架等等。在做淘寶后臺(tái)系統(tǒng)的時(shí)候,同樣需要這幾個(gè)模塊,行癲指導(dǎo)我把這些模塊單獨(dú)打成了 jar 包。另外在做淘寶機(jī)票、彩票系統(tǒng)的時(shí)候,頁面端也有很多東西需要復(fù)用,最直觀的是頁頭和頁腳,一開始我們每個(gè)系統(tǒng)里面復(fù)制了一份過去,但奇妙的是,那段時(shí)間頁腳要經(jīng)常修改,例如把“雅虎中國”改成“中國雅虎”,過一段時(shí)間又加了一個(gè)“口碑網(wǎng)”,再過一段時(shí)間變成了“雅虎口碑”,最后又變成了“中國雅虎”,每個(gè)系統(tǒng)都改一遍,折騰啊。后來我就把這部分 velocity 模版單獨(dú)拿出來了,做成了公用的模塊。
上面這些都是比較小的復(fù)用模塊,到 2006 年我們做了一個(gè)商品類目屬性的改造,在類目里面引入屬性的概念。項(xiàng)目的代號(hào)叫做“泰山”,如同它的名字,這是一個(gè)舉足輕重的項(xiàng)目,這個(gè)改變是一個(gè)劃時(shí)代的創(chuàng)新。在這之前的三年時(shí)間內(nèi),商品的分類都是按照樹狀的一級(jí)一級(jí)的節(jié)點(diǎn)來分的,隨著商品數(shù)量的增長,類目也變得越來越深,越來越復(fù)雜,這帶給買家的就是查找一件商品要逐級(jí)類目點(diǎn)開,找商品之前要懂商品的分類。而淘寶運(yùn)營部門管理類目的小二也發(fā)現(xiàn)一個(gè)很嚴(yán)重的問題 —— 例如男裝里面有T恤、T恤下面有耐克、耐克有純棉的,女裝里面也有T恤、T恤下面還是有耐克、耐克下面依然有純棉的,那是先分男女裝再分款式再分品牌再分材質(zhì)呢?還是先分品牌再分款式再分材質(zhì)再分男女呢?暈倒了。這時(shí)候,一位大俠出來了 —— 一燈,他說品牌、款式、材質(zhì)這種東東可以叫做“屬性”,屬性是類似 tag 的一個(gè)概念,與類目相比更加離散,更加靈活,這樣也縮減了類目的深度。這個(gè)思想的提出,一舉解決了分類的難題!從系統(tǒng)的角度來看,我們建立了“屬性”這樣一個(gè)數(shù)據(jù)結(jié)構(gòu),由于除了類目的子節(jié)點(diǎn)有屬性,父節(jié)點(diǎn)也有可能有屬性,于是類目屬性合起來也是一個(gè)結(jié)構(gòu)化的數(shù)據(jù)對(duì)象。這個(gè)做出來之后我們把它獨(dú)立出來作為一個(gè)服務(wù),叫做 catserver(category server)。跟類目屬性密切關(guān)聯(lián)的商品搜索功能,獨(dú)立出來,叫做 hesper(金星),catserver 和 hesper 供淘寶的前后臺(tái)系統(tǒng)調(diào)用。
現(xiàn)在淘寶的商品類目屬性已經(jīng)是地球上最大的了,幾乎沒有什么類目的商品在淘寶上找不到(除了違禁的),但最初類目屬性改造完之后,我們很缺屬性數(shù)據(jù),尤其是數(shù)碼類的最缺。那從哪里弄這些數(shù)據(jù)呢親?我們跟“中關(guān)村在線”合作,拿到了很多數(shù)據(jù),那個(gè)時(shí)候,很多商品屬性信息的后邊標(biāo)注著:“來自中關(guān)村在線”。有了類目屬性,給運(yùn)營的工作帶來很大的便利,我們知道淘寶的運(yùn)營主要就是類目的運(yùn)營,什么季節(jié)推什么商品,都要在類目屬性上面做調(diào)整,讓買家更容易找到。例如夏天我要用戶在女裝一級(jí)類目下就標(biāo)出來材質(zhì)是不是蕾絲的、是不是純棉的,冬天卻要把羽絨衣調(diào)到女裝一級(jí)類目下,流行什么就要把什么商品往更高級(jí)的類目調(diào)整。這樣類目和屬性要經(jīng)常調(diào)整,隨之而來的問題就顯現(xiàn)了 —— 調(diào)整到哪個(gè)類目,那類商品的賣家就要編輯一次自己的商品,隨著商品量的增長,賣家的工作量越來越大,然后我們就發(fā)現(xiàn)賣家受不了啦。到了 2008 年,我們研究了超市里面前后臺(tái)商品的分類,發(fā)現(xiàn)超市前臺(tái)商品可以隨季節(jié)和關(guān)聯(lián)來調(diào)整擺放場景(例如著名的啤酒和尿布的關(guān)聯(lián)),后臺(tái)倉庫里面要按照自然類目來存儲(chǔ),二者密切關(guān)聯(lián)卻又相互分開。然后我們就把前后臺(tái)類目分開了,這樣賣家發(fā)布商品選擇的是自然類目和屬性,淘寶前臺(tái)展示的是根據(jù)運(yùn)營需要而擺放的商品的類目和屬性。改造后的類目屬性服務(wù)取名叫做 forest(森林,跟類目屬性有點(diǎn)神似。catserver 還在,提供賣家授權(quán)、品牌服務(wù)、關(guān)鍵詞等相關(guān)的服務(wù))。類目屬性的服務(wù)化,是淘寶在系統(tǒng)服務(wù)化方面做的第一個(gè)探索。
雖然個(gè)別架構(gòu)師具備了代碼潔癖,但淘寶前臺(tái)系統(tǒng)的業(yè)務(wù)量和代碼量還是爆炸式的增長了起來。業(yè)務(wù)方總在后面催,開發(fā)人員不夠了就繼續(xù)招人,招來的人根本看不懂原來的業(yè)務(wù),只好摸索著在“合適的地方”加一些“合適的代碼”,看看運(yùn)行起來像那么回事,就發(fā)布上線了。在這樣的惡性循環(huán)中,系統(tǒng)越來越臃腫,業(yè)務(wù)的耦合性越來越高,開發(fā)的效率越來越低。借用當(dāng)時(shí)比較流行的一句話“寫一段代碼,編譯一下能通過,半個(gè)小時(shí)就過去了;編譯一下沒通過,半天就過去了?!痹谶@種情況下,系統(tǒng)出錯(cuò)的概率也逐步增長,常常是你改了商品相關(guān)的某些代碼,發(fā)現(xiàn)交易出問題了,甚至你改了論壇上的某些代碼,旺旺出問題了。這讓開發(fā)人員苦不堪言,而業(yè)務(wù)方還認(rèn)為這幫人干活越來越慢了。
大概是在 2007 年底的時(shí)候,研發(fā)部空降了一位從硅谷來的高管,空聞大師??章勈且晃粶睾竦拈L者,他告訴我們一切要以穩(wěn)定為中心,所有影響系統(tǒng)穩(wěn)定的因素都要解決掉。例如每做一個(gè)日常修改,都必須整個(gè)系統(tǒng)回歸測試一遍;多個(gè)日常修改如果放在一個(gè)版本里面,要是一個(gè)功能沒有測試通過,整個(gè)系統(tǒng)都不能發(fā)布。我們把這個(gè)叫做“火車模型”,任何一個(gè)乘客沒有上車,都不許發(fā)車。這樣做的最直接后果就是火車一直晚點(diǎn),新功能上線更慢了,我們能明顯的感覺到業(yè)務(wù)方的不滿,空聞的壓力肯定非常大。當(dāng)時(shí)我都不理解這種一刀切的做法,為了穩(wěn)定犧牲了發(fā)展的速度,這跟某 Party 的“穩(wěn)定壓倒一切”有什么分別?
但是到現(xiàn)在回過頭來看看,其實(shí)我們并沒有理解背后的思路。正是在這種要求下,我們不得不開始改變一些東西,例如把回歸測試日常化,每天晚上都跑一遍整個(gè)系統(tǒng)的回歸。還有就是在這種要求下,我們不得不對(duì)這個(gè)超級(jí)復(fù)雜的系統(tǒng)做肢解和重構(gòu),其中復(fù)用性最高的一個(gè)模塊 —— 用戶信息模塊開始拆分出來了,我們叫它 UIC(user information center)。在 UIC 里面,它只處理最基礎(chǔ)的用戶信息操作,例如getUserById、getUserByName等等。
在另外一個(gè)方面,還有兩個(gè)新興的業(yè)務(wù),也對(duì)系統(tǒng)基礎(chǔ)功能的拆分提出了要求。在那個(gè)時(shí)候,我們做了淘寶旅行(trip.taobao.com)和淘寶彩票(caipiao.taobao.com)兩個(gè)新業(yè)務(wù),這兩個(gè)新業(yè)務(wù)在商品的展示和交易的流程上都跟主站的業(yè)務(wù)不一樣,機(jī)票是按照航班的信息展示的,彩票是按照雙色球、數(shù)字和足球的賽程來展示的。但用到的會(huì)員的功能和交易的功能是跟主站差不多的,當(dāng)時(shí)做的時(shí)候就很糾結(jié),在主站里面做的話,會(huì)有一大半跟主站無關(guān)的東西,重新做一個(gè)的話,會(huì)有很多重復(fù)建設(shè)。最終我們決定不再給主站添亂了,就另起爐灶做了兩個(gè)新的業(yè)務(wù)系統(tǒng)。從查詢商品、購買商品、評(píng)價(jià)反饋、查看訂單這一整個(gè)流程都重新寫了一套出來?,F(xiàn)在在“我的淘寶”里面查看交易記錄的時(shí)候,還能發(fā)現(xiàn)“已買到的寶貝”里面把機(jī)票和彩票另外列出來了,他們沒有加入到普通的訂單里面去。在當(dāng)時(shí)如果已經(jīng)把會(huì)員、交易、商品、評(píng)價(jià)這些模塊拆分出來,就不用什么都重做一遍了。
到 2008 年初,整個(gè)主站系統(tǒng)(有了機(jī)票、彩票系統(tǒng)之后,把原來的系統(tǒng)叫做主站)的容量已經(jīng)到了瓶頸,商品數(shù)在一億以上,PV 在 2.5 億以上,會(huì)員數(shù)超過了五千萬。這個(gè)時(shí)候 Oracle 的連接池?cái)?shù)量都不夠用了,數(shù)據(jù)庫的容量到了極限,上層系統(tǒng)再增加機(jī)器也無法繼續(xù)擴(kuò)容了,我們只有把底層的基礎(chǔ)服務(wù)繼續(xù)拆分,從底層開始擴(kuò)容,上層才能擴(kuò)展,這才能容納以后三五年的增長。
于是那一年我們專門啟動(dòng)了一個(gè)更大的項(xiàng)目,把交易這個(gè)核心業(yè)務(wù)模塊也拆分出來了。原來的淘寶交易除了跟商品管理耦合在一起,也在支付寶和淘寶之間跳來跳去,跟支付寶耦合在一起,系統(tǒng)復(fù)雜,用戶體驗(yàn)也很不好。我們把交易的底層業(yè)務(wù)拆出來叫交易中心TC(trade center),所謂底層業(yè)務(wù)是例如創(chuàng)建訂單、減庫存、修改訂單狀態(tài)等原子型的操作;交易的上層業(yè)務(wù)叫交易管理TM(trade manager),例如拍下一件普通商品要對(duì)訂單、庫存、物流進(jìn)行操作,拍下虛擬商品不需要對(duì)物流進(jìn)行操作,這些在TM里面完成。這個(gè)項(xiàng)目取了一個(gè)很沒有創(chuàng)意的名字 —— “千島湖”,這幫開發(fā)人員取這個(gè)名字的目的是想在開發(fā)完畢之后,去千島湖玩一圈,后來他們?nèi)缭敢詢斄?。這個(gè)時(shí)候還有一個(gè)項(xiàng)目也在搞,就是淘寶商城,之前拆分出來的那些基礎(chǔ)服務(wù),給商城的快速構(gòu)建,提供了良好的基礎(chǔ)。
類目屬性、用戶中心、交易中心,隨著這些模塊逐步的拆分和服務(wù)化改造,我們?cè)谙到y(tǒng)架構(gòu)方面也積累了不少的經(jīng)驗(yàn)。到 2008 年底干脆做了一個(gè)更大的項(xiàng)目,把淘寶所有的業(yè)務(wù)都模塊化,這是繼 2004 年從 LAMP 架構(gòu)到 Java 架構(gòu)之后的第二次脫胎換骨。這個(gè)項(xiàng)目取了一個(gè)很霸氣的名字,叫“五彩石”(女媧煉石補(bǔ)天,用的石頭)。這個(gè)系統(tǒng)重構(gòu)的工作非常驚險(xiǎn),有人稱之為“給一架高速飛行的飛機(jī)換發(fā)動(dòng)機(jī)”。
五彩石項(xiàng)目發(fā)布之后,這幫工程師去三亞玩了幾天。他們把淘寶的系統(tǒng)拆分成了如下架構(gòu):
其中 UIC 和 Forest 上文說過,TC、IC、SC分別是交易中心(Trade Center)、商品中心(Item Center)、店鋪中心(Shop Center),這些中心級(jí)別的服務(wù)只提供原子級(jí)的業(yè)務(wù)邏輯,如根據(jù)ID查找商品、創(chuàng)建交易、減少庫存等操作。再往上一層是業(yè)務(wù)系統(tǒng)TM(Trade Manager交易業(yè)務(wù))、IM(Item Manager商品業(yè)務(wù))、SM(Shop Manager,因?yàn)椴缓寐?,所以后來改名?SS:Shop System,店鋪業(yè)務(wù))、Detail(商品詳情)。
拆分之后,系統(tǒng)之間的交互關(guān)系變得非常復(fù)雜,示意圖如下:
系統(tǒng)這么拆分的話,好處顯而易見,拆分之后每個(gè)系統(tǒng)可以單獨(dú)部署,業(yè)務(wù)簡單,方便擴(kuò)容;有大量可重用的模塊以便于開發(fā)新的業(yè)務(wù);能夠做到專人專事,讓技術(shù)人員更加專注于某一個(gè)領(lǐng)域。這樣要解決的問題也很明顯,分拆之后,系統(tǒng)之間還是必須要打交道的,越往底層的系統(tǒng),調(diào)用它的客戶方越多,這就要求底層的系統(tǒng)必須具有超大規(guī)模的容量和非常高的可用性。另外,拆分之后的系統(tǒng)如何通訊?這里需要兩種中間件系統(tǒng),一種是實(shí)時(shí)調(diào)用的中間件(淘寶的HSF,高性能服務(wù)框架)、一種是異步消息通知的中間件(淘寶的Notify)。另外還有一個(gè)需要解決的問題是用戶在A系統(tǒng)登錄了,到B系統(tǒng)的時(shí)候,用戶的登錄信息怎么保存?這又涉及到一個(gè) Session 框架。再者,還有一個(gè)軟件工程方面的問題,這么多層的一套系統(tǒng),怎么去測試它?
學(xué)習(xí)很多,剛好公司準(zhǔn)備進(jìn)行服務(wù)化的架構(gòu)重建….受益匪淺呀