淘寶,京東,蘇寧易購技術架構(路線)分析和比較

caixingyun發表於2016-05-28

最近因為參與專案的關係,對淘寶,京東,蘇寧易購三家網站系統構架做了膚淺的研究,做了幾張圖,放在下面,給需要的同學。


因為資料的不完整,有些可能不準確或是錯誤的,肯請各位指正。


這三家代表了三種流派,淘寶走的是開源路線,個人也比較推崇這種方式,但對技術人員的要求較高,比較少有公司勇於走這種路線,可能只有馬雲這種對技術不懂的,才能放手讓技術人員自由發展。


京東的劉強東自己懂開發,從一開始就構架在.Net上面,現在已經是尾大不掉,隨著發展已經開展痛苦的轉型中。


蘇寧易購因為內部ERP,CRM已有大量的應用,所以選用了底層、業務層比較成熟的商用套件IBM WCS,在業務構架方面還是有可取之處,但苦於技術、開發層面熟悉電商的高水平顧問缺乏,蘇寧目前通過招聘Java開發人員,準備加強自身的開發能力。


下面是幾張不涉及到專案機密可以拿出來討論的圖,歡迎大家討論指正,郵件可發至我的郵箱:fengqiang # gmail.com









關於淘寶的,詳細可以參考如下

一、個人網站 

  2003 年 4 月 7 日,馬雲,在杭州,成立了一個神祕的組織。他叫來十位員工,要他們簽了一份協議,這份協議要求他們立刻離開阿里巴巴,去做一個神祕的專案。這個專案要求絕對保密,老馬戲稱“連說夢話被老婆聽到都不行,誰要是透漏出去,我將追殺到天涯海角”。這份協議是英文版的,匆忙之間,大多數人根本來不及看懂,但出於對老馬的信任,都捲起鋪蓋離開了阿里巴巴。

  他們去了一個神祕的據點 —— 湖畔花園小區的一套未裝修的房子裡,房子的主人是馬雲。這夥人剛進去的時候,馬雲給他們佈置了一個任務,就是在最短的時間內做出一個個人對個人(C2C)的商品交易的網站。現在出一個問題考考讀者,看你適不適合做淘寶的創業團隊。親,要是讓你來做,你怎麼做?

  在說出這個答案之前,容我先賣個關子,介紹一下這個創業團隊的成員:三個開發工程師(虛竹、三豐、多隆)、一個UED(二當家)、三個運營(小寶、阿珂、破天)、一個經理(財神)、還有就是馬雲和他的祕書。當時對整個專案組來說壓力最大的就是時間,怎麼在最短的時間內把一個從來就沒有的網站從零開始建立起來?瞭解淘寶曆史的人知道淘寶是在 2003 年 5 月 10 日上線的,這之間只有一個月。要是你在這個團隊裡,你怎麼做?我們的答案就是:買一個來。

  買一個網站顯然比做一個網站要省事一些,但是他們的夢想可不是做一個小網站而已,要做大,就不是隨便買個就行的,要有比較低的維護成本,要能夠方便的擴充套件和二次開發。那接下來就是第二個問題:買一個什麼樣的網站?答案是:輕量一點的,簡單一點的,於是買了這樣一個架構的網站:LAMP(Linux+Apache+MySQL+PHP)。這個直到現在還是一個很常用的網站架構模型。這種架構的優點是:無需編譯,釋出快速,PHP功能強大,能做從頁面渲染到資料訪問所有的事情,而且用到的技術都是開源的,免費。

  當時我們是從一個美國人那裡買來的一個網站系統,這個系統的名字叫做 PHPAuction(他們的官方網站 http://www.phpauction.net,這個名字很直白,一眼就看出來這個系統是用什麼語言做的、是幹什麼用的),PHPAuction有好幾個版本,我們買的是最高版的,功能比較多,而且最重要的是對方提供了原始碼。最高版比較貴,花了我們 2000 美金(貌似現在降價了,只要 946 美元)。買來之後不是直接就能用的,需要很多本地化的修改,例如頁面模板改的漂亮一點,頁頭頁尾加上自己的站點簡介等,其中最有技術含量的是對資料庫進行了一個修改。原來是從一個資料庫進行所有的讀寫操作,拿過來之後多隆把它給拆分成一個主庫、兩個從庫,讀寫分離。這麼做的好處有幾點:儲存容量增加了,有了備份,使得安全性增加了,讀寫分離使得讀寫效率提升了。這樣整個系統的架構就如下圖所示:

 

  其中 Pear DB 是一個 PHP 模組,負責資料訪問層。另外也用開源的論壇系統 PHPBB(http://www.phpbbchina.com )搭建了一個小的論壇社群,虛竹負責機器採購、配置、架設等,三豐和多隆負責編碼,他們把交易系統和論壇系統的使用者資訊打通,給運營人員開發出後臺管理(admin系統)的功能,把交易型別從只有拍賣這一種增加為拍賣、一口價、求購商品、海報商品(意思是還沒推出的商品,先掛個海報出來)這四種。(PHPAuction 只有拍賣的交易,Auction 即拍賣的意思。@_行癲在微博中提到:今天 eBay 所有交易中拍賣交易仍然佔了 40%,而在中國,此種模式在淘寶幾乎從一開始就未能佔據優勢,如今在主流的交易中幾乎可以忽略不計。背後的原因一直令人費解。我大致可以給出其中一種解釋,eBay 基本在已開發國家展開業務,製造業外包後,電子商務的基本群體大多隻能表現為零散的個體間交易。)

  在經歷了另外一些有趣的事情之後(這些有趣的事情包括“淘寶”這個名字的由來,員工花名的由來等等,由於本書主要描述技術方面的故事,對這些有興趣的可以去網上找),網站開始上線執行了。

 

  在接下來的大半年時間裡,這個網站迅速顯示出了它的生機。這裡有必要提一下當時的市場環境,非典(SARS)的肆虐使得大家都不敢出門,尤其是去商場之類人多的地方。另外在神州大地上最早出現的 C2C 網站易趣也正忙的不亦樂乎,2002 年 3 月,eBay 以 3000 萬美元收購了易趣公司 33% 的股份,2003 年 6 月以 1.5 億美元收購了易趣公司剩餘 67% 的股份。當時淘寶網允許買賣雙方留下聯絡方式,允許同城交易,整個操作過程簡單輕鬆。而 eBay 為了收取交易佣金,是禁止這麼做的,這必然增加了交易過程的難度。而且 eBay 為了全球統一,把易趣原來的系統替換成了美國 eBay 的系統,使用者體驗一下子全變了,操作起來非常麻煩,這等於是把積累的使用者拱手送給了淘寶。為了不引起 eBay 的注意,淘寶網在 2003 年裡一直聲稱自己是一個“個人網站”。由於這個創業團隊強大的市場開拓和運營能力,淘寶網發展的非常迅猛,2003 年底就吸引了註冊使用者XXX,最高每日 31 萬PV,從 5 月到年底成交額 4000 萬。這沒有引起 eBay 的注意,卻引起了阿里巴巴內部很多員工的注意,他們覺得這個網站以後會成為阿里巴巴強勁的對手。甚至有人在內網發帖,忠告管理層要警惕這個剛剛起步的網站,但管理層似乎無動於衷。(這個團隊的保密工作做的真好)

  在市場和運營的後方,淘寶網的技術團隊也在快速的做著系統的改進和創新。這裡還有個有趣的故事,eBay 和易趣早期都有員工在論壇上響應使用者的需求,eBay 的論壇用粉紅色背景來區分員工的發言,易趣的員工在論壇上暱稱都選各種豆豆,例如黃豆豆、蠶豆豆等。淘寶在討論運營策略的時候提到這個問題,要求所有的員工都去論壇上回答使用者的問題。最早回答問題的任務落在小寶頭上,那我們用什麼名字好呢?“淘淘”?“寶寶”?小寶都不滿意,太女性化了。討論了很久之後,小寶靈光乍現,乾脆取個名字叫“小寶”吧,小寶帶七個老婆來開店,迎接各位客官,很有故事性。於是很多武俠小說中的人物開始在論壇中行俠仗義,這些暱稱下面標誌著“淘寶店小二”,他們回答著各種各樣的問題,快速響應著使用者的各種需求。如果是技術上能解決的,幾個人商量一下,馬上就開發、測試、釋出上線。反過來對比一下,易趣被 eBay 收購之後,系統更換成了全球通用的版本,響應使用者的一個需求需要層層審批,反應速度自然慢了下來。

  當時淘寶第一個版本的系統裡面已經包含了商品釋出、管理、搜尋、商品詳情、出價購買、評價投訴、我的淘寶這些功能(現在主流程中也是這些模組。在 2003 年 10 月增加了一個功能節點:“安全交易”,這個是支付寶的雛形)。隨著使用者需求和流量的不斷增長,系統上面做了很多的日常改進,伺服器由最初的一臺變成了三臺,一臺負責傳送 email、一臺負責執行資料庫、一臺負責執行 Web App。過一段時間之後,商品搜尋的功能佔用資料庫資源太大了(用like搜尋的,很慢),又從阿里巴巴中文站搬過來他們的搜尋引擎 iSearch,起初 iSearch 索引的檔案放在硬碟上,隨著資料量的增長,又採購了 NetApp 伺服器放置 iSearch。

  如此快節奏的工作,其實大家都累得不行,有人就提議大家隨時隨地的鍛鍊身體,可是外面 SARS 橫行,在一個一百多方的房子裡,怎麼鍛鍊呢?高挑美女阿珂提議大家練習提臀操,這個建議遭到男士的一致反對,後來虛竹就教大家練習倒立,這個大家都能接受。於是這個倒立的傳統一直延續至今,和花名文化、武俠文化一併傳承了下來。

  隨著訪問量和資料量的飛速上漲,問題很快就出來了,第一個問題出現在資料庫上。MySQL 當時是第 4 版的,我們用的是預設的儲存引擎 MyISAM,這種型別讀資料的時候會把表鎖住(我們知道 Oracle 在寫資料的時候會有行鎖,讀資料的時候是沒有的),尤其是主庫往從庫上面寫資料的時候,會對主庫產生大量的讀操作,使得主庫效能急劇下降。這樣在高訪問量的時候,資料庫撐不住了。另外,當年的 MySQL 不比如今的 MySQL,在資料的容量和安全性方面也有很多先天的不足(和 Oracle 相比)。

  二、Oracle/支付寶/旺旺

  淘寶網作為個人網站發展的時間其實並不長,由於它太引人注目了,馬雲在 2003 年 7 月就宣佈了這個是阿里巴巴旗下的網站,隨後在市場上展開了很成功的運作。最著名的就是利用中小網站來做廣告,突圍 eBay 在入口網站上對淘寶的廣告封鎖。上網比較早的人應該還記得那些在右下角的彈窗和網站腰封上一閃一閃的廣告。市場部那位到處花錢買廣告的傢伙,太能花錢了,一出手就是幾百萬,他被我們稱為“大少爺”。

  “大少爺”們做的廣告,帶來的就是迅速上漲的流量和交易量。在 2003 年底,MySQL 已經撐不住了,技術的替代方案非常簡單,就是換成 Oracle。換 Oracle 的原因除了它容量大、穩定、安全、效能高之外,還有人才方面的原因。在 2003 年的時候,阿里巴巴已經有一支很強大的 DBA 團隊了,有馮春培、汪海(七公)這樣的人物,後來還有馮大輝(@fenng)、陳吉平(拖雷)。這樣的人物牛到什麼程度呢?Oracle 給全球的技術專家頒發一些頭銜,其中最高階別的叫 ACE(就是撲克牌的“尖兒”,夠大的吧),被授予這個頭銜的人目前全球也只有 300 多名(名單在這裡: http://apex.oracle.com/pls/otn/f?p=19297:3 ),當年全球只有十幾名。有如此強大的技術後盾,把 MySQL 換成 Oracle 是順理成章的事情。

  但更換資料庫不是隻換個庫就可以的,訪問方式,SQL 語法都要跟著變,最重要的一點是,Oracle 併發訪問能力之所以如此強大,有一個關鍵性的設計 —— 連線池。但對於 PHP 語言來說它是放在 Apache 上的,每一個請求都會對資料庫產生一個連線,它沒有連線池這種功能(Java 語言有 Servlet 容器,可以存放連線池)。那如何是好呢?這幫人打探到 eBay 在 PHP 下面用了一個連線池的工具,是 BEA 賣給他們的。我們知道 BEA 的東西都很貴,我們買不起,於是多隆在網上尋尋覓覓,找到一個開源的連線池代理服務 SQLRelay( http://sourceforge.jp/projects/freshmeat_sqlrelay ),這個東西能夠提供連線池的功能,多隆對它進行了一些功能改進之後就拿來用了。這樣系統的架構就變成了如下的樣子:

  資料一開始是放在本地的,DBA 們對 Oracle 做調優的工作,也對 SQL 進行調優。後來資料量變大了,本地儲存不行了。買了 NAS(Network Attached Storage:網路附屬儲存),NetApp 的 NAS 儲存作為了資料庫的儲存裝置,加上 Oracle RAC(Real Application Clusters,實時應用叢集)來實現負載均衡。七公說這實際上是走了一段彎路,NAS 的 NFS(Network File System)協議傳輸的延遲很嚴重,但那時侯不懂。後來採購了 Dell 和 EMC 合作的 SAN 低端儲存,效能一下子提升了 10 幾倍,這才比較穩定了。再往後來資料量更大了,儲存的節點一拆二、二拆四,RAC 又出問題了。這才踏上了購買小型機的道路。在那段不穩定的時間裡,七公曾經在機房住了 5 天 5 夜。

  替換完資料庫,時間到了 2004 年春天,俗話說“春宵一刻值千金”,但這些人的春宵卻不太好過了。他們在把資料的連線放在 SQLRelay 之後就噩夢不斷,這個代理服務經常會死鎖,如同之前的 MySQL 死鎖一樣。雖然多隆做了很多修改,但當時那個版本內部處理的邏輯不對,問題很多,唯一解決的辦法就是“重啟”它的服務。這在白天還好,連線上機房的伺服器,把程式殺掉,然後開啟就可以了,但是最痛苦的是它在晚上也要死掉,於是工程師們不得不 24 小時開著手機,一旦收到“ SQLRelay 程式掛起”的簡訊,就從春夢中醒來,開啟電腦,連上機房,重啟服務。後來乾脆每天睡覺之前先重啟一下。做這事最多的據說是三豐,他現在是淘寶網的總裁。現在我們知道,任何牛B的人物,都有一段苦B的經歷。

  微博上有人說“好的架構是進化來的,不是設計來的”。的確如此,其實還可以再加上一句“好的功能也是進化來的,不是設計來的”。在架構的進化過程中,業務的進化也非常迅猛。最早的時候,買家打錢給賣家都是通過銀行轉賬匯款,有些騙子收了錢卻不發貨,這是一個很嚴重的問題。然後這夥人研究了 PayPal 的支付方式,發現也不能解決問題。後來這幾個聰明的腦袋又想到了“擔保交易”這種第三方託管資金的辦法。於是在 2003 年 10 月,淘寶網上面上線了一個功能,叫做“安全交易”,賣家選擇支援這種功能的話,買家會把錢交給淘寶網,等他收到貨之後,淘寶網再把錢給賣家。這就是現在的支付寶,在前兩天(2012.2.21)年會上,支付寶公佈 2011 年的交易筆數已經是 PayPal 的兩倍。這個劃時代的創新,其實就是在不斷的思索過程中的一個靈光乍現。

  當時開發“安全交易”功能的是茅十八和他的徒弟苗人鳳(茅十八開發到一半去上海讀 MBA 去了,苗人鳳現在是支付寶的首席業務架構師),開發跟銀行閘道器對接的功能的是多隆。當時多數銀行的網站已經支援線上支付了,但多隆告訴我,他們的閘道器五花八門,用什麼技術的都有,必須一家一家去接。而且他們不保證使用者付錢了就一定扣款成功、不保證扣款成功了就一定通知淘寶、不保證通知淘寶了就一定能通知到、不保證通知到了就不重複通知。這害苦了苗人鳳,他必須每天手工核對賬單,對不齊的話就一定是有人的錢找不到地方了,少一分錢都睡不著覺。另外他為了測試這些功能,去杭州所有的銀行都辦理了一張銀行卡。一堆銀行卡擺在桌子上,不知道的人還以為這個傢伙一定很有錢,其實裡面都只是十塊八塊的。現在我們再一次知道,任何牛B的人物,都必須有一段苦B的經歷。

  有人說淘寶打敗易趣(eBay 中國)是靠免費,其實這只是原因之一。如果說和易趣過招第一招是免費的話,這讓使用者沒有門檻就願意來,那第二招就是“安全支付”,這讓使用者放心付款,不必擔心被騙。在武俠小說中真正的高手飛花摘葉即可傷人,他們不會侷限於一招兩招,一旦出手,連綿不絕。而淘寶的第三招就是“旺旺”,讓使用者線上溝通。其實淘寶旺旺也不是自己生出來的,是從阿里巴巴的“貿易通”複製過來的。從 2004 年 3 月開始,“叮咚、叮咚”這個經典的聲音就回蕩在所有淘寶買家和賣家的耳邊,“親,包郵不?”,“親,把零頭去掉行不?”,這親切的砍價聲造就了後來的“淘寶體”。有人說中國人就是愛砍價,雖然筆者體會不到砍價成功後有多少成就感,但每次我去菜市場,看到大媽們砍價砍得天昏地暗,那滿足的勁頭堪比撿到了錢,我就深刻的理解了淘寶旺旺在交易過程中的價值。我猜 eBay 也體會不到砍價的樂趣,他們一直不允許買賣雙方線上聊天,收購了 skype 之後也沒有用到電子商務中去。

  旺旺在推出來沒多久,就惹了一個法律方面的麻煩。有個做雪餅的廠家找上門來,說我們侵權了,他們家的雪餅很好吃,牛奶也做得不錯,我們都很喜歡。然後我們就在旺旺的前面加了兩個字,叫做“淘寶旺旺”。在那個野蠻生長的階段,其實很多產品都是想到什麼就做什麼,例如我們還搭建過一個聊天室,但似乎淘寶網不是一個閒聊的地方,這個聊天室門可羅雀,一段時間後就關閉掉了。

  SQLRelay 的問題搞得三豐他們很難睡個囫圇覺,那一年開半年會的時候,公司特地給三豐頒了一個獎項,對他表示深切的安慰。但不能總這樣啊,於是,2004 年的上半年開始,整個網站就開始了一個脫胎換骨的手術。

  三、淘寶技術發展(Java時代:脫胎換骨)

  我的師父黃裳@嶽旭強曾經說過,“好的架構圖充滿美感”,一個架構好不好,從審美的角度就能看得出來。後來我看了很多系統的架構,發現這個言論基本成立。那麼反觀淘寶前面的兩個版本的架構,你看哪個比較美?

  顯然第一個比較好看,後面那個顯得頭重腳輕,這也註定了它不是一個穩定的版本,只存活了不到半年的時間。2004 年初,SQL Relay 的問題解決不了,資料庫必須要用 Oracle,那從哪裡動刀?只有換開發語言了。換什麼語言好呢?Java。Java 是當時最成熟的網站開發語言,它有比較良好的企業開發框架,被世界上主流的大規模網站普遍採用,另外有 Java 開發經驗的人才也比較多,後續維護成本會比較低。  

  到 2004 年上半年,淘寶網已經執行了一年的時間,這一年積累了大量的使用者,也快速的開發了很多功能,當時這個網站已經很龐大了,而且新的需求還在源源不斷的過來。把一個龐大的網站的開發語言換掉,無異於脫胎換骨,在換的過程中還不能拖慢業務的發展,這無異於邊換邊跑,對時間和技術能力的要求都非常高。做這樣的手術,需要請第一流的專家來主刀。現在再考一下讀者,如果你在這個創業團隊裡面,請什麼樣的人來做這事?我們的答案是請 Sun 的人。沒錯,就是創造 Java 語言的那家公司,世界上沒有比他們更懂 Java 的了。除此之外,還有一個不為人知的原因,……(此處和諧掉 200 字,完整版見 aliway)

  這幫 Sun 的工程師的確很強大,在筆者 2004 年底來淘寶的時候,他們還在,有幸跟他們共事了幾個月。現在擺在他們面前的問題是用什麼辦法把一個龐大的網站從 PHP 語言遷移到 Java?而且要求在遷移的過程中,不停止服務,原來系統的 bugfix 和功能改進不受影響。親,你要是架構師,你怎麼做?有人的答案是寫一個翻譯器,如同把中文翻譯成英文一樣,自動翻譯。我只能說你這個想法太超前了,換個說法就是“too simple, sometimes naive”。當時沒有,現在也沒有人能做到。他們的大致方案是給業務分模組,一個模組一個模組的替換。如使用者模組,老的 member.taobao.com 繼續維護,不新增新功能,新的功能先在新的模組上開發,跟老的共用一個資料庫,開發完畢之後放到不同的應用叢集上,另開個域名 member1.taobao.com,同時替換老的功能,替換一個,把老的模組上的功能關閉一個,逐漸的把使用者引導到 member1.taobao.com,等所有功能都替換完畢之後,關閉 member.taobao.com。後來很長時間裡面都是在用 member1 這樣奇怪的域名,兩年後有另外一家網際網路公司開始做電子商務了,我們發現他們的域名也叫 member1.xx.com、auction1.xx.com……  

  說了開發模式,再說說用到的 Java MVC 框架,當時的 Struts 1.x 是用的比較多的框架,但是用過 WebWork 和 Struts 2 的同學可能知道,Struts 1.x 在多人協作方面有很多致命的弱點,由於沒有一個輕量框架作為基礎,因此很難擴充套件,這樣架構師對於基礎功能和全域性功能的控制就很難做到。而阿里巴巴的 18 個創始人之中,有個架構師,在 Jakarta Turbine 的基礎上,做了很多擴充套件,打造了一個阿里巴巴自己用的 MVC 框架 WebX (http://www.openwebx.org/docs/Webx3_Guide_Book.html),這個框架易於擴充套件,方便元件化開發,它的頁面模板支援 JSP 和 Velocity 等、持久層支援 iBATIS 和 Hibernate 等、控制層可以用 EJB 和 Spring(Spring 是後來才有的)。專案組選擇了這個強大的框架,這個框架如果當時開源了,也許就沒有 WebWork 和 Struts 2 什麼事了。另外,當時 Sun 在全世界大力推廣他們的 EJB,雖然淘寶的架構師認為這個東東用不到,但他們還是極力堅持。在經歷了很多次的技術討論、爭論和爭吵之後,這個系統的架構就變成了下圖的樣子:

 

  Java 應用伺服器是 Weblogic,MVC 框架是 WebX、控制層用了 EJB、持久層是 iBATIS,另外為了緩解資料庫的壓力,商品查詢和店鋪查詢放在搜尋引擎上面。這個架構圖是不是好看了一點了,親?  

  這幫 Sun 的工程師開發完淘寶的網站之後,又做了一個很牛的網站,叫“支付寶”。  

  其實在任何時候,開發語言本身都不是系統的瓶頸,業務帶來的壓力更多的是壓到了資料和儲存上。上面一篇也說到,MySQL 撐不住了之後換 Oracle,Oracle 的儲存一開始在本機上,後來在 NAS 上,NAS 撐不住了用 EMC 的 SAN 儲存,再然後 Oracle 的 RAC 撐不住了,資料的儲存方面就不得不考慮使用小型機了。在 2004 年的夏天,DBA 七公、測試工程師郭芙和架構師行癲,踏上了去北京測試小型機的道路。他們帶著小型機回來的時候,我們像歡迎領袖一樣的歡迎他們,因為那個是我們最值錢的裝置了,價格表上的數字嚇死人。小型機買回來之後我們爭相合影,然後 Oracle 就跑在了小型機上,儲存方面從 EMC 低端 cx 儲存到 Sun oem hds 高階儲存,再到 EMC dmx 高階儲存,一級一級的往上跳。  

  到現在為止,我們已經用上了 IBM 的小型機、Oracle 的資料庫、EMC 的儲存,這些東西都是很貴的,那些年可以說是花錢如流水啊。有人說過“錢能解決的問題,就不是問題”,但隨著淘寶網的發展,在不久以後,錢已經解決不了我們的問題了。花錢買豪華的配置,也許能支援 1 億 PV 的網站,但淘寶網的發展實在是太快了,到了 10 億怎麼辦?到了百億怎麼辦?在 N 年以後,我們不得不創造技術,解決這些只有世界頂尖的網站才會遇到的問題。後來我們在開源軟體的基礎上進行自主研發,一步一步的把 IOE(IBM 小型機、Oracle、EMC 儲存)這幾個“神器”都去掉了。這就如同在《西遊記》裡面,妖怪們拿到神仙的兵器會非常厲害,連猴子都能夠打敗,但最牛的神仙是不用這些神器的,他們揮一揮衣袖、翻一下手掌就威力無比。去 IOE 這一部分會在最後一個章節裡面講,這裡先埋個千里伏筆。  

  欲知後事如何,且聽下回分解。

  四、淘寶技術發展(Java時代:堅若磐石)

  已經有讀者在迫不及待的問怎麼去掉了 IOE,別急,在去掉 IOE 之前還有很長的路要走。行癲他們買回來小型機之後,我們用上了 Oracle,七公帶著一幫 DBA 在優化 SQL 和儲存,行癲帶著幾個架構師在研究資料庫的擴充套件性。Oracle 本身是一個封閉的系統,用 Oracle 怎麼做擴充套件?用現在一個時髦的說法就是做“分庫分表”。

  我們知道一臺 Oracle 的處理能力是有上限的,它的連線池有數量限制,查詢速度跟容量成反比。簡單的說,在資料量上億、查詢量上億的時候,就到它的極限了。要突破這種極限,最簡單的方式就是多用幾個 Oracle 資料庫。但一個封閉的系統做擴充套件,不像分散式系統那樣輕鬆。我們把使用者的資訊按照 ID 來放到兩個資料庫裡面(DB1/DB2),把商品的資訊跟著賣家放在兩個對應的資料庫裡面,把商品類目等通用資訊放在第三個庫裡面(DBcommon)。這麼做的目的除了增加了資料庫的容量之外,還有一個就是做容災,萬一一個資料庫掛了,整個網站上還有一半的資料能操作。  

  資料庫這麼分了之後,應用程式有麻煩了,如果我是一個買家,買的商品有 DB1 的也有 DB2 的,要檢視“我已買到的寶貝”的時候,應用程式怎麼辦?必須到兩個資料庫裡面分別查詢出來對應的商品。要按時間排序怎麼辦?兩個庫裡面“我已買到的寶貝”全部查出來在應用程式裡面做合併。還有分頁怎麼處理?關鍵字查詢怎麼處理?這些東西交給程式設計師來做的話會很悲催,於是行癲在淘寶的第一個架構上的作品就來解決了這個問題,他寫了一個資料庫路由的框架 DBRoute,這個框架在淘寶的 Oracle 時代一直在使用。後來隨著業務的發展,這種分庫的第二個目的 —— 容災的效果就沒有達到。像評價、投訴、舉報、收藏、我的淘寶等很多地方,都必須同時連線 DB1 和 DB2,哪個庫掛了都會導致整個網站掛掉。  

  上一篇說過,採用 EJB 其實是和 Sun 的工程師妥協的結果,在他們走了之後,EJB 也逐漸被冷落了下來。在 2005、2006年的時候,Spring 大放異彩,正好利用 Spring 的反射(IoC)模式替代了 EJB 的工廠模式,給整個系統精簡了很多程式碼。  

  上一篇還說過,為了減少資料庫的壓力,提高搜尋的效率,我們引入了搜尋引擎。隨著資料量的繼續增長,到了 2005 年,商品數有 1663 萬,PV 有 8931 萬,註冊會員有 1390 萬,這給資料和儲存帶來的壓力依然山大,資料量大,效能就慢。親,還有什麼辦法能提升系統的效能?一定還有招數可以用,這就是快取和 CDN(內容分發網路)。  

  你可以想象,九千萬的訪問量,有多少是在商品詳情頁面?訪問這個頁面的時候,資料全都是隻讀的(全部從資料庫裡面讀出來,不寫入資料庫),如果把這些讀操作從資料庫裡面移到記憶體裡,資料庫將會多麼的感激涕零。在那個時候我們的架構師多隆大神,找到了一個基於 Berkeley DB 的開源的快取系統,把很多不太變動的只讀資訊放了進去。其實最初這個快取系統還比較弱,我們並沒有把整個商品詳情都放在裡面,一開始把賣家的資訊放裡面,然後把商品屬性放裡面,商品詳情這個欄位太大,放進去受不了。說到商品詳情,這個欄位比較恐怖,有人統計過,淘寶商品詳情列印出來平均有 5 米長,在系統裡面其實放在哪裡都不招人待見。筆者清楚的記得,我來淘寶之後擔任專案經理做的第一個專案就是把商品詳情從商品表裡面給移出來。這個欄位太大了,查詢商品資訊的時候很多都不需要檢視詳情,它跟商品的價格、運費這些放在一個表裡面,拖慢了整個表的查詢速度。在 2005 年的時候,我把商品詳情放在資料庫的另外一張表裡面,再往後這個大欄位被從資料庫裡面請了出來,這也讓資料庫再一次感激涕零。  

  到現在為止,整個商品詳情的頁面都在快取裡面了,眼尖的讀者可能會發現現在的商品詳情不全是“只讀”的資訊了,這個頁面上有個資訊叫“瀏覽量”,這個數字每重新整理一次頁面就要“寫入”資料庫一次,這種高頻度實時更新的資料能用快取嗎?如果不用快取,一天幾十億的寫入,資料庫會怎麼樣?一定會掛掉。那怎麼辦?親……先不回答你(下圖不是廣告,讓你看看瀏覽量這個資料在哪裡)

  

  CDN 這個工作相對比較獨立,跟別的系統一樣,一開始我們也是採用的商用系統。後來隨著流量的增加,商用的系統已經撐不住了,LVS 的創始人章文嵩博士帶人搭建了淘寶自己的 CDN 網路。在本文的引言中我說過淘寶的 CDN 系統支撐了 800Gbps 以上的流量,作為對比我們可以看一下國內專業做 CDN 的上市公司 ChinaCache 的介紹 —— “ChinaCache……是中國第一的專業 CDN 服務提供商,向客戶提供全方位網路內容快速分佈解決方案。作為首家獲信產部許可的 CDN 服務提供商,目前 ChinaCache 在全國 50 多個大中城市擁有近 300 個節點,全網處理能力超過 500Gbps,其 CDN 網路覆蓋中國電信、中國網通、中國移動、中國聯通、中國鐵通和中國教育科研網等各大運營商。” —— 這樣你可以看得出淘寶在 CDN 上面的實力,這在全世界都是數一數二的。另外因為 CDN 需要大量的伺服器,要消耗很多能源(消耗多少?在前兩年我們算過一筆帳,淘寶上產生一個交易,消耗的電足以煮熟 4 個雞蛋)。這兩年章文嵩的團隊又在研究低功耗的伺服器,在綠色計算領域也做了很多開創性的工作。淘寶 CDN 的發展需要專門一個章節來講,想先睹為快的可以看一下筆者對章文嵩的專訪。  

  回想起剛用快取那段時間,筆者還是個小菜鳥,有一個經典的錯誤常常犯,就是資料庫的內容更新的時候,忘記通知快取系統,結果在測試的時候就發現我改過的資料怎麼在頁面上沒變化呢。後來做了一些頁面上的程式碼,修改 CSS 和 JS 的時候,使用者本地快取的資訊沒有更新,頁面上也會亂掉,在論壇上被人說的時候,我告訴他用 Ctrl+F5 重新整理頁面,然後趕緊修改指令碼檔案的名稱,重新發布頁面。學會用 Ctrl+F5 的會員對我佩服的五體投地,我卻慚愧的無地自容。 

  有些技術的發展是順其自然的,有些卻是突如其來的。到 2007 年的時候,我們已經有幾百臺應用伺服器了,這上面的 Java 應用伺服器是 WebLogic,而 WebLogic 是非常貴的,比這些伺服器本身都貴。有一段時間多隆研究了一下 JBoss,說我們換掉 WebLogic 吧,於是又省下了不少銀兩。那一年,老馬舉辦了第一屆的“網俠大會”,會上來的大俠中有一位是上文提到的章文嵩,還有一位曾經在 JBoss 團隊工作,我們也把這位大俠留下了,這樣我們用起 JBoss 更加有底氣了。  

  這些雜七雜八的修改,我們對資料分庫、放棄 EJB、引入 Spring、加入快取、加入 CDN、採用開源的 JBoss,看起來沒有章法可循,其實都是圍繞著提高容量、提高效能、節約成本來做的,由於這些不算大的版本變遷,我們姑且叫它 2.1 版吧,這個版本從構圖上來看有 3 只腳,是不是穩定了很多?

  架構圖如下:

  、淘寶技術發展(Java時代:創造技術-TFS)

  在講淘寶檔案系統 TFS 之前,先回顧一下上面幾個版本。1.0 版的 PHP 系統執行了將近一年的時間(2003.05~2004.01);後來資料庫變成 Oracle 之後(2004.01~2004.05,叫 1.1 版本吧),不到半年就把開發語言轉換為 Java 系統了(2004.02~2005.03,叫2.0版本);進行分庫、加入快取、CDN之後我們叫它 2.1 版本(2004.10~2007.01)。這中間有些時間的重合,因為很多架構的演化並沒有明顯的時間點,它是逐步進化而來的。

  在描述 2.1 版本的時候我寫的副標題是“堅若磐石”,這個“堅若磐石”是因為這個版本終於穩定下來了,在這個版本的系統上,淘寶網執行了兩年多的時間。這期間有很多優秀的人才加入,也開發了很多優秀的產品,例如支付寶認證系統、招財進寶專案、淘寶旅行、淘寶彩票、淘寶論壇等等。甚至在團購網站風起雲湧之前,淘寶網在 2006 年就推出了團購的功能,只是淘寶網最初的團購功能是買家發起的,達到賣家指定的數量之後,享受比一口價更低的價格,這個功能看起來是結合了淘寶一口價和荷蘭拍的另一種交易模式,但不幸沒有支撐下去。

  在這些產品和功能的最底層,其實還是商品的管理和交易的管理這兩大功能。這兩大功能在 2.1 版本里面都有很大的變化。商品的管理起初是要求賣家選擇 7 天到期還是 14 天到期,到期之後就要下架,必須重新發布才能上架,上架之後就變成了新的商品資訊(ID變過了)。另外如果這個期間內成交了,之後再有新貨,必須釋出一個新的商品資訊。這麼做有幾個原因,一是參照拍賣商品的時間設定,要在某日期前結束掛牌;二是搜尋引擎不知道同樣的商品哪個排前面,那就把掛牌時間長的排前面,這樣就必須在某個時間把老的商品下架掉,不然它老排在前面;第三是成交資訊和商品 ID 關聯,這個商品如果多次編輯還是同一個 ID 的話,成交記錄裡面的商品資訊會變來變去;還有一個不為人知的原因,我們的儲存有限,不能讓所有的商品老存放在主庫裡面。這種處理方式簡單粗暴,但還算是公平。不過這樣很多需求都無法滿足,例如同樣的商品,我上一次銷售的時候很多好評都沒法在下一個商品上體現出來;再例如我買過的商品結束後只看到交易的資訊,不知道賣家還有沒有再賣了。後來基於這些需求,我們在 2006 年下半年把商品和交易拆開。一個商家的一種商品有個唯一的 ID,上下架都是同一個商品。那麼如果賣家改價格、庫存什麼的話,已成交的資訊怎麼處理?那就在買家每交易一次的時候,都記錄下商品的快照資訊,有多少次交易就有多少個快照。這樣買賣雙方比較爽了,給系統帶來了什麼?儲存的成本大幅度上升了!

  儲存的成本高到什麼程度呢?資料庫方面提到過用了 IOE,一套下來就是千萬級別的,那幾套下來就是⋯⋯。另外淘寶網還有很多檔案需要儲存,我們有哪些檔案呢?最主要的就是圖片、商品描述、交易快照,一個商品要包含幾張圖片和一長串的描述資訊,而每一張圖片都要生成幾張規格不同的縮圖。在 2010 年,淘寶網的後端系統上儲存著 286 億個圖片檔案。圖片在交易系統中非常重要,俗話說“一張好圖勝千言”、“無圖無真相”,淘寶網的商品照片,尤其是熱門商品,圖片的訪問流量是非常大的。淘寶網整體流量中,圖片的訪問流量要佔到 90% 以上。且這些圖片平均大小為 17.45 KB,小於 8K 的圖片佔整體圖片數量 61%,佔整體系統容量的 11%。這麼多的圖片資料、這麼大的訪問流量,給淘寶網的系統帶來了巨大的挑戰。眾所周知,對於大多數系統來說,最頭疼的就是大規模的小檔案儲存與讀取,因為磁頭需要頻繁的尋道和換道,因此在讀取上容易帶來較長的延時。在大量高併發訪問量的情況下,簡直就是系統的噩夢。我們該怎麼辦?

  同樣的套路,在某個規模以下,採用現有的商業解決方案,達到某種規模之後,商業的解決方案無法滿足,只有自己創造解決方案了。對於淘寶的圖片儲存來說,轉折點在 2007 年。這之前,一直採用的商用儲存系統,應用 NetApp 公司的檔案儲存系統。隨著淘寶網的圖片檔案數量以每年 2 倍(即原來 3 倍)的速度增長,淘寶網後端 NetApp 公司的儲存系統也從低端到高階不斷遷移,直至 2006 年,即使是 NetApp 公司最高階的產品也不能滿足淘寶網儲存的要求。從 2006 年開始,淘寶網決定自己開發一套針對海量小檔案儲存的檔案系統,用於解決自身圖片儲存的難題。這標誌著淘寶網從使用技術到了創造技術的階段。

  2007年之前的圖片儲存架構如下圖:


  章文嵩博士總結了幾點商用儲存系統的侷限和不足:

  首先是商用的儲存系統沒有對小檔案儲存和讀取的環境進行有針對性的優化;其次,檔案數量大,網路儲存裝置無法支撐;另外,整個系統所連線的伺服器也越來越多,網路連線數已經到達了網路儲存裝置的極限。此外,商用儲存系統擴容成本高,10T的儲存容量需要幾百萬,而且存在單點故障,容災和安全性無法得到很好的保證。

  談到在商用系統和自主研發之間的經濟效益對比,章文嵩博士列舉了以下幾點經驗:

  1. 商用軟體很難滿足大規模系統的應用需求,無論儲存還是 CDN 還是負載均衡,因為在廠商實驗室端,很難實現如此大的資料規模測試。

  2. 研發過程中,將開源和自主開發相結合,會有更好的可控性,系統出問題了,完全可以從底層解決問題,系統擴充套件性也更高。

  3. 在一定規模效應基礎上,研發的投入都是值得的。上圖是一個自主研發和購買商用系統的投入產出比對比,實際上,在上圖的交叉點左邊,購買商用系統都是更加實際和經濟性更好的選擇,只有在規模超過交叉點的情況下,自主研發才能收到較好的經濟效果。實際上,規模化達到如此程度的公司其實並不多,不過淘寶網已經遠遠超過了交叉點。

  4. 自主研發的系統可在軟體和硬體多個層次不斷的優化。

  歷史總是驚人的巧合,在我們準備研發檔案儲存系統的時候,Google 走在了前面,2007 年他們公佈了 GFS( Google File System )的設計論文,這給我們帶來了很多借鑑的思路。隨後我們開發出了適合淘寶使用的圖片儲存系統TFS(Taobao File System)。3年之後,我們發現歷史的巧合比我們想象中還要神奇,幾乎跟我們同時,中國的另外一家網際網路公司也開發了他們的檔案儲存系統,甚至取的名字都一樣 —— TFS,太神奇了!(猜猜是哪家?)

  2007 年 6 月,TFS 正式上線運營。在生產環境中應用的叢集規模達到了 200 臺 PC Server(146G*6 SAS 15K Raid5),檔案數量達到上億級別;系統部署儲存容量:140TB;實際使用儲存容量: 50TB;單臺支援隨機IOPS200+,流量 3MBps。

  要講 TFS 的系統架構,首先要描述清楚業務需求,淘寶對圖片儲存的需求大概可以描述如下:

  檔案比較小;併發量高;讀操作遠大於寫操作;訪問隨機;沒有檔案修改的操作;要求儲存成本低;能容災能備份。應對這種需求,顯然要用分散式儲存系統;由於檔案大小比較統一,可以採用專有檔案系統;併發量高,讀寫隨機性強,需要更少的 IO 操作;考慮到成本和備份,需要用廉價的儲存裝置;考慮到容災,需要能平滑擴容。

  參照 GFS 並做了適度的優化之後,TFS 1.0 版的架構圖如下:


  從上面架構圖上看:叢集由一對 Name Server 和多臺 Data Serve r構成,Name Server 的兩臺伺服器互為雙機,就是叢集檔案系統中管理節點的概念。

  在這個架構中:
  • 每個 Data Server 執行在一臺普通的 Linux 主機上
  • 以 block 檔案的形式存放資料檔案(一般64M一個block )
  • block 存多份保證資料安全
  • 利用 ext3 檔案系統存放資料檔案
  • 磁碟 raid5 做資料冗餘
  • 檔名內建後設資料資訊,使用者自己儲存 TFS 檔名與實際檔案的對照關係 – 使得後設資料量特別小。

  淘寶 TFS 檔案系統在核心設計上最大的取巧的地方就在,傳統的叢集系統裡面後設資料只有 1 份,通常由管理節點來管理,因而很容易成為瓶頸。而對於淘寶網的使用者來說,圖片檔案究竟用什麼名字來儲存實際上使用者並不關心,因此TFS 在設計規劃上考慮在圖片的儲存檔名上暗藏了一些後設資料資訊,例如圖片的大小、時間、訪問頻次等等資訊,包括所在的邏輯塊號。而在後設資料上,實際上儲存的資訊很少,因此後設資料結構非常簡單。僅僅只需要一個 fileID,能夠準確定位檔案在什麼地方。

  由於大量的檔案資訊都隱藏在檔名中,整個系統完全拋棄了傳統的目錄樹結構,因為目錄樹開銷最大。拿掉後,整個叢集的高可擴充套件性極大提高。實際上,這一設計理念和目前業界的“物件儲存”較為類似,淘寶網 TFS 檔案系統已經更新到 1.3 版本,在生產系統的效能已經得到驗證,且不斷得到了完善和優化,淘寶網目前在物件儲存領域的研究已經走在前列。

  在 TFS 上線之前,淘寶網每個商品只允許上傳一張圖片,大小限定在 120K 之內,在商品詳情裡面的圖片必須使用外站的服務。那時侯釋出一件商品確實非常麻煩,筆者曾經想賣一臺二手電腦,先把照片上傳到 Google 相簿,在釋出到淘寶網之後發現 Google 相簿被牆了,我的圖片別人看不到,當時鬱悶的不行。TFS 上線後,商品展示圖片開放到 5 張,商品描述裡面的圖片也可以使用淘寶的圖片服務,到現在為止,淘寶網給每個使用者提供了 1G 的圖片空間,這下大家都滿足了。技術和業務就是這麼互相用力的推動著,業務滿足不了的時候,技術必須創新,技術創新之後,業務有了更大的發展空間。 

  1.3 版本的架構見阿里味(阿里巴巴內網)⋯⋯

  、淘寶技術發展(分散式時代:服務化)

  在系統發展的過程中,架構師的眼光至關重要,作為程式設計師,把功能實現即可,但作為架構師,要考慮系統的擴充套件性、重用性,這種敏銳的感覺,有人說是一種程式碼潔癖。淘寶早期有幾個架構師具備了這種感覺。一指開發的 Webx 是一個擴充套件性很強的框架,行癲在這個框架上插入了資料分庫路由的模組、session 框架等等。在做淘寶後臺系統的時候,同樣需要這幾個模組,行癲指導我把這些模組單獨打成了 jar 包。另外在做淘寶機票、彩票系統的時候,頁面端也有很多東西需要複用,最直觀的是頁頭和頁尾,一開始我們每個系統裡面複製了一份過去,但奇妙的是,那段時間頁尾要經常修改,例如把“雅虎中國”改成“中國雅虎”,過一段時間又加了一個“口碑網”,再過一段時間變成了“雅虎口碑”,最後又變成了“中國雅虎”,每個系統都改一遍,折騰啊。後來我就把這部分 velocity 模版單獨拿出來了,做成了公用的模組。  

  上面這些都是比較小的複用模組,到 2006 年我們做了一個商品類目屬性的改造,在類目裡面引入屬性的概念。專案的代號叫做“泰山”,如同它的名字,這是一個舉足輕重的專案,這個改變是一個劃時代的創新。在這之前的三年時間內,商品的分類都是按照樹狀的一級一級的節點來分的,隨著商品數量的增長,類目也變得越來越深,越來越複雜,這帶給買家的就是查詢一件商品要逐級類目點開,找商品之前要懂商品的分類。而淘寶運營部門管理類目的小二也發現一個很嚴重的問題 —— 例如男裝裡面有T恤、T恤下面有耐克、耐克有純棉的,女裝裡面也有T恤、T恤下面還是有耐克、耐克下面依然有純棉的,那是先分男女裝再分款式再分品牌再分材質呢?還是先分品牌再分款式再分材質再分男女呢?暈倒了。這時候,一位大俠出來了 —— 一燈,他說品牌、款式、材質這種東東可以叫做“屬性”,屬性是類似 tag 的一個概念,與類目相比更加離散,更加靈活,這樣也縮減了類目的深度。這個思想的提出,一舉解決了分類的難題!從系統的角度來看,我們建立了“屬性”這樣一個資料結構,由於除了類目的子節點有屬性,父節點也有可能有屬性,於是類目屬性合起來也是一個結構化的資料物件。這個做出來之後我們把它獨立出來作為一個服務,叫做 catserver(category server)。跟類目屬性密切關聯的商品搜尋功能,獨立出來,叫做 hesper(金星),catserver 和 hesper 供淘寶的前後臺系統呼叫。  

  現在淘寶的商品類目屬性已經是地球上最大的了,幾乎沒有什麼類目的商品在淘寶上找不到(除了違禁的),但最初類目屬性改造完之後,我們很缺屬性資料,尤其是數碼類的最缺。那從哪裡弄這些資料呢親?我們跟“中關村線上”合作,拿到了很多資料,那個時候,很多商品屬性資訊的後邊標註著:“來自中關村線上”。有了類目屬性,給運營的工作帶來很大的便利,我們知道淘寶的運營主要就是類目的運營,什麼季節推什麼商品,都要在類目屬性上面做調整,讓買家更容易找到。例如夏天我要使用者在女裝一級類目下就標出來材質是不是蕾絲的、是不是純棉的,冬天卻要把羽絨衣調到女裝一級類目下,流行什麼就要把什麼商品往更高階的類目調整。這樣類目和屬性要經常調整,隨之而來的問題就顯現了 —— 調整到哪個類目,那類商品的賣家就要編輯一次自己的商品,隨著商品量的增長,賣家的工作量越來越大,然後我們就發現賣家受不了啦。到了 2008 年,我們研究了超市裡面前後臺商品的分類,發現超市前臺商品可以隨季節和關聯來調整擺放場景(例如著名的啤酒和尿布的關聯),後臺倉庫裡面要按照自然類目來儲存,二者密切關聯卻又相互分開。然後我們就把前後臺類目分開了,這樣賣家釋出商品選擇的是自然類目和屬性,淘寶前臺展示的是根據運營需要而擺放的商品的類目和屬性。改造後的類目屬性服務取名叫做 forest(森林,跟類目屬性有點神似。catserver 還在,提供賣家授權、品牌服務、關鍵詞等相關的服務)。類目屬性的服務化,是淘寶在系統服務化方面做的第一個探索。 

  雖然個別架構師具備了程式碼潔癖,但淘寶前臺系統的業務量和程式碼量還是爆炸式的增長了起來。業務方總在後面催,開發人員不夠了就繼續招人,招來的人根本看不懂原來的業務,只好摸索著在“合適的地方”加一些“合適的程式碼”,看看執行起來像那麼回事,就釋出上線了。在這樣的惡性迴圈中,系統越來越臃腫,業務的耦合性越來越高,開發的效率越來越低。借用當時比較流行的一句話“寫一段程式碼,編譯一下能通過,半個小時就過去了;編譯一下沒通過,半天就過去了。”在這種情況下,系統出錯的概率也逐步增長,常常是你改了商品相關的某些程式碼,發現交易出問題了,甚至你改了論壇上的某些程式碼,旺旺出問題了。這讓開發人員苦不堪言,而業務方還認為這幫人幹活越來越慢了。  

  大概是在 2007 年底的時候,研發部空降了一位從矽谷來的高管,空聞大師。空聞是一位溫厚的長者,他告訴我們一切要以穩定為中心,所有影響系統穩定的因素都要解決掉。例如每做一個日常修改,都必須整個系統迴歸測試一遍;多個日常修改如果放在一個版本里面,要是一個功能沒有測試通過,整個系統都不能釋出。我們把這個叫做“火車模型”,任何一個乘客沒有上車,都不許發車。這樣做的最直接後果就是火車一直晚點,新功能上線更慢了,我們能明顯的感覺到業務方的不滿,空聞的壓力肯定非常大。當時我都不理解這種一刀切的做法,為了穩定犧牲了發展的速度,這跟某 Party 的“穩定壓倒一切”有什麼分別?  

  但是到現在回過頭來看看,其實我們並沒有理解背後的思路。正是在這種要求下,我們不得不開始改變一些東西,例如把迴歸測試日常化,每天晚上都跑一遍整個系統的迴歸。還有就是在這種要求下,我們不得不對這個超級複雜的系統做肢解和重構,其中複用性最高的一個模組 —— 使用者資訊模組開始拆分出來了,我們叫它 UIC(user information center)。在 UIC 裡面,它只處理最基礎的使用者資訊操作,例如getUserById、getUserByName等等。  

  在另外一個方面,還有兩個新興的業務,也對系統基礎功能的拆分提出了要求。在那個時候,我們做了淘寶旅行(trip.taobao.com)和淘寶彩票(caipiao.taobao.com)兩個新業務,這兩個新業務在商品的展示和交易的流程上都跟主站的業務不一樣,機票是按照航班的資訊展示的,彩票是按照雙色球、數字和足球的賽程來展示的。但用到的會員的功能和交易的功能是跟主站差不多的,當時做的時候就很糾結,在主站裡面做的話,會有一大半跟主站無關的東西,重新做一個的話,會有很多重複建設。最終我們決定不再給主站添亂了,就另起爐灶做了兩個新的業務系統。從查詢商品、購買商品、評價反饋、檢視訂單這一整個流程都重新寫了一套出來。現在在“我的淘寶”裡面檢視交易記錄的時候,還能發現“已買到的寶貝”裡面把機票和彩票另外列出來了,他們沒有加入到普通的訂單裡面去。在當時如果已經把會員、交易、商品、評價這些模組拆分出來,就不用什麼都重做一遍了。  

  到 2008 年初,整個主站系統(有了機票、彩票系統之後,把原來的系統叫做主站)的容量已經到了瓶頸,商品數在一億以上,PV 在 2.5 億以上,會員數超過了五千萬。這個時候 Oracle 的連線池數量都不夠用了,資料庫的容量到了極限,上層系統再增加機器也無法繼續擴容了,我們只有把底層的基礎服務繼續拆分,從底層開始擴容,上層才能擴充套件,這才能容納以後三五年的增長。

  於是那一年我們專門啟動了一個更大的專案,把交易這個核心業務模組也拆分出來了。原來的淘寶交易除了跟商品管理耦合在一起,也在支付寶和淘寶之間跳來跳去,跟支付寶耦合在一起,系統複雜,使用者體驗也很不好。我們把交易的底層業務拆出來叫交易中心TC(trade center),所謂底層業務是例如建立訂單、減庫存、修改訂單狀態等原子型的操作;交易的上層業務叫交易管理TM(trade manager),例如拍下一件普通商品要對訂單、庫存、物流進行操作,拍下虛擬商品不需要對物流進行操作,這些在TM裡面完成。這個專案取了一個很沒有創意的名字 —— “千島湖”,這幫開發人員取這個名字的目的是想在開發完畢之後,去千島湖玩一圈,後來他們如願以償了。這個時候還有一個專案也在搞,就是淘寶商城,之前拆分出來的那些基礎服務,給商城的快速構建,提供了良好的基礎。

  類目屬性、使用者中心、交易中心,隨著這些模組逐步的拆分和服務化改造,我們在系統架構方面也積累了不少的經驗。到 2008 年底乾脆做了一個更大的專案,把淘寶所有的業務都模組化,這是繼 2004 年從 LAMP 架構到 Java 架構之後的第二次脫胎換骨。這個專案取了一個很霸氣的名字,叫“五彩石”(女媧煉石補天,用的石頭)。這個系統重構的工作非常驚險,有人稱之為“給一架高速飛行的飛機換髮動機”。  

  五彩石專案釋出之後,這幫工程師去三亞玩了幾天。他們把淘寶的系統拆分成了如下架構:

  其中 UIC 和 Forest 上文說過,TC、IC、SC分別是交易中心(Trade Center)、商品中心(Item Center)、店鋪中心(Shop Center),這些中心級別的服務只提供原子級的業務邏輯,如根據ID查詢商品、建立交易、減少庫存等操作。再往上一層是業務系統TM(Trade Manager交易業務)、IM(Item Manager商品業務)、SM(Shop Manager,因為不好聽,所以後來改名叫 SS:Shop System,店鋪業務)、Detail(商品詳情)。  

  拆分之後,系統之間的互動關係變得非常複雜,示意圖如下:

  系統這麼拆分的話,好處顯而易見,拆分之後每個系統可以單獨部署,業務簡單,方便擴容;有大量可重用的模組以便於開發新的業務;能夠做到專人專事,讓技術人員更加專注於某一個領域。這樣要解決的問題也很明顯,分拆之後,系統之間還是必須要打交道的,越往底層的系統,呼叫它的客戶方越多,這就要求底層的系統必須具有超大規模的容量和非常高的可用性。另外,拆分之後的系統如何通訊?這裡需要兩種中介軟體系統,一種是實時呼叫的中介軟體(淘寶的HSF,高效能服務框架)、一種是非同步訊息通知的中介軟體(淘寶的Notify)。另外還有一個需要解決的問題是使用者在A系統登入了,到B系統的時候,使用者的登入資訊怎麼儲存?這又涉及到一個 Session 框架。再者,還有一個軟體工程方面的問題,這麼多層的一套系統,怎麼去測試它?


相關文章