淘寶技術發展主要經歷了“個人網站”→“Oracle/ 支付寶 / 旺旺”→“Java 時代 1.0”→“Java 時代 2.0”→“Java 時代 3.0”→“分布式時代”。每個階段的主要驅動力是什么。
1. 個人網站
淘寶當時在初創時,沒有過多考慮技術是否優越、性能是否海量以及穩定性如何,主要的考慮因素就是:快!
買一個什么樣的網站?方便地擴展和二次開發。答案是:輕量一點的,簡單一點的。
買一個系統是為了“快速可用”,而買一個輕量級的系統是為了“快速開發”。主要遵循的是“合適原則”和“簡單原則”。第一代的技術架構如圖所示。
2.Oracle/ 支付寶 / 旺旺
在 2003 年底,MySQL 已經撐不住了。
一般人或者團隊在這個時候,可能就開始優化系統、優化架構、分拆業務了,因為這些是大家耳熟能詳也很拿手的動作。淘寶這個時候:換 Oracle 的原因除了它容量大、穩定、安全、性能高,還有人才方面的原因。
除了購買 Oracle,后來為了優化,又買了更強大的存儲:
后來數據量變大了,本地存儲不行了。買了 NAS(Network Attached Storage,網絡附屬存儲),NetApp 的 NAS 存儲作為了數據庫的存儲設備,加上 Oracle RAC(Real Application Clusters,實時應用集群)來實現負載均衡。
第一階段買的是“方案”,這個階段買的就是“性能”,這里架構設計和選擇主要遵循的還是“合適原則”和“簡單原則”。
3. 脫胎換骨的 Java 時代 1.0
淘寶切換到 Java 的原因很有趣,主要因為找了一個 PHP 的開源連接池 SQL Relay 連接到 Oracle,而這個代理經常死鎖,死鎖了就必須重啟,而數據庫又必須用 Oracle,于是決定換個開發語言。最后淘寶挑選了 Java,而且當時挑選 Java,也是請 Sun 公司的人,這幫人很歷害,先是將淘寶網站從 PHP 熱切換到了 Java,后來又做了支付寶。
頻繁的死鎖和重啟對用戶業務產生了嚴重的影響,從業務的角度來看這是不得不解決的技術問題。
但這次淘寶為什么沒有去“買”呢?我們看最初選擇 SQL Relay 的原因:
但對于 PHP 語言來說,它是放在 Apache 上的,每一個請求都會對數據庫產生一個連接,它沒有連接池這種功能(Java 語言有 Servlet 容器,可以存放連接池)。那如何是好呢?這幫人打探到 eBay 在 PHP 下面用了一個連接池的工具,是 BEA 賣給他們的。我們知道 BEA 的東西都很貴,我們買不起,于是多隆在網上尋尋覓覓,找到一個開源的連接池代理服務 SQL Relay。
不清楚當時到底有多貴,Oracle 都可以買,連接池買不起 ?所以我個人感覺這次切換語言,更多是為以后業務發展做鋪墊,畢竟當時 PHP 語言遠遠沒有 Java 那么火、那么好招人。淘寶選擇 Java 語言的理由可以從側面驗證這點:
Java 是當時最成熟的網站開發語言,它有比較良好的企業開發框架,被世界上主流的大規模網站普遍采用,另外有 Java 開發經驗的人才也比較多,后續維護成本會比較低。
綜合來看,這次架構的變化沒有再簡單通過“買”來解決,而是通過重構來解決,架構設計和選擇遵循了“演化原則”。
4. 堅若磐石的 Java 時代 2.0
Java 時代 2.0,淘寶做了很多優化工作:數據分庫、放棄 EJB、引入 Spring、加入緩存、加入 CDN、采用開源的 JBoss。看起來沒有章法可循,其實都是圍繞著提高容量、提高性能、節約成本來做的。
就是“買”也搞不定了,此時的業務發展情況是這樣的:隨著數據量的繼續增長,到了 2005 年,商品數有 1663 萬,PV 有 8931 萬,注冊會員有 1390 萬,這給數據和存儲帶來的壓力依然很大,數據量大,性能就慢。
整個架構上去進行調整和優化。比如說 Oracle 再強大,在做 like 類搜索的時候,也不可能做到純粹的搜索系統如 Solr、Sphinx 等的性能,因為這是機制決定的。
另外,隨著規模的增大,純粹靠買的一個典型問題開始成為重要的考慮因素,那就是成本。當買一臺兩臺 Oracle 的時候,可能對成本并不怎么關心,但如果要買 100 臺 Oracle,成本就是一個關鍵因素了。這就是“量變帶來質變”的一個典型案例,業務和系統發生質變后,架構設計遵循“演化原則”的思想,需要再一次重構甚至重寫。
5.Java 時代 3.0 和分布式時代
Java 時代 3.0 我個人認為是淘寶技術飛躍的開始,商用轉為“自研”,典型的就是去 IOE 化。
分布式時代我認為是淘寶技術的修煉成功,到了這個階段,自研技術已經自成一派,除了支撐本身的海量業務,也開始影響整個互聯網的技術發展。
到了這個階段,業務規模急劇上升后,原來并不是主要復雜度的 IOE 成本開始成為了主要的問題,因此通過自研系統來降低 IOE 的成本,去 IOE 也是系統架構的再一次演化。
手機 QQ
注:以下部分內容摘自《QQ 1.4 億在線背后的故事》。
手機 QQ 的發展歷程按照用戶規模可以粗略劃分為 4 個階段:十萬級、百萬級、千萬級、億級,不同的用戶規模,IM 后臺的架構也不同,而且基本上都是用戶規模先上去,然后產生各種問題,倒逼技術架構升級。
1. 十萬級 IM 1.X
最開始的手機 QQ 后臺是這樣的,可以說是簡單得不能再簡單、普通得不能再普通的一個架構了,因為當時業務剛開始,架構設計遵循的是“合適原則”和“簡單原則”。
2. 百萬級 IM 2.X
隨著業務發展到 2001 年,QQ 同時在線人數也突破了一百萬。第一代架構很簡單,明顯不可能支撐百萬級的用戶規模,主要的問題有:
以接入服務器的內存為例,單個在線用戶的存儲量約為 2KB,索引和在線狀態為 50 字節,好友表 400 個好友 × 5 字節 / 好友 = 2000 字節,大致來說,2GB 內存只能支持一百萬在線用戶。
CPU/ 網卡包量和流量 / 交換機流量等瓶頸。
單臺服務器支撐不下所有在線用戶 / 注冊用戶。
于是針對這些問題做架構改造,按照“演化原則”的指導進行了重構,重構的方案相比現在來說也還是簡單得多,因此當時做架構設計時也遵循了“合適原則”和“簡單原則”。IM 2.X 的最終架構如圖所示。
3. 千萬級 IM 3.X
業務發展到 2005 年,QQ 同時在線人數突破了一千萬。第二代架構支撐百萬級用戶是沒問題的,但支撐千萬級用戶又會產生新問題,表現有:
同步流量太大,狀態同步服務器遇到單機瓶頸。
所有在線用戶的在線狀態信息量太大,單臺接入服務器存不下,如果在線數進一步增加,甚至單臺狀態同步服務器也存不下。
單臺狀態同步服務器支撐不下所有在線用戶。
單臺接入服務器支撐不下所有在線用戶的在線狀態信息。
針對這些問題,架構需要繼續改造升級,再一次“演化”。IM 3.X 的最終架構如下圖,可以看到這次的方案相比之前的方案來說并不簡單了,這是業務特性決定的。
4. 億級 IM 4.X
業務發展到 2010 年 3 月,QQ 同時在線人數過億。第三代架構此時也不適應了,主要問題有:
靈活性很差,比如“昵稱”長度增加一半,需要兩個月;增加“故鄉”字段,需要兩個月;最大好友數從 500 變成 1000,需要三個月。
無法支撐某些關鍵功能,比如好友數上萬、隱私權限控制、PC QQ 與手機 QQ 不可互踢、微信與 QQ 互通、異地容災。
除了不適應,還有一個更嚴重的問題:
IM 后臺從 1.0 到 3.5 都是在原來基礎上做改造升級的,但是持續打補丁已經難以支撐億級在線,IM 后臺 4.0 必須從頭開始,重新設計實現!
這里再次遵循了“演化原則”,決定重新打造一個這么復雜的系統,不得不佩服當時決策人的勇氣和魄力!
重新設計的 IM 4.0 架構如圖所示,和之前的架構相比,架構本身都拆分為兩個主要的架構:存儲架構和通信架構。
存儲架構
通信架構
小結
搜索一個互聯網大廠(BATJ、TMD 等)的架構發展案例,分析一下其發展過程,看看哪些地方體現了這三條架構設計原則。