來源:huashiou sf.gg/a/1190000018626163
1. 概述本文以淘寶作為例子,介紹從一百個到千萬級并發(fā)情況下服務端的架構的演進過程,,同時列舉出每個演進階段會遇到的相關技術,,讓大家對架構的演進有一個整體的認知,文章最后匯總了一些架構設計的原則,。
2. 基本概念在介紹架構之前,,為了避免部分讀者對架構設計中的一些概念不了解,下面對幾個最基礎的概念進行介紹:
3. 架構演進3.1 單機架構以淘寶作為例子,。在網(wǎng)站最初時,應用數(shù)量與用戶數(shù)都較少,,可以把Tomcat和數(shù)據(jù)庫部署在同一臺服務器上,。瀏覽器往www.taobao.com發(fā)起請求時,首先經(jīng)過DNS服務器(域名系統(tǒng))把域名轉(zhuǎn)換為實際IP地址10.102.4.1,,瀏覽器轉(zhuǎn)而訪問該IP對應的Tomcat,。
3.2 第一次演進:Tomcat與數(shù)據(jù)庫分開部署Tomcat和數(shù)據(jù)庫分別獨占服務器資源,,顯著提高兩者各自性能,。
3.3 第二次演進:引入本地緩存和分布式緩存在Tomcat同服務器上或同JVM中增加本地緩存,,并在外部增加分布式緩存,,緩存熱門商品信息或熱門商品的html頁面等。通過緩存能把絕大多數(shù)請求在讀寫數(shù)據(jù)庫前攔截掉,,大大降低數(shù)據(jù)庫壓力,。其中涉及的技術包括:使用memcached作為本地緩存,使用Redis作為分布式緩存,,還會涉及緩存一致性,、緩存穿透/擊穿、緩存雪崩,、熱點數(shù)據(jù)集中失效等問題,。
3.4 第三次演進:引入反向代理實現(xiàn)負載均衡在多臺服務器上分別部署Tomcat,使用反向代理軟件(Nginx)把請求均勻分發(fā)到每個Tomcat中,。此處假設Tomcat最多支持100個并發(fā),Nginx最多支持50000個并發(fā),,那么理論上Nginx把請求分發(fā)到500個Tomcat上,,就能抗住50000個并發(fā)。其中涉及的技術包括:Nginx,、HAProxy,,兩者都是工作在網(wǎng)絡第七層的反向代理軟件,主要支持http協(xié)議,,還會涉及session共享,、文件上傳下載的問題。
3.5 第四次演進:數(shù)據(jù)庫讀寫分離把數(shù)據(jù)庫劃分為讀庫和寫庫,讀庫可以有多個,,通過同步機制把寫庫的數(shù)據(jù)同步到讀庫,,對于需要查詢最新寫入數(shù)據(jù)場景,可通過在緩存中多寫一份,,通過緩存獲得最新數(shù)據(jù),。其中涉及的技術包括:Mycat,它是數(shù)據(jù)庫中間件,,可通過它來組織數(shù)據(jù)庫的分離讀寫和分庫分表,,客戶端通過它來訪問下層數(shù)據(jù)庫,,還會涉及數(shù)據(jù)同步,數(shù)據(jù)一致性的問題,。
3.6 第五次演進:數(shù)據(jù)庫按業(yè)務分庫把不同業(yè)務的數(shù)據(jù)保存到不同的數(shù)據(jù)庫中,,使業(yè)務之間的資源競爭降低,對于訪問量大的業(yè)務,,可以部署更多的服務器來支撐,。這樣同時導致跨業(yè)務的表無法直接做關聯(lián)分析,需要通過其他途徑來解決,,但這不是本文討論的重點,,有興趣的可以自行搜索解決方案。
3.7 第六次演進:把大表拆分為小表比如針對評論數(shù)據(jù),,可按照商品ID進行hash,路由到對應的表中存儲,;針對支付記錄,,可按照小時創(chuàng)建表,每個小時表繼續(xù)拆分為小表,,使用用戶ID或記錄編號來路由數(shù)據(jù),。只要實時操作的表數(shù)據(jù)量足夠小,請求能夠足夠均勻的分發(fā)到多臺服務器上的小表,,那數(shù)據(jù)庫就能通過水平擴展的方式來提高性能,。其中前面提到的Mycat也支持在大表拆分為小表情況下的訪問控制。 這種做法顯著的增加了數(shù)據(jù)庫運維的難度,,對DBA的要求較高,。數(shù)據(jù)庫設計到這種結構時,已經(jīng)可以稱為分布式數(shù)據(jù)庫,,但是這只是一個邏輯的數(shù)據(jù)庫整體,,數(shù)據(jù)庫里不同的組成部分是由不同的組件單獨來實現(xiàn)的,如分庫分表的管理和請求分發(fā),,由Mycat實現(xiàn),,SQL的解析由單機的數(shù)據(jù)庫實現(xiàn),讀寫分離可能由網(wǎng)關和消息隊列來實現(xiàn),,查詢結果的匯總可能由數(shù)據(jù)庫接口層來實現(xiàn)等等,,這種架構其實是MPP(大規(guī)模并行處理)架構的一類實現(xiàn)。 目前開源和商用都已經(jīng)有不少MPP數(shù)據(jù)庫,,開源中比較流行的有Greenplum,、TiDB,、Postgresql XC、HAWQ等,,商用的如南大通用的GBase,、睿帆科技的雪球DB、華為的LibrA等等,,不同的MPP數(shù)據(jù)庫的側重點也不一樣,,如TiDB更側重于分布式OLTP場景,Greenplum更側重于分布式OLAP場景,,這些MPP數(shù)據(jù)庫基本都提供了類似Postgresql,、Oracle、MySQL那樣的SQL標準支持能力,,能把一個查詢解析為分布式的執(zhí)行計劃分發(fā)到每臺機器上并行執(zhí)行,,最終由數(shù)據(jù)庫本身匯總數(shù)據(jù)進行返回,也提供了諸如權限管理,、分庫分表,、事務、數(shù)據(jù)副本等能力,,并且大多能夠支持100個節(jié)點以上的集群,,大大降低了數(shù)據(jù)庫運維的成本,并且使數(shù)據(jù)庫也能夠?qū)崿F(xiàn)水平擴展,。
3.8 第七次演進:使用LVS或F5來使多個Nginx負載均衡由于瓶頸在Nginx,因此無法通過兩層的Nginx來實現(xiàn)多個Nginx的負載均衡,。圖中的LVS和F5是工作在網(wǎng)絡第四層的負載均衡解決方案,,其中LVS是軟件,運行在操作系統(tǒng)內(nèi)核態(tài),,可對TCP請求或更高層級的網(wǎng)絡協(xié)議進行轉(zhuǎn)發(fā),,因此支持的協(xié)議更豐富,并且性能也遠高于Nginx,,可假設單機的LVS可支持幾十萬個并發(fā)的請求轉(zhuǎn)發(fā),;F5是一種負載均衡硬件,與LVS提供的能力類似,,性能比LVS更高,,但價格昂貴。由于LVS是單機版的軟件,,若LVS所在服務器宕機則會導致整個后端系統(tǒng)都無法訪問,,因此需要有備用節(jié)點,。可使用keepalived軟件模擬出虛擬IP,,然后把虛擬IP綁定到多臺LVS服務器上,,瀏覽器訪問虛擬IP時,會被路由器重定向到真實的LVS服務器,,當主LVS服務器宕機時,,keepalived軟件會自動更新路由器中的路由表,把虛擬IP重定向到另外一臺正常的LVS服務器,,從而達到LVS服務器高可用的效果,。 此處需要注意的是,上圖中從Nginx層到Tomcat層這樣畫并不代表全部Nginx都轉(zhuǎn)發(fā)請求到全部的Tomcat,,在實際使用時,,可能會是幾個Nginx下面接一部分的Tomcat,這些Nginx之間通過keepalived實現(xiàn)高可用,,其他的Nginx接另外的Tomcat,,這樣可接入的Tomcat數(shù)量就能成倍的增加。
3.9 第八次演進:通過DNS輪詢實現(xiàn)機房間的負載均衡在DNS服務器中可配置一個域名對應多個IP地址,,每個IP地址對應到不同的機房里的虛擬IP,。當用戶訪問www.taobao.com時,DNS服務器會使用輪詢策略或其他策略,,來選擇某個IP供用戶訪問,。此方式能實現(xiàn)機房間的負載均衡,至此,,系統(tǒng)可做到機房級別的水平擴展,,千萬級到億級的并發(fā)量都可通過增加機房來解決,系統(tǒng)入口處的請求并發(fā)量不再是問題,。
3.10 第九次演進:引入NoSQL數(shù)據(jù)庫和搜索引擎等技術當數(shù)據(jù)庫中的數(shù)據(jù)多到一定規(guī)模時,,數(shù)據(jù)庫就不適用于復雜的查詢了,往往只能滿足普通查詢的場景。對于統(tǒng)計報表場景,,在數(shù)據(jù)量大時不一定能跑出結果,,而且在跑復雜查詢時會導致其他查詢變慢,對于全文檢索,、可變數(shù)據(jù)結構等場景,,數(shù)據(jù)庫天生不適用。因此需要針對特定的場景,,引入合適的解決方案,。如對于海量文件存儲,可通過分布式文件系統(tǒng)HDFS解決,,對于key value類型的數(shù)據(jù),,可通過HBase和Redis等方案解決,對于全文檢索場景,,可通過搜索引擎如ElasticSearch解決,,對于多維分析場景,可通過Kylin或Druid等方案解決,。 當然,,引入更多組件同時會提高系統(tǒng)的復雜度,不同的組件保存的數(shù)據(jù)需要同步,,需要考慮一致性的問題,,需要有更多的運維手段來管理這些組件等。
3.11 第十次演進:大應用拆分為小應用按照業(yè)務板塊來劃分應用代碼,,使單個應用的職責更清晰,,相互之間可以做到獨立升級迭代。這時候應用之間可能會涉及到一些公共配置,,可以通過分布式配置中心Zookeeper來解決,。
3.12 第十一次演進:復用的功能抽離成微服務如用戶管理、訂單,、支付,、鑒權等功能在多個應用中都存在,那么可以把這些功能的代碼單獨抽取出來形成一個單獨的服務來管理,,這樣的服務就是所謂的微服務,,應用和服務之間通過HTTP、TCP或RPC請求等多種方式來訪問公共服務,,每個單獨的服務都可以由單獨的團隊來管理,。此外,,可以通過Dubbo、SpringCloud等框架實現(xiàn)服務治理,、限流,、熔斷、降級等功能,,提高服務的穩(wěn)定性和可用性,。
3.13 第十二次演進:引入企業(yè)服務總線ESB屏蔽服務接口的訪問差異通過ESB統(tǒng)一進行訪問協(xié)議轉(zhuǎn)換,應用統(tǒng)一通過ESB來訪問后端服務,,服務與服務之間也通過ESB來相互調(diào)用,,以此降低系統(tǒng)的耦合程度。這種單個應用拆分為多個應用,,公共服務單獨抽取出來來管理,,并使用企業(yè)消息總線來解除服務之間耦合問題的架構,就是所謂的SOA(面向服務)架構,,這種架構與微服務架構容易混淆,,因為表現(xiàn)形式十分相似。個人理解,,微服務架構更多是指把系統(tǒng)里的公共服務抽取出來單獨運維管理的思想,,而SOA架構則是指一種拆分服務并使服務接口訪問變得統(tǒng)一的架構思想,SOA架構中包含了微服務的思想,。
3.14 第十三次演進:引入容器化技術實現(xiàn)運行環(huán)境隔離與動態(tài)服務管理目前最流行的容器化技術是Docker,,最流行的容器管理服務是Kubernetes(K8S),應用/服務可以打包為Docker鏡像,通過K8S來動態(tài)分發(fā)和部署鏡像,。Docker鏡像可理解為一個能運行你的應用/服務的最小的操作系統(tǒng),,里面放著應用/服務的運行代碼,運行環(huán)境根據(jù)實際的需要設置好,。把整個“操作系統(tǒng)”打包為一個鏡像后,,就可以分發(fā)到需要部署相關服務的機器上,直接啟動Docker鏡像就可以把服務起起來,,使服務的部署和運維變得簡單,。 在大促的之前,可以在現(xiàn)有的機器集群上劃分出服務器來啟動Docker鏡像,,增強服務的性能,,大促過后就可以關閉鏡像,對機器上的其他服務不造成影響(在3.14節(jié)之前,,服務運行在新增機器上需要修改系統(tǒng)配置來適配服務,,這會導致機器上其他服務需要的運行環(huán)境被破壞)。
3.15 第十四次演進:以云平臺承載系統(tǒng)系統(tǒng)可部署到公有云上,利用公有云的海量機器資源,,解決動態(tài)硬件資源的問題,,在大促的時間段里,在云平臺中臨時申請更多的資源,,結合Docker和K8S來快速部署服務,,在大促結束后釋放資源,真正做到按需付費,,資源利用率大大提高,,同時大大降低了運維成本。 所謂的云平臺,,就是把海量機器資源,,通過統(tǒng)一的資源管理,抽象為一個資源整體,,在之上可按需動態(tài)申請硬件資源(如CPU,、內(nèi)存、網(wǎng)絡等),,并且之上提供通用的操作系統(tǒng),,提供常用的技術組件(如Hadoop技術棧,MPP數(shù)據(jù)庫等)供用戶使用,,甚至提供開發(fā)好的應用,,用戶不需要關系應用內(nèi)部使用了什么技術,就能夠解決需求(如音視頻轉(zhuǎn)碼服務,、郵件服務,、個人博客等)。在云平臺中會涉及如下幾個概念:
4. 架構設計總結
|
|
來自: 壞尐孒95qanplv > 《Java基基-微信收藏》