1. 程式人生 > >All-In-One到SOA的分散式架構演進

All-In-One到SOA的分散式架構演進

曾經架構在我以前看來,多麼高大上的詞啊,可望不可及; 

在看了很久分散式的文章、書籍和架構後試著總結了一番;

此文的應用場景是超大使用者系統的發展程序;

下面大家就聽我娓娓道來吧~

最開始的應用是單一的應用,入下圖;

1、單一應用


在誕生之初始,應用與資料庫是部署在同一臺機器上,這時的使用者量、資料量規模都比較小,這樣的架構既簡單實用、便於維護,成本又低,成為了這個時代的主流架構方式。隨著使用者量的增大,訪問量急劇增加;於是到了下一步;

2、垂直應用

配置三臺伺服器,一個應用伺服器,一臺DB伺服器,一臺檔案伺服器;

垂直型應用架構,是指將一個大的單一應用拆分成若干個小的單一應用,這樣每個應用的壓力大約有原來的1/n(粗略估計值)。這種拆分方式為後來的技 術發展奠定了基礎,每次架構的變化都與這次有著密不可分的關係——分治(將一個大的問題按一定業務規則分成若干個小的問題,逐個解決)。


一臺檔案伺服器掛了但還是能訪問應用和資料庫的; 這樣將應用分成不同的業務,可以提升訪問效率;

這時我們發現有很多業務的訪問,非常集中;即2 8原則,80%的業務集中在20%的資料上,於是我們可以使用快取技術講這20%的資料快取下來,效能一下子就上來了;快取又分為兩種,一種是本地快取(Local Cache),一種是遠端快取(Remote Distributed Cache);遠端快取又分為單機快取和分散式快取;


這時我們使用了快取的技術,效能的瓶頸來到了伺服器,單臺再強大的伺服器也不行了,於是我們使用了伺服器叢集


通過Nginx的反向代理,通過負載均衡的排程,可以在一定程度上解決伺服器處理能力的瓶頸;

負載均衡的策略有:

   輪詢每一次來自網路的請求輪流分配給內部中的伺服器,從1至N然後重新開始。此種均衡演算法適合於伺服器組中的所有伺服器都有相同   的軟硬體配置並且平均服務請求相對均衡的情況。實現簡單,但存在伺服器的處理能力不同的情況;

   權重根據伺服器的不同處理能力,給每個伺服器分配不同的權值,使其能夠接受相應權值數的服務請求。例如:伺服器A的權值被設計   成1,B的權值是3,C的權值是6,則伺服器A、B、C將分別接受到10%、30%、60%的服務請求。此種均衡演算法能確保高效能的服務          器得到更多的使用率,避免低效能的伺服器負載過重。考慮了伺服器處理能力的不足;

  隨機均衡:把來自網路的請求隨機分配給內部中的多個伺服器。

  地址雜湊:又分為原IP地址雜湊,目標IP地址雜湊; 針對目標IP地址的負載均衡,但它是一種靜態對映演算法,通過一個雜湊(Hash)函式   將一個目標IP地址對映到一臺伺服器。

還有基於以上幾種延伸出來的策略,比如:  

 最小連線:可以使叢集中的伺服器負載得更均勻;

  權重最小連線客戶端的每一次請求服務在伺服器停留的時間可能會有較大的差異,隨著工作時間加長,如果採用簡單的輪循或隨機均衡   演算法,每一臺伺服器上的連線程序可能會產生極大的不同,並沒有達到真正的負載均衡。最少連線數均衡演算法對內部中需負載的每一臺服   務器都有一個數據記錄,記錄當前該伺服器正在處理的連線數量,當有新的服務連線請求時,將把當前請求分配給連線數最少的伺服器,  使均衡更加符合實際情況,負載更加均衡。此種均衡演算法適合長時處理的請求服務,如FTP。

伺服器是做叢集了,系統的效能是得到優化了,但是問題又來了;seesion如何管理?

假設一個使用者登入了A伺服器,session資訊儲存到了A伺服器上了,假設我們使用的負載均衡策略是用的地址雜湊,根據ip進行hash雜湊;可以保證使用者的登入資訊在A伺服器上訪問到,但是某些特殊情況,可能存在同一臺伺服器被雜湊到了巨多的請求壓力過大,某些伺服器又沒有什麼壓力這時效能瓶頸又來了~

那麼我們用輪詢或者最小連線的負載均衡策略好了;使用者登入了A伺服器,session資訊儲存到了A伺服器上,但第二次訪問的時候呢,訪問的是B伺服器,這時存貯在A伺服器上的session資訊,我們在B伺服器上是讀取不到的;這時候我們就要解決session管理的問題了;  


Browser1 訪問應用時,它的seesionID 可能一開始是存在  伺服器A上的,如果這個A伺服器掛掉了,Browser1又要去訪問伺服器2,而伺服器二又是沒有使用者Browser1的seesionID;這時的解決方案是:Browser1經過Nginx把session存到A伺服器上時,會把Browser1的seesion複製到B伺服器上;也就是這兩個伺服器都保持著Browser1的sessionID;

好的,這個時候session共享的問題解決了,但新問題又出來了,A伺服器跟B伺服器之間要不斷的同步session資訊,當大量的使用者都線上的時候,伺服器之間佔用的記憶體會過多,不適合做大規模的叢集,只適合一些機器不多的情況; 不要著急,解決方案還是有的:那就是使用Cookie;


大家應該都知道session和cookie的區別吧,這裡就不做過多的介紹了;

我們讓攜帶著session資訊的cookie去訪問我們的應用伺服器,這種方式解決了session共享的問題,但是問題又來了.......

cookie的長度是有限制的,cookie是儲存在瀏覽器上的,安全性也是一個問題; 怎麼辦呢....

我們可以增加一個seesion的伺服器;


這樣,使用者的請求路徑就變成了,Browser1通過Nginx請求到A伺服器,然後把Browser1的session存到session伺服器中,當想獲取使用者的seesion的時候,往session伺服器裡拿就是的了; 把所有的session 都放到session伺服器當中就解決 了這個問題; 但此時session伺服器又是單點的,為了保證可用性,在使用者量大的時候,可以將session伺服器做成叢集;

好的,關於session的問題又解決了;但問題又來了!!!

一個龐大的系統畢竟是給大量的使用者使用的,隨著使用者量的增加,系統的升級再所難免,這時的瓶頸不在伺服器的處理上,不在負載均衡的策略上,不在快取技術上了,而是在資料庫上了;


如果是上面這個架構圖,我們的讀與寫的操作,都要經過同一個資料庫伺服器,在大量使用者訪問的情況下,資料庫的併發量有限,為了保證資料的四大特性難免會發生阻塞;我們可以將資料庫進行讀寫分離,來保證資料庫的高可用性;

寫的操作放在主庫,讀的操作方在從庫;於是就有了下面這個圖;

Master是主庫,Slave是從庫,所有的寫操作將引入主庫,讀操作引入從庫;極大程度的緩解資料庫鎖之間的競爭;提高了併發吞吐和負載能力。

資料庫的問題暫時解決了;以後還會有還有新的問題嗎?還會有的~如何提高不同地區的訪問速度?應用伺服器增加了叢集,資料庫伺服器也讀寫分離了,但檔案伺服器呢??於是有了下面這個架構圖;


使用CDN可以很好的解決不同的地區訪問速度的問題,又把檔案伺服器改成了叢集的形式;在使用分散式檔案系統的時候又有問題了...

1、如何不影響已經部署在線上的業務訪問,不能讓某個圖片突然就訪問不到了;

2、是否需要備份伺服器?

3、是否要重新做域名解析?

這一塊的問題待補充吧.... 因為我還沒有把那個分散式檔案儲存系統的書看完。。以後會補充好的吐舌頭

這是資料庫又他瞄的出問題了,讀寫分離還是慢啊,怎麼辦?我們使用專庫專用的方式來進行資料的垂直拆分;


不同的業務,使用自己的庫,這樣,讀寫資料,併發量上不去的問題問題就都解決了;但是每個業務用的資料庫都不一樣又會有哪些新問題的?

1、跨業務的事務,跨庫的事務;   可以用分散式事務來解決

2、隨著業務使用者群體的不斷變大,某單個數據庫又會成為效能的瓶頸;這時我們又要將單個數據進行水平拆分;架構圖如下,只是把users庫分為users1、users2;  這是不是和開始的All in one 到垂直拆分類似了? 


在水平拆分後,又會有sql路由的問題,假設我們有一個使用者,他的資訊是存在了users1當中還是user2當中了呢?

同時還有出現分頁的問題;假設有這麼個需求,讓我們查詢2016年雙11有多少使用者在淘寶下過單,這些使用者存在不同的資料庫中,後臺的運營管理系統如何進行展示呢?分頁也是一個問題。

寫了這麼多,大家可以看到,大型系統架構的演進過程中有非常多的問題;但是遇到問題的解決思路肯定會是類似這個樣子的;

那麼我們可以理解解決高效能問題,可以將單一的應用垂直拆分成幾個不同的業務去劃分;

解決高可用的問題,我們可以將單點的伺服器做成叢集;比如上圖,如果負載均衡的伺服器掛了,後面一系列的應用伺服器叢集是不是都沒辦法用了?

解決高併發的問題,以後再說哈~~

公司的業務需求不同,效能需求也不同;上面的這個架構圖可能也不是最後的形態;我想每個公司的業務不同,架構肯定也是不同的;

這漫長的演變過程中還有系統的安全性,資料分析,監控,反作弊等問題需要解決;

最後的SOA架構,微服務化,訊息佇列,任務排程,多機房部署這些名詞我也緊緊只有淺薄的瞭解;

知識越學越多,想到淘寶的系統得多麼的龐大才能支撐起上億的併發量。想想就覺得恐怖,大神們太牛逼了;

同樣的,任何網站的架構都是從小做起的,學習也是,希望菜鳥幾年後也能成長起來~~奮鬥

上面只是對分散式系統架構的演進進行了介紹,並沒有介紹當前流行的一些分散式技術如何在當中使用;以後會娓娓道來......靜待.......