淘寶框架歷程

 一、個人網站 

         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 框架。再者,還有一個軟件工程方面的問題,這麼多層的一套系統,怎麼去測試它?

原文地址:http://www.361way.com/taobao-architecture/1948.html
發佈了17 篇原創文章 · 獲贊 12 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章