淘宝网的技术发展史(三)——分布式时代
本文是《淘寶網(wǎng)的技術(shù)發(fā)展史》系列連載文的第三篇。在系統(tǒng)發(fā)展的過程中,架構(gòu)師的眼光至關(guān)重要,作為程序員,把功能實(shí)現(xiàn)即可;但作為架構(gòu)師,要考慮系統(tǒng)的擴(kuò)展性、復(fù)用性,這種敏銳的感覺,有人說是一種代碼潔癖。
文/淘寶技術(shù)大學(xué)培訓(xùn)專家?子柳
?
在做淘寶機(jī)票、彩票系統(tǒng)的時候,頁面端也有很多東西需要復(fù)用,最直觀的是頁頭和頁腳。一開始我們每個系統(tǒng)里面復(fù)制了一份過去,但奇妙的是,那段時間頁腳要經(jīng)常修改,例如把“雅虎中國”改成“中國雅虎”,過一段時間又加了一個“口碑網(wǎng)”,再過一段時間變成了“雅虎口碑”,最后又變成了“中國雅虎”。后來我就把這部分velocity模板單獨(dú)拿出來了,做成了公用的模塊。
?
類目屬性服務(wù)化
上面這些都是比較小的復(fù)用模塊,到2006年我們做了一個商品類目屬性的改造,在類目里面引入屬性的概念。項(xiàng)目的代號叫做“泰山”。如同它的名字,這是一個舉足輕重的項(xiàng)目,這個改變是一個劃時代的創(chuàng)新。
在這之前的三年時間內(nèi),商品的分類都是按照樹狀的一級一級的節(jié)點(diǎn)來分的,隨著商品數(shù)量的增長,類目也變得越來越深、越來越復(fù)雜,這使得買家找一件商品要逐級類目點(diǎn)開,找商品之前要懂商品的分類。
而淘寶運(yùn)營部門管理類目的小二也發(fā)現(xiàn)一個很嚴(yán)重的問題——例如男裝里面有T恤、T恤下面有耐克、耐克有純棉的,女裝里面也有T恤、T恤下面還是有耐克、耐克下面依然有純棉的,那是先分男女裝再分款式再分品牌再分材質(zhì),還是先分品牌再分款式再分材質(zhì)再分男女呢?
這時候,一位大俠——一燈出來了,他說品牌、款式、材質(zhì)這種東東可以叫做“屬性”,屬性是類似tag的一個概念,與類目相比更加離散,更加靈活,這樣也縮減了類目的深度。這個思想的提出,一舉解決了分類的難題!從系統(tǒng)的角度來看,我們建立了“屬性”這樣一個數(shù)據(jù)結(jié)構(gòu),由于除了類目的子節(jié)點(diǎn)有屬性,父節(jié)點(diǎn)也可能有屬性,于是類目屬性合起來也是一個結(jié)構(gòu)化的數(shù)據(jù)對象。這個做出來之后我們把它獨(dú)立出來作為一個服務(wù),叫做catserver(category?server)。跟類目屬性密切關(guān)聯(lián)的商品搜索功能也獨(dú)立出來,叫做hesper(金星)。catserver和hesper供淘寶的前后臺系統(tǒng)調(diào)用。
現(xiàn)在幾乎沒有什么類目的商品在淘寶上找不到(除了違禁的),但最初類目屬性改造完之后,我們很缺屬性數(shù)據(jù),尤其是數(shù)碼類的數(shù)據(jù)最缺。那從哪里弄這些數(shù)據(jù)呢?我們跟“中關(guān)村在線”合作,拿到了很多數(shù)據(jù),那個時候,很多商品屬性信息的后邊都標(biāo)注著“來自中關(guān)村在線”。有了類目屬性,給運(yùn)營的工作帶來很大的便利。我們知道淘寶的運(yùn)營主要就是類目的運(yùn)營,什么季節(jié)推什么商品,都要在類目屬性上做調(diào)整,讓買家更容易找到。例如夏天我要用戶在女裝一級類目下就標(biāo)出來材質(zhì)是不是蕾絲的、是不是純棉的,而冬天就要把羽絨衣調(diào)到女裝一級類目下,流行什么就要把什么商品往更高級的類目調(diào)整。
這樣類目和屬性要經(jīng)常調(diào)整,問題就隨之而來了——調(diào)整到哪個類目,那類商品的賣家就要編輯一次自己的商品,隨著商品量的增長,賣家的工作量越來越大,然后我們就發(fā)現(xiàn)賣家受不了了。
到了2008年,我們研究了超市前后臺商品的分類,發(fā)現(xiàn)超市前臺商品可以隨季節(jié)和關(guān)聯(lián)度來調(diào)整擺放場景(例如著名的啤酒和尿布的關(guān)聯(lián)),后臺倉庫要按照自然類目來存儲,二者密切關(guān)聯(lián)卻又相互分開。然后我們就也把前后臺類目分開了,這樣賣家發(fā)布商品選擇的是自然類目和屬性,淘寶前臺展示的是根據(jù)運(yùn)營需要而擺放的商品的類目和屬性。改造后的類目屬性服務(wù)取名叫做forest(森林,跟類目屬性有點(diǎn)神似)。catserver還在,提供賣家授權(quán)、品牌服務(wù)、關(guān)鍵詞等相關(guān)的服務(wù)。類目屬性的服務(wù)化,是淘寶在系統(tǒng)服務(wù)化方面做的第一個探索。
雖然個別架構(gòu)師具備了代碼潔癖,但淘寶前臺系統(tǒng)的業(yè)務(wù)量和代碼量還是爆炸式地增長了起來。業(yè)務(wù)方總在后面催,開發(fā)人員不夠了就繼續(xù)招人,招來的人根本看不懂原來的業(yè)務(wù),只好摸索著在“合適的地方”加一些“合適的代碼”,看看運(yùn)行起來像那么回事,就發(fā)布上線了。在這樣的惡性循環(huán)中,系統(tǒng)越來越臃腫,業(yè)務(wù)的耦合性越來越高,開發(fā)的效率越來越低。在這種情況下,系統(tǒng)出錯的概率也逐步增長,常常是你改了商品相關(guān)的某些代碼,發(fā)現(xiàn)交易出問題了,甚至你改了論壇上的某些代碼,旺旺出問題了。這讓開發(fā)人員苦不堪言,而業(yè)務(wù)方還認(rèn)為這幫人干活越來越慢了。
?
以穩(wěn)定為中心
大概是在2007年底的時候,研發(fā)部空降了一位從硅谷來的高管——空聞大師。他告訴我們一切要以穩(wěn)定為中心,所有影響系統(tǒng)穩(wěn)定的因素都要解決掉。例如每做一個日常修改,都必須整個系統(tǒng)回歸測試一遍;多個日常修改如果放在一個版本里面,要是一個功能沒有測試通過,整個系統(tǒng)都不能發(fā)布。我們把這個叫做“火車模型”,任何一個乘客沒有上車,都不許發(fā)車。這樣做的最直接后果就是火車一直晚點(diǎn),新功能上線更慢了,我們能明顯地感覺到業(yè)務(wù)方的不滿,空聞的壓力肯定非常大。當(dāng)時我都不理解這種一刀切的做法,為了穩(wěn)定犧牲了發(fā)展的速度。
但是到現(xiàn)在回過頭來看看,其實(shí)我們并沒有理解背后的思路。正是在這種要求下,我們不得不開始改變一些東西,例如把回歸測試日常化,每天晚上都跑一遍整個系統(tǒng)的回歸。還有就是在這種要求下,我們不得不對這個超級復(fù)雜的系統(tǒng)做肢解和重構(gòu),其中復(fù)用性最高的一個模塊——用戶信息模塊開始拆分出來了,我們叫它UIC(user?information?center)。在UIC里面,它只處理最基礎(chǔ)的用戶信息操作,例如getUserById、getUserByName等等。
另外一方面,還有兩個新興的業(yè)務(wù),也對系統(tǒng)基礎(chǔ)功能的拆分提出了要求。在那個時候,我們做了淘寶旅行(trip.taobao.com)和淘寶彩票(caipiao.taobao.com)兩個新業(yè)務(wù),這兩個新業(yè)務(wù)在商品的展示和交易的流程上都跟主站的業(yè)務(wù)不一樣,機(jī)票是按照航班的信息展示的,彩票是按照雙色球、數(shù)字和足球的賽程來展示的。但用到的會員的功能和交易的功能是跟主站差不多的,當(dāng)時做的時候就很糾結(jié),在主站里面做的話,會有一大半跟主站無關(guān)的東西,重新做一個的話,會有很多重復(fù)建設(shè)。
最終我們決定不再給主站添亂了,就另起爐灶做了兩個新的業(yè)務(wù)系統(tǒng)。從查詢商品、購買商品到????????????????????????評價(jià)反饋、查看訂單這一整個流程都重新寫了一套出來。現(xiàn)在在“我的淘寶”里面查看交易記錄的時候,還能發(fā)現(xiàn)“已買到的寶貝”里面把機(jī)票和彩票另外列出來了,它們沒有加入到普通的訂單里面去。在當(dāng)時如果已經(jīng)把會員、交易、商品、評價(jià)這些模塊拆分出來,就不用什么都重做一遍了。
?
拆分核心模塊
到2008年初,整個主站系統(tǒng)(有了機(jī)票、彩票系統(tǒng)之后,把原來的系統(tǒng)叫做主站)的容量已經(jīng)到了瓶頸,商品數(shù)在一億以上,PV在2.5億以上,會員數(shù)超過了五千萬。這個時候Oracle的連接池?cái)?shù)量都不夠用了,數(shù)據(jù)庫的容量到了極限,上層系統(tǒng)再增加機(jī)器也無法繼續(xù)擴(kuò)容了,我們只有把底層的基礎(chǔ)服務(wù)繼續(xù)拆分,從底層開始擴(kuò)容,上層才能擴(kuò)展,這才能容納以后三五年的增長。
于是那一年我們專門啟動了一個更大的項(xiàng)目,把交易這個核心業(yè)務(wù)模塊也拆分出來了。原來的淘寶交易除了跟商品管理耦合在一起,也在支付寶和淘寶之間跳來跳去,跟支付寶耦合在一起,系統(tǒng)復(fù)雜,用戶體驗(yàn)也很不好。我們把交易的底層業(yè)務(wù)拆出來叫交易中心TC(trade?center),所謂底層業(yè)務(wù)是例如創(chuàng)建訂單、減庫存、修改訂單狀態(tài)等原子型的操作;交易的上層業(yè)務(wù)叫交易管理TM(trade?manager),例如拍下一件普通商品要對訂單、庫存、物流進(jìn)行操作,拍下虛擬商品不需要對物流進(jìn)行操作,這些在TM里面完成。這個項(xiàng)目取了一個很沒有創(chuàng)意的名字——“千島湖”,這幫開發(fā)人員取這個名字的目的是想在開發(fā)完畢之后,去千島湖玩一圈,后來他們?nèi)缭敢詢斄恕_@個時候還有一個項(xiàng)目也在搞,就是淘寶商城,之前拆分出來的那些基礎(chǔ)服務(wù),給商城的快速構(gòu)建提供了良好的基礎(chǔ)。
類目屬性、用戶中心、交易中心,隨著這些模塊逐步地拆分和服務(wù)化改造,我們在系統(tǒng)架構(gòu)方面也積累了不少的經(jīng)驗(yàn)。到2008年底干脆做了一個更大的項(xiàng)目,把淘寶所有的業(yè)務(wù)都模塊化,這是繼2004年從LAMP架構(gòu)到Java架構(gòu)之后的第二次脫胎換骨。這個項(xiàng)目取了一個很霸氣的名字,叫“五彩石”(女媧煉石補(bǔ)天用的石頭)。這個系統(tǒng)重構(gòu)的工作非常驚險(xiǎn),有人稱之為“給一架高速飛行的飛機(jī)換發(fā)動機(jī)”。
“五彩石”項(xiàng)目發(fā)布之后,這幫工程師去三亞玩了幾天。他們把淘寶的系統(tǒng)拆分成了如下架構(gòu):
其中UIC和forest上文說過,TC、IC、SC分別是交易中心(trade?center)、商品中心(item?center)、店鋪中心(shop?center),這些中心級別的服務(wù)只提供原子級的業(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)椴缓寐?#xff0c;所以后來改名叫SS,即shop?system,店鋪業(yè)務(wù))、Detail(商品詳情)。
拆分之后,系統(tǒng)之間的交互關(guān)系變得非常復(fù)雜,如圖2所示。
拆分之后每個系統(tǒng)可以單獨(dú)部署,業(yè)務(wù)簡單,方便擴(kuò)容;有大量可重用的模塊以便于開發(fā)新的業(yè)務(wù);能夠做到專人專事,讓技術(shù)人員更加專注于某一個領(lǐng)域。這樣要解決的問題也很明顯:分拆之后,系統(tǒng)之間還是必須要打交道的,越往底層的系統(tǒng),調(diào)用它的客戶方越多,這就要求底層的系統(tǒng)必須具有超大規(guī)模的容量和非常高的可用性。
另外,拆分之后的系統(tǒng)如何通訊?這里需要兩種中間件系統(tǒng),一種是實(shí)時調(diào)用的中間件(淘寶的HSF,高性能服務(wù)框架)、一種是異步消息通知的中間件(淘寶的Notify)。另外還有一個需要解決的問題是用戶在A系統(tǒng)登錄了,到B系統(tǒng)的時候,用戶的登錄信息怎么保存?這又涉及一個session框架。再者,還有一個軟件工程方面的問題:這么多層的一套系統(tǒng),怎么去測試它?這些問題在后來的發(fā)展中都進(jìn)行了解決。
http://i.wshang.com/?p=22930
總結(jié)
以上是生活随笔為你收集整理的淘宝网的技术发展史(三)——分布式时代的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 淘宝网的技术发展史(二) ——Oracl
- 下一篇: Android数据手册:Android颜