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

轉自:http://blog.sina.com.cn/s/blog_633219970101062y.html

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

          TFS的開發,讓淘寶的圖片功能得到了充分的發揮。同TFS一樣,很多技術都是在產品的推動下得到發展的。在講下面的技術之前,有必要說說那些年,我們一起做過的幾個產品。

 

先說個比較悲劇的——【團購】,這個團購可不是現在滿大街掛的那種groupon類型的模式,在groupon出生之前,在2006年,淘寶的產品經理一燈就提出了“團購”這種產品。一燈最初的設想是讓買家在社區發起團購,“團長”找到足夠的人之後,去跟賣家砍價,這類似於現在蘑菇街的“自由團”。但由於種種原因,在開發的時候產品的功能做了裁剪,跟最初的設想比起來偏離了一點,變成了讓賣家設置團購價,在買家達到指定的數量之後,以團購價成交。這個功能看起來是結合了淘寶一口價和荷蘭拍的另一種交易模式,但不幸沒有支撐下去,這種交易方式最大的弱點就是讓買家看到了賣家的底牌,即便達不到團購的數量,他們也往團購的價格上砍。當時爲了引流量,淘寶網開闢了團購專區,實誠的賣家在達不到團購數量的時候,被砍價砍虧了,狡猾的賣家乾脆提高原價,利用這個專區做促銷。在接下來的兩年裏這個產品淪落成了促銷工具(話說現在滿大街的團購,其實也就是促銷)。這個產品,讓研發人員對“產品”這個概念有了深刻的認識。

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

 

再說一個更加悲劇的——【我的淘寶】,我的淘寶是給會員管理自己的商品、交易、收貨地址、評價、投訴的地方,這個地方由於登錄之後才能看到,所以風格跟外面完全不一樣,很長時間都沒有優化過,樣子醜,用戶操作也不方便,如果一個人有很多商品,上下架需要一個一個的操作,非常麻煩(想想那些賣書的)。這時候一個重要人物登場了,承志(現在的蘑菇街CEO,他讓我把他描寫的帥一點),他給我們演示了最牛叉的前端交互技術,就是Gmail上那種Ajax的交互方式,可以拖動、可以用右鍵、可以組合鍵選擇、操作完畢還不刷新頁面,管理商品如有神助,帥呆了。我是這個項目的項目經理,一燈是產品經理,我們再拉上萬劍和一夥工程師就開搞了。熱火朝天的幹了三個月,快要完成的時候,老馬不知道怎麼回事突然出現在我身後,看我操作了一遍新版我的淘寶之後,問我這是不是客戶端軟件,我說是網頁,他抓狂了,說這跟客戶端軟件一樣,鏈接底下連線都木有,上下架用文件夾表示,我都不知道怎麼操作了,賣家肯定也不會玩。

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

 

老馬果然是神一樣的人物,他說的應驗了,淘寶曆史上第一個羣體性事件爆發了,試用完新版本的我的淘寶之後,很多賣家憤怒了,說不會玩。一燈就和承志一起商量怎麼把頁面改得像個網頁一點,改了半個月,憤怒依然沒有平息。我很無奈地看着這兩個人在那裏堅持,然後跟老闆們商量怎麼辦。後來我們用了一個很挫的方法給自己一個臺階,到論壇上讓大家投票要不要使用新版我的淘寶,投票結果是一半以上的反對。於是這麼十來個人做了3個月的系統被殺掉了。這讓我非常沮喪,但最痛苦的還不是這個,我們下線之後,另外一撥賣家不滿了,說這麼好的功能怎麼沒有了?啊~~~你們怎麼不早點站出來,親?這個產品帶給我們的是新技術(Ajax)的嘗試,還有就是新技術對用戶操作習慣的改變,一定要慎之又慎。另外還有一點沒有總結好的教訓,就是應對羣體事件的時候,我們手足無措,在後來【招財進寶】和淘寶商城出現羣體性事件的時候,我發現悲劇在重演。

 

說到【招財進寶】,這個是最悲劇的產品。到2006年五一的時候,一個劃時代的項目啓動了(我苦逼的連續失去了兩個五一節,前面一個是2005年做支付寶系統)。財神說要用最好的項目陣容,我被選中了,這一下子讓我覺得我能劃分到最好的員工之類,在【我的淘寶】這個產品中嚴重受傷的心又痊癒了。這是一個商品P4P的系統,就是按成交付費。我們認爲已經有很多賣家有錢了,但淘寶上這麼多的商品,他們很難被找到,賣家願意花錢讓商品排在前面。我們允許賣家購買廣告位,把他的商品按一定算法給個排名(類似於百度的競價排名,但不僅僅看他出了多少錢,還有信用、成交量、被收藏數量等等,這個算法搞的巨複雜)。這是一個多麼牛叉的盈利模式啊!

 

這個系統進行的很順利,但發佈的時候,更大的羣體性事件出來了,買家們質疑:你們不是承諾3年不收費麼?收廣告費不是收費麼?後來我們的競爭對手又推波助瀾,公關公司和圈子裏各路大俠上躥下跳,甚至同行搞了個“一鍵搬家”的功能來收納我們的會員。一時之間,輿論譁然,各種矛頭都指了過來。爲了收場,我們又一次在論壇裏面讓用戶投票決定產品是否下線,同【我的淘寶】一樣,以悲劇收場。也如同【我的淘寶】一樣,下線後,一撥嚐到甜頭的賣家說,這麼好的功能怎麼沒有了?(直到後來yahoo中國合併過來之後,開發了淘寶直通車,才以類似的產品形態滿足了這部分需求)

 

雖然招財進寶失敗了,但這個項目中對技術的探索更加深入,這裏面用到了用戶行爲追蹤、Ajax等。其中有一個技術的細節非常經典,淘寶商品詳情頁面每天的流量在10億以上,裏面的內容都是放在緩存裏的,做招財進寶的時候,我們要給賣家顯示他的商品被瀏覽的次數(見下圖),這個數字必須實時更新,而用緩存的話一般都是異步更新的。於是商品表裏面增加了這樣一個字段,每增加一個PV這個字段就要更新一次。發佈上去一個小時數據庫就掛掉了,撐不住這麼高的update。數據庫撐不住怎麼辦?一般的緩存策略是不支持實時更新的,這時候多隆大神想了個辦法,在apache上面寫了一個模塊,這個數字根本不經過下層的web容器(只經過apache)就寫入一個集中式的緩存區了,這個緩存區的數據再異步更新到數據庫。這就是我前面提到的,我們整個商品詳情的頁面都在緩存中了,把緩存用到了極致。

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

(這個圖真不是廣告,親)

 

那麼接下來,我們就說說緩存的技術吧。

 

淘寶在很早就開始使用緩存的技術了,在2004年的時候,我們使用一個叫做ESI(Edge Side Includes)的緩存。在決定採用ESI之前,多隆試用了很多java的cache,但都比較重,後來用了oracle web cache,也經常掛掉,oracle web cache也支持ESI,多隆由此發現了ESI這個好東東。ESI是一種數據緩衝/緩存服務器,它提供將Web網頁的部分(這裏指頁面的片段)進行緩衝/緩存的技術及服務。由Oracle公司和Akamai Technologies公司制定規格,Akamai公司提供對應的信息傳送的服務。以往的數據緩衝服務器和信息傳送服務以“頁”爲單位制作,複製到數據緩衝服務器中,處理靜態頁面很有效。但在面對動態內容的時候,就很難得到高效率。在ESI中是部分的緩衝網頁,使用基於XML的標記語言,指定想要緩衝的頁面部分。由此,頁面內分爲動態地變更的部分和靜態的不變更的部分,只將靜態的部分有效地發送到服務器中。淘寶網的數據雖然大部分都是動態產生的,但頁面中的靜態片段也有很多,例如頁面的頭、尾,商品詳情頁面的賣家信息等(如下圖右側),這些最早都是從ESI緩存中讀取的。

 

 

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

 

ESI解決了頁面端靜態片段的緩存,聰明的讀者可能馬上就想到了,在後端的那些數據能不能使用緩存?顯然也是可以的,而且是必須的。例如一個大賣家的商品和店鋪,一天的瀏覽量可能是幾百萬,一個小賣家的可能只有幾個,那這個大賣家的用戶信息要是每次都去數據庫裏面取,顯然不划算,要是把這個信息放在內存裏面,每次都從內存裏取,性能要好很多。這種應用場景,就是memcached這種Key-Value緩存的用武之地。只可惜在淘寶急需要memcached的時候,它還沒有嶄露頭角(它2003.6出現的,但近幾年才火爆起來,當時沒發現它)。我們的架構師多隆大神再一次出手了,他寫了一個緩存系統,叫TBstore,這是一個分佈式的基於Berkeley DB的cache系統,推出之後在Alibaba集團內部使用非常廣泛,特別是對於淘寶,tbstore上應用了ESI(就是上面說過的那個ESI)、checkcode(驗證碼)、description(前文說過的商品詳情)、story(心情故事,商品信息裏面的一個大字段,長度僅次於商品詳情)、用戶信息等等內容。

 

TBstore的分佈式算法實現:根據保存的key,對key進行hash算法,取得hash值,再對hash值與總Cache服務器數據取模。然後根據取模後的值,找到服務器列表中下標爲此值Cache服務器。由java client api封裝實現,應用無需關心;這點和memecached的實現方案完全一致。

 

TBstore有一個優點,這也是它的弱點,它的存儲是基於Berkeley DB的,而Berkeley DB在數據量超過內存的時候,就要往磁盤上寫數據了,所以說它是可以做持久化存儲的。但是一旦往磁盤寫數據,作爲緩存的性能就大幅度下降。

 

這時又有一個項目,推動了淘寶在緩存方面的技術提升。在2007年,我們把淘寶的用戶信息獨立出來,形成一箇中心繫統UIC(user information center),因爲淘寶所有的功能都要依賴於用戶信息,所以這個模塊必須單獨拿出來,不然以後系統無法擴展了。把UIC拿出來以後,應用系統訪問UIC,UIC訪問數據庫取得用戶信息,粗粗算一下,每天要取幾十億的用戶信息,直接查詢數據庫的話,顯然數據庫要崩潰的,這裏必須要用緩存。於是多隆爲UIC專門寫了一個緩存系統,取名叫做tdbm。tdbm拋棄了Berkeley DB的持久功能,數據全部存放在內存中。到2009年,多隆又參考了memcached的內存結構,改進了tdbm的集羣分佈方式,在內存利用率和吞吐量方面又做了大幅提升,推出了tdbm2.0系統。

 

由於tdbm和TBstore的數據接口和用途都很相似,開發團隊把二者合併,推出了淘寶自創的KV緩存系統——tair。tair包括緩存和持久化兩種存儲功能。tair 作爲一個分佈式系統,是由一箇中心控制節點和一系列的服務節點組成。我們稱中心控制節點爲config server,服務節點是data server。config server 負責管理所有的data server,維護data server的狀態信息。data server 對外提供各種數據服務,並以心跳的形式將自身狀況彙報給config server。 config server是控制點,而且是單點,目前採用一主一備的形式來保證其可靠性。所有的 data server 地位都是等價的。tair的架構圖如下所示:

淘寶技術發展(Java時代:創造技術-Tair)
部署結構圖是這個樣子的:

 

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

目前,tair支撐了淘寶幾乎所有系統的緩存信息。Tair已開源,地址code.taobao.org。

 

在創造了TFS和tair之後,整個系統的架構可以如下所示:


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

 

在這個時候搜索引擎iSearch也進行了一次升級,之前的搜索引擎是把數據分到多臺機器上,但是每份數據只有一份,現在是每份數據變成多份,整個系統從一個單行的部署變成了矩陣。能夠支撐更大的訪問量,並且做到很高的可用性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章