1. 程式人生 > 其它 >im即時通訊開發技術:100到1000萬高併發的架構演進

im即時通訊開發技術:100到1000萬高併發的架構演進

在介紹架構之前,為了避免部分讀者對架構設計中的一些概念不瞭解,下面對幾個最基礎的概念進行介紹。

1)什麼是分散式?

系統中的多個模組在不同伺服器上部署,即可稱為分散式系統,如Tomcat和資料庫分別部署在不同的伺服器上,或兩個相同功能的Tomcat分別部署在不同伺服器上。

2)什麼是高可用?

系統中部分節點失效時,其他節點能夠接替它繼續提供服務,則可認為系統具有高可用性。

3)什麼是叢集?

一個特定領域的軟體部署在多臺伺服器上並作為一個整體提供一類服務,這個整體稱為叢集。

如Zookeeper中的Master和Slave分別部署在多臺伺服器上,共同組成一個整體提供集中配置服務。

在常見的叢集中,客戶端往往能夠連線任意一個節點獲得服務,並且當叢集中一個節點掉線時,其他節點往往能夠自動的接替它繼續提供服務,這時候說明叢集具有高可用性。

即時通訊開發

4)什麼是負載均衡?

請求傳送到系統時,通過某些方式把請求均勻分發到多個節點上,使系統中每個節點能夠均勻的處理請求負載,則可認為系統是負載均衡的。

 

5)什麼是正向代理和反向代理?

系統內部要訪問外部網路時,統一通過一個代理伺服器把請求轉發出去,在外部網路看來就是代理伺服器發起的訪問,此時代理伺服器實現的是正向代理;

當外部請求進入系統時,代理伺服器把該請求轉發到系統中的某臺伺服器上,對外部請求來說,與之互動的只有代理伺服器,此時代理伺服器實現的是反向代理。

簡單來說,正向代理是代理伺服器代替系統內部來訪問外部網路的過程,反向代理是外部請求訪問系統時通過代理伺服器轉發到內部伺服器的過程。

以淘寶作為例子:在網站最初時,應用數量與使用者數都較少,可以把Tomcat和資料庫部署在同一臺伺服器上。瀏覽器往發起請求時,首先經過DNS伺服器(域名系統)把域名轉換為實際IP地址10.102.4.1,瀏覽器轉而訪問該IP對應的Tomcat。

架構瓶頸:隨著使用者數的增長,Tomcat和資料庫之間競爭資源,單機效能不足以支撐業務。

第一次演進:Tomcat與資料庫分開部署

Tomcat和資料庫分別獨佔伺服器資源,顯著提高兩者各自效能。

架構瓶頸:隨著使用者數的增長,併發讀寫資料庫成為瓶頸。

第二次演進:引入本地快取和分散式快取

在Tomcat同伺服器上或同JVM中增加本地快取,並在外部增加分散式快取,快取熱門商品資訊或熱門商品的html頁面等。通過快取能把絕大多數請求在讀寫資料庫前攔截掉,大大降低資料庫壓力。其中涉及的技術包括:使用memcached作為本地快取,使用Redis作為分散式快取,還會涉及快取一致性、快取穿透/擊穿、快取雪崩、熱點資料集中失效等問題。

架構瓶頸:快取抗住了大部分的訪問請求,隨著使用者數的增長,併發壓力主要落在單機的Tomcat上,響應逐漸變慢。

第三次演進:引入反向代理實現負載均衡

在多臺伺服器上分別部署Tomcat,使用反向代理軟體(Nginx)把請求均勻分發到每個Tomcat中。此處假設Tomcat最多支援100個併發,Nginx最多支援50000個併發,那麼理論上Nginx把請求分發到500個Tomcat上,就能抗住50000個併發。

其中涉及的技術包括:Nginx、HAProxy,兩者都是工作在網路第七層的反向代理軟體,主要支援http協議,還會涉及session共享、檔案上傳下載的問題。

架構瓶頸:反向代理使應用伺服器可支援的併發量大大增加,但併發量的增長也意味著更多請求穿透到資料庫,單機的資料庫最終成為瓶頸。

第四次演進:資料庫讀寫分離

把資料庫劃分為讀庫和寫庫,讀庫可以有多個,通過同步機制把寫庫的資料同步到讀庫,對於需要查詢最新寫入資料場景,可通過在快取中多寫一份,通過快取獲得最新資料。其中涉及的技術包括:Mycat,它是資料庫中介軟體,可通過它來組織資料庫的分離讀寫和分庫分表,客戶端通過它來訪問下層資料庫,還會涉及資料同步,資料一致性的問題。

架構瓶頸:業務逐漸變多,不同業務之間的訪問量差距較大,不同業務直接競爭資料庫,相互影響效能。

 

第五次演進:資料庫按業務分庫

把不同業務的資料儲存到不同的資料庫中,使業務之間的資源競爭降低,對於訪問量大的業務,可以部署更多的伺服器來支撐。這樣同時導致跨業務的表無法直接做關聯分析,需要通過其他途徑來解決,但這不是本文討論的重點,有興趣的可以自行搜尋解決方案。

架構瓶頸:隨著使用者數的增長,單機的寫庫會逐漸會達到效能瓶頸。

第六次演進:把大表拆分為小表

比如針對評論資料,可按照商品ID進行hash,路由到對應的表中儲存;針對支付記錄,可按照小時建立表,每個小時表繼續拆分為小表,使用使用者ID或記錄編號來路由資料。只要實時操作的表資料量足夠小,請求能夠足夠均勻的分發到多臺伺服器上的小表,那資料庫就能通過水平擴充套件的方式來提高效能。其中前面提到的Mycat也支援在大表拆分為小表情況下的訪問控制。

這種做法顯著的增加了資料庫運維的難度,對DBA的要求較高。資料庫設計到這種結構時,已經可以稱為分散式資料庫,但是這只是一個邏輯的資料庫整體,資料庫裡不同的組成部分是由不同的元件單獨來實現的,如分庫分表的管理和請求分發,由Mycat實現,SQL的解析由單機的資料庫實現,讀寫分離可能由閘道器和訊息佇列來實現,查詢結果的彙總可能由資料庫介面層來實現等等,這種架構其實是MPP(大規模並行處理)架構的一類實現。

目前開源和商用都已經有不少MPP資料庫,開源中比較流行的有Greenplum、TiDB、Postgresql XC、HAWQ等,商用的如南大通用的GBase、睿帆科技的雪球DB、華為的LibrA等等,不同的MPP資料庫的側重點也不一樣,如TiDB更側重於分散式OLTP場景,Greenplum更側重於分散式OLAP場景,這些MPP資料庫基本都提供了類似Postgresql、Oracle、MySQL那樣的SQL標準支援能力,能把一個查詢解析為分散式的執行計劃分發到每臺機器上並行執行,最終由資料庫本身彙總資料進行返回,也提供了諸如許可權管理、分庫分表、事務、資料副本等能力,並且大多能夠支援100個節點以上的叢集,大大降低了資料庫運維的成本,並且使資料庫也能夠實現水平擴充套件。

架構瓶頸:資料庫和Tomcat都能夠水平擴充套件,可支撐的併發大幅提高,隨著使用者數的增長,最終單機的Nginx會成為瓶頸。

 

第七次演進:使用LVS或F5來使多個Nginx負載均衡

由於瓶頸在Nginx,因此無法通過兩層的Nginx來實現多個Nginx的負載均衡。圖中的LVS和F5是工作在網路第四層的負載均衡解決方案,其中LVS是軟體,執行在作業系統核心態,可對TCP請求或更高層級的網路協議進行轉發,因此支援的協議更豐富,並且效能也遠高於Nginx,可假設單機的LVS可支援幾十萬個併發的請求轉發;F5是一種負載均衡硬體,與LVS提供的能力類似,效能比LVS更高,但價格昂貴。由於LVS是單機版的軟體,若LVS所在伺服器宕機則會導致整個後端系統都無法訪問,因此需要有備用節點。可使用keepalived軟體模擬出虛擬IP,然後把虛擬IP繫結到多臺LVS伺服器上,瀏覽器訪問虛擬IP時,會被路由器重定向到真實的LVS伺服器,當主LVS伺服器宕機時,keepalived軟體會自動更新路由器中的路由表,把虛擬IP重定向到另外一臺正常的LVS伺服器,從而達到LVS伺服器高可用的效果。

此處需要注意的是,上圖中從Nginx層到Tomcat層這樣畫並不代表全部Nginx都轉發請求到全部的Tomcat,在實際使用時,可能會是幾個Nginx下面接一部分的Tomcat,這些Nginx之間通過keepalived實現高可用,其他的Nginx接另外的Tomcat,這樣可接入的Tomcat數量就能成倍的增加。

架構瓶頸:由於LVS也是單機的,隨著併發數增長到幾十萬時,LVS伺服器最終會達到瓶頸,此時使用者數達到千萬甚至上億級別,使用者分佈在不同的地區,與伺服器機房距離不同,導致了訪問的延遲會明顯不同。