其實分布式系統的出現和分布式系統面臨的挑戰歸結到最終都是因為使用者數量的急劇增長導致的,隨著使用者數量和活躍使用者數的,應用服務和資料庫服務的併發訪問壓力越來越大,我們不得不進行服務拆分,做資料庫的拆分和讀寫分離。服務拆分之後可以讓我們能對每個服務進行針對性的部署,核心服務得到更好的隔離。
對於服務的拆分,我們可以根據領域驅動設計的思想,將整個系統進行域的劃分,找出我們的核心子域、支撐子域;服務拆分之後面臨的乙個問題是服務之間的呼叫,此時rpc就出現了(當然此前還有webservice等技術),而隨著rpc的出現,又帶來了新的問題,就是服務的治理,例如新的服務上線之後如何讓其他服務發現,服務下線之後如何剔除,服務呼叫超時之後如何進行處理,還有就是服務的效能監控和可用率監控以及相應的報警措施。
同時,有些場景下可能我們不需要同步的呼叫一些服務,只需要非同步通知就可以了,雖然現在的rpc框架也可以實現非同步呼叫,但是當非同步呼叫失敗後還是會影響到通知的準確性,於是就有了訊息佇列。訊息佇列可以讓我們實現服務之間的非同步呼叫,當需要做某乙個通知時,我們只需要往訊息佇列的服務方傳送一條訊息,用乙個消費者去消費這條訊息然後呼叫其他服務即可。同樣每一項技術的引入都會給我們帶來新的問題,訊息佇列的使用使得我們必須得保證訊息的傳送和消費都成功進行,不然就會丟失訊息,造成系統資料的不一致。而如何確保訊息的準確傳送,上篇文章已經說過,要同時保證客戶端傳送和消費訊息都是正常的,服務端接收訊息和持久化訊息也是正常的。
保證訊息不丟之後,我們可能還需要注意訊息的重複消費,為了保證訊息不丟,就一定會出現訊息的重發,這個時候就需要在消費訊息的時候進行冪等處理。同時,我們可能還需要對訊息進行順序消費,對於訊息的順序消費,在傳送訊息的時候可以根據訊息的某個特徵進行路由,將這一類訊息路由到同乙個broker上,保證這類訊息傳送的順序性,而對於訊息消費的順序性則通過控制消費者數量來實現,乙個主題只讓乙個消費者消費即可實現。很顯然這樣的模式讓我們的併發能力顯著降低,總是這麼的矛盾。我們還得保證訊息佇列服務的高可用,針對不同系統的重要性,我們還得設計相應的降級方案,保證在訊息系統不可用時整個系統的可用。
對於查詢服務,可能每次查詢到的結果都是一樣的,在這種場景下我們不需要每次都去查詢資料庫,而是可以將結果快取起來,每次查詢從快取獲取,減輕資料庫的壓力。快取的實現可以是jvm快取,或者專業的快取資料庫,例如redis;由於直接操作記憶體,加上自身良好的設計,redis可以支撐很大的併發,如果搭建redis集群,則可以扛住更大的併發。同樣快取資料庫的引入也給我們帶來了問題,例如常見的快取穿透、快取擊穿、快取雪崩、熱點key、大key等。熱點key的問題,微博就經常遇到,在某個時間點,某個熱點話題關聯的key的訪問量劇增,導致快取伺服器的連線打滿,使得其他的請求只能去查詢資料庫,資料庫扛不住併發的壓力直接宕機,導致服務不可用。對於熱點key的問題,不可能常年備著很多機器,就為了那乙個不知道什麼時候發生的點。我們可以通過大資料統計的技術提前預知熱點key,然後提前觸發服務的降級策略,最暴力的就是直接拒絕訪問,或者溫柔點,提前加上jvm快取,利用雙快取來進行處理。
而對於大key,我們都知道redis在處理客戶端的請求時時單執行緒的,基於io多路復用技術,實現了高效能的併發訪問。但是這樣也存在乙個很嚴重的問題,當某個客戶端的操作耗時很久時,此時會有大量的請求阻塞,嚴重可能導致快取不可用,服務雪崩。對於大key,我們的基本思想是進行拆分,讓每個key盡量的小,而且將key進行拆分之後還能進行分流,提高效能。
除了上述問題之外,redis本身也得實現乙個高可用的架構,例如redis的哨兵和集群等。
對於寫服務,多個服務之間的呼叫又會涉及到分布式事務的問題。
使用者數量帶來的另乙個問題就是海量資料的處理,例如電商平台,隨著使用者數量的劇增,每天的訂單量都會很大,基本都會有幾百萬到千萬的訂單產生。如果我們使用mysql進行儲存,我們知道mysql單錶的資料量最好是控制在200-500萬左右,這樣基本一天就會寫滿一張表,這對資料庫來說壓力是非常大的。對於海量資料的儲存,我們的基本思想就是進行拆分,一張表放不下,就用多張表,乙個庫放不下就用多個庫,乙個機器放不下,就用多台機器。也就是我們常說的分庫分表的技術,假設我們現在資料每日的增長在1000萬左右,我們可以使用16個資料庫,每個庫設定32張表,,這樣落到每張表上的單日資料增長也才兩萬左右,單表達到效能瓶頸也需要將近一年的時間。當達到瓶頸後我們還可以再擴庫,繼續分擔資料庫壓力。而為了保證資料不丟失、防止單點故障,我們還會做資料庫的主從架構,防止一台資料庫伺服器宕機後,部分資料的丟失導致的服務不可用。
分布式 分布式系統的設計
在計算機領域,當單機效能達到瓶頸時,一般有兩種方式解決效能問題 而分布式系統的設計說白了就是 如何合理將乙個系統拆分成多個子系統部署到不同機器上。講設計方法前,先介紹分布式系統的特性 1 分布性 空間中隨機分布。這些計算機可以分布在不同的機房,不同的城市,甚至不同的國家。2 對等性 分布式系統中的計...
分布式系統設計準則
該文章需要整理 2015.3.13修改 分布式系統通常服務大請求 維護著大資料 快速響應 長時間可用。設計分布式後台服務需要考慮的東西很多,本文給出一些常用的設計準則,以備檢視。效能 快速響應 低延遲 可靠性 系統可靠就是同樣的請求返回同樣的資料 更新能夠持久化 資料不會丟失 可管理性 便於運維,整...
分布式系統唯一ID設計
目錄 1 概述 2 分布式唯一id特點 3 分布式唯一id傳統方案 3.1 uuid 3.2 資料庫生成 3.3 redis生成id 3.4 利用zookeeper生成唯一id 3.5 snowflake 雪花演算法 方案 在複雜分布式系統中,往往需要對大量的資料和訊息進行唯一標識。如在金融 電商 ...