細談八種架構涉及模式及其優缺點概述

1、什麼是架構面試

我想這個問題,十我的回答得有十一個答案,由於另外的那一個是你們妥協的結果,哈哈,我理解,架構就是骨架,以下圖所示:sql

 

 人類的身體的支撐是主要由骨架來承擔的,而後是其上面的肌肉、神經、皮膚。架構對於軟件的重要性不亞於骨架對人類身體的重要性。docker

2、什麼是設計模式數據庫

這個問題我問過的面試者不下數十次,回答五花八門,在我看來,模式就是經驗,涉及模式就是涉及經驗,有了這些經驗,咱們就能在特定狀況下使用特定的設計、組合設計。這樣能夠大大節省咱們的設計時間,提升工做效率。後端

做爲一個老碼農,經理的系統架構設計也不算少,接下來,我會把工做中用到的一些架構方面的設計模式分享給你們,望你們少走彎路。整體而言,有八種,分別是:設計模式

一、單庫單應用模式:最簡單的,可能你們都見過瀏覽器

二、內容分發模式:目前用的比較多緩存

三、查詢分類模式:對於大併發的查詢、業務。服務器

四、微服務模式:適用於複雜的業務模式的拆解網絡

五、多級緩存模式:能夠把緩存玩的很好

六、分庫分表模式:解決單及數據庫瓶頸

七、彈性伸縮模式:解決波峯波谷業務的流量不均勻的方法之一

八、多機房模式:解決高可用、高性能的一種方法

3、單庫單應用模式

這是最簡單的一種設計模式,咱們的大部分本科畢業設計、一些小的應用,基本上都是這種模式,這種模式的通常設計見下圖:

 

 如上圖所示,這種模式通常只有一個數據庫,一個業務應用層,一個後臺管理系統,全部的業務都是用業務層完成的,全部的數據也都是存儲在一個數據庫中,好一點會由數據庫的同步,雖然簡單,可是也並非一無可取。

優勢:結構簡單、開發速度快、實現簡單,可用於產品的初版等有原型驗證需求。

缺點:性能差、基本沒有高可用、擴展性查,不適合用於大規模部署、應用等生產環境。

4、內容分發模式

基本上全部的大型的網站都有或多或少的採用這一種設計模式,常見的應用場景是採用CDN技術把網頁、圖片、CSS、JS等這些靜態資源分發到離用戶最近的服務器,這種模式的通常設計見下圖:

 

 如上圖所示,這種模式較單庫單應用的模式多了一個CDN、一個雲存儲OSS(七牛、又拍等雷同)。一個經典的應用流程(以用戶上傳、查看圖片需求爲例以下:)

一、上傳的時候,用戶選擇本地機器上的一個圖片進行上傳

二、程序會把這個圖片上傳到雲存儲OSS上,並返回該圖片的一個URL

三、程序把這個URL字符串存儲在業務數據庫中,上傳完成

四、查看的時候,程序從業務數據庫獲得該圖片的URL

五、程序經過DNS查詢到這個URL的圖片服務器

六、智能DNS會解析這個URL,獲得於用戶最近的服務器(或集羣)的地址A

七、而後把服務器A上的圖片返回給程序

八、程序顯示該圖片,查看完成

由上可知,這個模式的關鍵是智能DNS,他可以解析出離用戶最近的服務器,運行原理大體是:根據請求者的IP獲得請求地點B,而後經過計算或者配置獲得與B最近或通信時間最短的服務器C,而後把C的IP地址返回給請求者。這種模式的優缺點以下:

優勢:資源下載快,無需過多的開發與配置,同時也減輕了後端服務器對資源的存儲壓力,減小帶寬的使用。

缺點:目前來講OSS、CDN的加個仍是稍微優勢貴的,只適用於中小規模的應用,另外因爲網絡傳輸延遲、CDN的同步策略等,會有一些一致性、更新慢方面的問題。

5、查詢分離模式

這種模式主要解決單及數據庫壓力過大,從而致使業務緩慢甚至超時,查詢影響時間變長的問題,也包括須要大量數據庫服務器計算資源的查詢請求,這個能夠說是單庫應用模式的升級版本,也是技術架構迭代演進過程當中的必經之路。

這種模式的通常設計以下圖:

 

 如上圖所示,這種模式較單庫但應用模式與內容分發模式多了幾個部分,一個是業務數據庫的主從分離,一個是引入ES,爲何要這樣?都解決的哪些痛點,下面具體結合業務需求場景進行敘述。

 場景一:全文關鍵詞檢索

我想這個需求,絕大多數應用都會有,若是使用傳統的數據庫技術,大部分可能會使用like這種sql語句,高級一點的是先分詞,而後通分詞index相關的記錄。sql語句的性能問題與全表掃描機制致使了很是嚴重的性能問題,如今基本上不多見到。

ES較Solr配置簡單、使用方便,因此這裏選用了他。另外,ES支持橫向擴展,理論上沒有性能的瓶頸。同時,還支持各類插件、自定義分詞器等,可擴展性較強。在這裏,使用ES不只能夠替代數據庫完成全檢索功能,還能夠實現諸如分頁、排序、分組、分面等功能。具體的,請同窗們自行學習之,那怎麼使用呢?一個通常的流程是這樣的:

一、服務端把一條業務數據落庫

二、服務器異步把該條數據發送到ES

三、ES把該條記錄按照規則、配置放入本身的索引庫

四、客戶端查詢的時候,由服務端把這個請求發送到ES,獲得數據後,根據需求拼裝、組合數據,返回給客戶端

實際中怎麼用,還請同窗們根據實際狀況作組合、取捨

場景二:大量的普通查詢

這個場景是指咱們的業務中的大部分輔助性的查詢,如:取錢的時候先查詢一下餘額,根據用戶的ID查詢用戶的記錄,取得該用戶最新的一條取錢記錄等,咱們確定是要每天用到的,並且用的還很是多。同時呢,咱們的寫入請求也是很是多的,致使大量的寫入、查詢操做壓向同一數據庫,而後,數據庫掛了,系統掛了,領導生氣了,被開除了,還不起房貸了,露宿街頭了,老婆跟別人跑了……

不敢想,因此要求咱們必須分散數據庫的壓力,一個業界較成熟的方案就是數據庫的讀寫分離,寫的時候入主庫,讀的時候讀分庫。這樣就把壓力分散到不一樣的數據庫了,若是一個讀庫性能不行,扛不住的話,能夠一主多從,橫向擴展,可謂是一劑良藥啊!那麼怎麼使用呢?一個通常的流程是這樣的:

一、服務端把一條數據落庫

二、數據庫同步或異步或半同步把這條數據複製到從庫

三、服務端讀取數據的時候直接去從庫讀相應的數據

比較簡單吧,一些聰明的、愛思考的、上進的同窗可能發現問題了,也包括上面介紹的場景一,就是延遲問題,如:數據還沒到從庫,我就立刻讀,那麼是讀不到的,會發生問題的。對於這個問題,各家公司解決的思路也是不同的,方法不盡相同,一個廣泛的解決方案是:讀不到就讀主庫,固然這麼說也是有前提條件的,但具體的方案就不在這裏一一展開了,我可能會在接下來的分享中詳解各類方案。

另外,關於數據庫複製模式,還請同窗們自行學習,太多了,這裏說不清,該總結一下這種模式的優缺點了,以下:

優勢:減小數據庫的壓力,理論上提供無限高的讀性能,簡介提升業務(寫)的性能,專用的查詢、索引、全文(分詞)解決方案。

缺點:數據延遲,數據一致性的保證。

6、微服務模式

上面的模式看似不錯,解決了性能問題,我能夠不用魯肅街頭了、老婆仍是個人,哈哈,可是軟件系統天生的複雜性決定了,出了性能,還有其餘諸如高可用、健壯性等大量問題等待咱們去解決,在加上各個部門的撕逼、扯皮,更讓咱們碼農雪上加霜,因此,繼續吧……

微服務模式能夠說是最近的熱點,花花綠綠、大大小小、國內國外的公司都在鼓吹,實踐這個模式,但是大部分都沒有弄清爲何要這麼作,也並不知道這麼作有什麼好處、壞處,在這裏,我將以我本身的親身實踐說一下我對這個模式的見解,不喜勿噴,隨着業務與人員的增長,遇到的問題以下:

一、單及數據庫寫請求量大量增長,致使數據庫壓力變大

二、數據庫一旦掛了,那麼整個業務都掛了

三、業務代碼愈來愈多,都在一個GIT裏,愈來愈難以維護

四、代碼腐化嚴重,臭味愈來愈濃

五、上線愈來愈頻繁,常常是一個小功能的修改,就要整個大項目從新編譯

六、部門愈來愈多,該哪一個部門改動大項目中的哪一個東西,撕逼的厲害

七、其餘一些外圍系統直接連數據庫,致使一旦數據庫結構發生變化,全部的相關係統都要通知,甚至對修改不敏感的系統也要通知

八、每一個應用服務器須要開通全部權限、網絡、FTP、各類各樣的,由於每一個服務器部署的應用都是同樣的。

九、做爲架構師,我已經屎去了對這個系統的把控……

爲了解決上述問題,我司使用了微服務模式,這種模式的通常設計以下圖:

 

 如上圖所示,我把業務分塊,作了垂直切分,切成一個個獨立的系統,每一個系統各子衍化,有本身的庫、緩存、ES等輔助系統,系統之間的實時交互經過RPC,異步交互經過MQ,經過這種組合,共同完成整個系統功能。

那麼,這麼作是否真的能解決上述問題了呢?不玩虛的,一個一個來講。

對於問題一,因爲拆分紅多個子系統,系統的壓力被分散了,而各個子系統都有本身的數據庫實例,因此數據庫的壓力變小。

對於問題二,一個子系統A的數據庫掛了,只是影響到系統A和使用系統A的那些功能,不會全部的功能不可用,從而解決一個數據庫掛了,致使全部的功能都不可用的狀況。

對於問題三、四,也由於拆分獲得了解決,各個子系統都有本身獨立的GIT代碼庫,不會相互影響。通用的模塊可經過庫、服務、平臺的形式解決。

對於問題五,子系統A發生改變,須要上線,那麼咱們只須要編譯A,而後上線就能夠了,不須要其餘系統作通向的事情。

對於問題六,順應了康威定律,我部門該幹什麼事,輸出什麼,也經過服務的形式暴露出來,我部門只管把我部的職責、軟件功能作好就能夠。

對於問題七,全部須要我部數據的需求,都經過接口的形式發不出去,客戶經過接口獲取數據,從而屏蔽了底層數據庫結構,甚至數據來源,我部只需保證我部的接口契約沒有發生變化便可,新的需求增長新的接口,不會影響老的接口。

對於問題八,不一樣的子系統須要不一樣的權限,這個問題也優雅的解決了。

對於問題九,暫時控制住複雜性,我只須要控制好大方面,定義好系統邊界、接口、大的流程,而後再分而治之、逐個擊破、合縱連橫。

目前來講,全部問題獲得解決!bingo!

可是,還有許多其餘的反作用會隨之產生,如RPC、MQ的超高穩定性、超高性能,網絡延遲,數據一致性等問題,這個就不展開來說了,太多了,一本書都講不完。

另外,對於這個模式來講,最難把握的是度,切記不要切分過細,我見過一個功能一個子系統,上百個方法分紅上百個子系統的,真的是太過分了。實踐中,一個比較可行的方法是:能不分就不分,除非有很是必要的理由!

優勢:相對高性能,可擴展性強,高可用,適用於中等以上規模公司架構。

缺點:複雜、度很差把握。指不只須要一個能再高層把控大方向、大流程、整體技術的人,還須要可以針對各個子系統有針對性的開發。把握很差度或者濫用的話,這個模式拔苗助長!

 7、多級緩存模式

這個模式能夠說是應對超高查詢壓力的一種廣泛採用的策略,基本的思想就是再全部鏈路的地方,能加緩存的就加緩存,以下圖所示:

 

 如上圖所示,通常在三個地方加入緩存,一個是客戶端處,一個是API網關處,一個是具體的後端業務處,下面分別介紹:

 客戶端處緩存:這個地方加緩存能夠說是效果最好的一個——無延遲。由於不用通過長長的網絡鏈條去後端業務處獲取數據,從而致使加載時間過長,客戶流失等損失,雖然有CDN的支持,可是從客戶端到CDN仍是有網絡延遲的,雖然不大,具體的技術依據不一樣的客戶端而定,對於WEB來說,有瀏覽器本地緩存、Cookie、Storage、緩存策略等技術;對於APP來說,有本地數據庫,本地文件,本地內存,進程內緩存支持,以上提到的各類技術有興趣的同窗能夠繼續展開學習,若是客戶端緩存沒有命中,那麼會去後端業務拿數據,通常來說,就會有個API網關,在這裏加緩存也是很是重要的。

後端業務處理:這個我就不用多說了,你們應該差很少都知道,什麼Redis、Memcache、Jvm等等,不贅述了。

實踐中,要結合具體的實際狀況,綜合利用各級緩存技術,使得各類請求最大程度的在到達後端業務以前就被解決掉,從而減小後端服務器壓力、減小佔用帶寬、加強用戶體驗。至因而否只有這三個地方加緩存,我以爲要活學活用,心法比劍法重要!總結一下這個模式的優缺點:

優勢:抗住大量讀請求,減小後端壓力。

缺點:數據一致性問題較爲突出,容易發生雪崩,即:若是客戶端緩存失效、API網關緩存失效,那麼全部的大量請求瞬間壓向後端業務系統,後果可想而知。

8、分庫分表模式

這種模式主要解決單表寫入、讀取 、存儲壓力過大,從而致使業務緩慢甚至超時,交易失敗,容量不夠的問題。通常有水平切分和垂直切分兩種,這裏主要介紹水平切分。這個模式也是技術架構迭代演進的畢竟之路。

這種模式的通常設計見下圖:

 

 如上圖所示紅色部分,把一張表分到了幾個不一樣的庫中,從而分擔壓力。是否是很籠統?哈哈,那咱們接下來就詳細的講解一下,首先澄清幾個概念,以下:

主機:硬件,指一臺物理機,或虛擬機,有本身的CPU,內存,硬盤等。

實例:數據庫實例,如一個MySql服務進程,一個主機能夠有多個實例,不一樣的實例有不一樣的進程,監聽不一樣的端口。

庫:指表的集合,如學校庫,可能包含教師表、學生表、食堂表等等,這些表在一個庫中。一個實例中能夠有多個庫,庫與庫之間用庫名來區分。

表:庫中的表,沒必要多說,不懂的就不用往下看了,不解釋。

那麼怎麼把單表分散呢?到底怎麼個分發呢?分發到哪裏呢?如下是幾個工做中的實踐,分享一下:

主機:這是最主要的也是最重要的點,本質上分庫分表是由於計算與存儲資源不夠致使的,而這種資源主要由物理機,主機提供的,畢竟沒有可用的計算資源,怎麼分效果都不是太好。

實例:實例控制着鏈接數,同時受OS限制,CPU、內存、硬盤、網絡IO也會受間接影響。會出現熱實例的現象,即:有些實例特別忙,有些實例很是的空閒。一個典型的現象是:因爲單表反應慢,致使鏈接池被拉滿,因此其餘的業務都受影響了。這時候,把表分到不一樣的實例是有一些效果的。

庫:通常是因爲單庫中最大單表數量的限制,才採起分庫。

表:單表壓力過大,索引量大,容量大,單表的鎖。據以上,把單表水平切分紅不一樣的表。

大型應用中,都是一臺主機上只有一個實例,一個實例中只有一個庫,庫==實例==主機,因此纔有了分庫分表這個簡稱。

既然知道了這個基本理論,那麼具體是怎麼作的呢?邏輯是怎麼跑的呢?接下來以一個例子來說解一下。

這個需求很簡單,用戶表(user),單表數據量1億,查詢、插入、存儲都出現了問題,怎麼辦呢?

首先,分析問題,這個明顯是因爲數據量太大了而致使的問題。

其次,設計方案,能夠分爲10個庫,這樣每一個庫的數據量就降到了1KW,單表1KW數據量仍是有些大,並且不利於之後量的增加,因此每一個庫再分100個表,這樣每一個單表數據量就爲10W了,對於查詢、索引更新、單表文件大小、打開速度,都有一些溢出。接下來,給IT部門打電話,要10太物理機,擴展數據庫……

最後,邏輯實現,這裏應該是最有學問的地方。首先是寫入數據,須要知道寫道哪一個分庫分表中,讀也是同樣的,因此,須要有個請求路由曾,負責把請求分發、轉換到不一樣的庫表中,通常有路由規則的概念。

怎麼樣,簡單吧?哈哈。說說這個模式的問題,主要是帶來了事務上的問題,由於分庫分表,事務完成不了,而分佈式事務又太本重,因此這裏須要有必定的策略,保證在這種狀況下事務可以完成。採起的策略如:最終一致性、複製、特殊設計等。再有就是業務代碼的改造,一些關聯查詢要改造,一些單表orderBy的問題須要特殊處理,也包括groupBy語句,如何解決這些反作用不是一句兩句可以說清楚的,之後有時間,我單獨講講這些。

該總結一下這種模式的優缺點了,以下:

優勢:減小數據庫單表的壓力。

缺點:事務保證困難、業務邏輯須要作大量改造。

9、彈性伸縮模式

這種模式主要解決突發流量的到來,致使沒法橫向擴展或者橫向擴展太慢,進而影響業務,全站崩潰的問題。這個模式是一種相對來講比較高級的技術,也是各大公司目前都在研究、試用的技術。截至今日,有這種思想的架構師已是很不錯的了,可以拿到較高薪資,更別提那些已經實踐過的,甚至實現了底層系統的那些,因此,你懂得……

這種模式的通常設計以下圖:

 

 如上圖所示,多了一個彈性伸縮服務,用來動態的增長、減小實例。原理上很是簡單,可是這個模式到底解決了什麼問題呢?先說說由來和意義。

每一年的雙十一、618或者一些大促銷到來以前,咱們都會爲大流量的到來作如下幾個方面的工做:提早準備10倍甚至更多的機器,即使用不上也要放在那裏備着,以防萬一,這樣浪費了大量的資源。每臺機器配置、調試、引流,以便讓全部的機器均可用,這樣浪費了大量的人力、物力,更容易出錯。若是機器準備不充分,那麼還要加班加點的重複上面的工做,這樣特別容易出錯,引來領導的不滿,沒時間回家陪老婆,而後你老婆就……哈哈

在雙十一以後,咱們還要人工作縮容,很是的辛苦。通常一年中會有屢次促銷,那麼咱們就會一直這樣,實在是煩!

最嚴重的,忽然間的大流量爆發,會讓咱們猝不及防,半夜起來擴容是正常不過的事情,爲此,咱們偷懶起來,要更多的機器備着,也就出現了大量CPU利用率爲1%的機器。

相信我,若是你是老闆必定很震驚吧!

哈哈,那麼如何改變這種狀況呢?請接着看

爲此,首先把全部的計算資源整合成資源池的概念,而後經過一些策略、監控、服務,動態的從資源池中獲取資源,用完後再放回到池子中,供其餘系統試用。具體實現上比較成熟的兩種資源池方案是VM、docker,每一個都有着本身強大的生態。監控點有CPU、內存、硬盤、網絡IO、服務質量等,根據這些,再配合一些預留、擴張、收縮策略,就能夠簡單的實現自動收縮。怎麼樣?是否是很神奇?深刻的內容我會在後面的文章中詳細的講述,該總結如下這種模式的優缺點了。以下:

優勢:彈性、隨需計算,充分優化企業計算資源。

缺點:應用要從架構層作到可橫向擴展化改造、依賴的底層配套比較多,對技術水平、實力、應用規模要求比較高。

10、多機房模式

這種模式主要解決不一樣地區高性能、高可用的問題

隨着應用用戶的不斷增長,用戶羣體分佈在全球各地,若是把服務器都部署在一個地方,一個機房,好比北京,那麼美國的用戶使用應用的時候會特別慢,由於每一個請求都須要經過海底光纜走上那麼一秒鐘左右,這樣對用戶體檢及其很差,怎麼辦?使用多機房部署。這種模式通常設計以下圖所示:

 

 

 如上圖所示,一個典型的用戶請求流程以下:

用戶請求一個鏈接A

經過DNS智能解析到離用戶最近的機房B

使用B機房服務鏈接A

是否是以爲很簡單,沒啥?其實這裏面的問題沒有表面這麼簡單,下面一一道來,

首先是數據同步問題,在中國產生的數據要同步到美國,美國的也同樣,數據同步就會涉及數據版本、一致性、更新丟棄、刪除等問題。

其次是一地多機房的請求路由問題,典型的是如上圖,中國的北京機房和杭州機房,若是北京機房掛了,那麼要可以經過路由把全部發往北京機房的請求轉發到杭州機房,異地也存在這個問題。

因此,多機房模式,也就是異地多活並非那麼的簡單,這裏只是起了個頭,具體的有哪些坑,會在後面的文章中介紹。

該總結如下這種模式的優缺點了,以下:

優勢:高可用、高性能、異地多活。

缺點:數據同步、數據一致性、請求路由。

至此,整個關於八種架構設計模式及其優缺點的概述就介紹完了,最後,我想說的是,沒有銀彈、靈活運用,共勉!

相關文章
相關標籤/搜索