《從0開始學架構》–筆記

《從0開始學架構》–筆記

第1篇 架構是什麼

系統 泛指由一群有關聯的個體組成,根據某種規則運作,能完成個別元件不能單獨完成的工作的群體(能力)。

從邏輯的角度拆分系統後,得到的單元就是“模塊”,從物理的角度拆分系統後,得到的單元就是“組件”。劃分模塊的主要目的是職責分離,劃分組件的主要目的是單元複用。

框架是組件規範,提供基礎功能的產品。軟件架構指軟件系統的“基礎結構”,創造這些基礎結構的準則,以及這些結構的描述。框架關注的是“規範”,架構關注的是“結構”。

軟件架構指軟件系統的頂層結構:

* 架構需要明確系統包含哪些“個體”,個體可以是 子系統、模塊、組件等。

* 架構需要明確個體的運作和協作的規則。

* 頂層結構可以更好地區分系統和子系統。

自話:軟件架構確定了系統中應該包含哪些個體,以及個體之間應該如何協作,以提供某種能力,從而實現系統的價值。

第2篇 架構設計的歷史背景

“模塊”“對象”“組件”本質上都是對達到一定規模的軟件進行拆分,區別只是在於隨著軟件的複雜度不斷增加,拆分的粒度越來越粗,拆分的層次越來越高。

第3篇 架構設計的目的

架構設計的主要目的是為了解決軟件系統複雜度帶來的問題。

架構設計首先要分析系統的複雜度所在,然後針對這些複雜度進行設計、制定方案。

軟件系統中高性能帶來的複雜度主要體現在兩方面,一方面是單臺計算機內部為了提高性能帶來的複雜度;另一方面是多臺計算機集群為了高性能帶來的複雜度。

系統的高可用本質都是通過“冗餘”來實現的,方法是增加機器。

高性能增加機器的目的在於“提升”處理性能,高可用增加機器的目的在於“冗餘”處理單元。

存儲高可用的難點不在於如何備份數據,而在於如何減少或者規避數據不一致對業務造成的影響。

高可用狀態決策:無論是計算高可用還是存儲高可用,其基礎都是“狀態決策”,即系統能夠判斷當前狀態是正常還是異常,如果出現異常就要採取行動來保證高可用。

決策方式:

* 獨裁式:所有冗餘的個體向一個獨立的決策主體上報狀態信息,決策者進行決策。問題在於決策者本身是個單點。

* 協商式:兩個獨立的個體通過交流信息,然後根據規則進行決策,最常用的協商式決策就是主備決策。難點在於兩者的信息交換出現問題時如何決策。

* 民主式:指多個獨立的個體通過投票的方式來進行決策。缺陷是腦裂:原來統一的集群因為連接中斷,造成兩個獨立分隔的子集群,每個子集群單獨進行選舉,選出兩個決策者。解決方法是要求“投票節點數必須超過系統總結點數一半”。

可擴展性是指為了應對將來需求變化而提供的一種擴展能力。

設計具備良好可擴展性的系統,有兩個基本條件:正確預測變化、完美封裝變化。

預測變化的複雜性在於:不能每個設計點都考慮可擴展性、不能完全不考慮可擴展性、所有的預測都存在出錯的可能性。

設計具備良好可擴展性的系統,有兩個思考角度:從業務維度,對業務深入理解,對可預計的業務變化進行預測;從技術維度,利用擴展性好的技術,實現對變化的封裝。

應對變化的常見方案一是將“變化”封裝在一個“變化層”,將不變的部分封裝在一個獨立的“穩定層”。

方案二是提煉出一個“抽象層”和一個“實現層”,抽象是文檔的,實現可根據具體業務需要定製開發,加入新的功能時,只需要增加新的實現,無需修改抽象層。

舉例:設計一個支付網關對接不同的支付機構,為業務系統提供支付能力。每家支付機構的通信方式、請求/響應格式都是不一樣的,但基本參數都是四要素信息(銀行卡號、預留手機號、姓名、身份證號)、扣款金額等,扣款結果一般就是成功/失敗/等通知,因此可以抽象出統一的接口,對接不同支付機構的具體實現類實現這個接口、完成具體的調用邏輯,當要對接新的支付機構時只需要添加一個實現類;業務系統只需訪問這個統一的接口。

第7篇 複雜度來源:低成本、安全、規模

低成本是架構設計的一個約束條件,不是首要目標,本質上與高性能/高可用衝突。

從技術的角度,安全可以分為兩類:功能上的安全,架構上的安全。

功能安全一般與具體的編碼相關,是實現的問題。功能安全是一個逐步完善的過程,往往都是在問題出現之後才能針對性的提出解決方案,也無法預測下一個漏洞在哪裡。

架構安全是防止暴力破壞,典型的就是防止DDOS攻擊。

規模帶來複雜度的主要原因是“量變引起質變”,當數量超過一定的閾值後,複雜度會發生質的變化。

常見的規模帶來的複雜度有:功能越來越多,導致系統複雜度指數級上升;數據越來越多,系統複雜度發生質變;

第8篇 架構設計三原則

合適原則:合適優於業界領先。真正優秀的架構都是在企業當前人力、條件、業務等各種約束下設計出來的,能夠合理地將資源整合在一起併發揮出最大功效,並且能夠快速落地。

簡單優於複雜。(複雜分結構複雜和邏輯複雜)

對於建築,永恆是主題;對於軟件,變化才是主題。軟件架構需要根據業務發展不斷變化。

第10篇 架構設計流程1:識別複雜度

深入研究業務需求、通過“排查法”分析複雜度所在。

第11篇 架構設計流程2:設計備選方案

成熟的架構師需要對已經存在的技術非常熟悉,對已經經過驗證的架構模式爛熟於心,然後根據對業務的理解,挑選合適的架構模式進行組合,再對組合的方案進行修改和調整。

備選方案:數量3-5個最佳;差異要比較明顯;技術不要只侷限於已經熟悉的技術;不宜過於詳細而忽略整體設計;

第12篇 架構設計流程3:評估和選擇備選方案

列出需要關注的質量屬性點,分別從這些質量熟悉的維度去評估每個方案,再綜合挑選適合當時情況的最優方案。

常見的方案質量熟性有:性能、高可用、成本、複雜度、安全性、可擴展性、可伸縮性等。

第13篇 架構設計流程4:詳細方案設計

詳細方案設計就是將方案涉及的關鍵技術細節確定下來。

架構師不但要進行備選方案設計和選型,還需要對備選方案的關鍵細節有深入的理解。通過分步驟、分階段、分系統等方式,儘量降低方案複雜度,方案本身的複雜度越高,某個細節推翻整個方案的可能性就越高,適當降低複雜性,可以減少這種風險。如果方案本身很複雜,採取設計團隊的方式來進行設計,防止只有1-2個架構師可能出現思維盲點或經驗盲區。;

第14/15篇 高性能數據庫集群

讀寫分離

將讀壓力分散到集群中的多個節點,但沒有分散存儲壓力。主從複製延遲和分配機制會帶來複雜度。

解決主從延遲的常見方法:寫操作後的讀操作發送給數據庫主服務器(和業務強綁定,侵入業務代碼);讀從機失敗後再讀一次主機(大量二次讀會增加主機讀壓力);關鍵業務讀寫操作全部指向主機,非關鍵業務採用讀寫分離。

讀寫分離的實現一般有兩種方式:程序代碼封裝和中間件封裝。

程序代碼封裝指在代碼中抽象一個數據訪問層,實現讀寫操作分離和數據庫服務器連接的管理。

中間件封裝指的是獨立一套系統出來,實現讀寫操作分離和數據庫服務器連接的管理。

讀寫分離首先需要考慮業務的讀寫比例。

分庫分表

既分散了讀壓力,又分散了存儲壓力。

分庫帶來的問題:join 操作問題,事務問題,成本問題。

水平分表相比垂直分表,引入的複雜性主要體現在:

* 路由:用於確定某條數據所在切分後的子表。常見的路由算法有 範圍路由、hash路由、配置路由。

* join 操作

* count 操作

* order by 操作

第17篇 高性能緩存架構

緩存穿透

指緩存沒有發揮作用,業務系統雖然去緩存查詢數據,但緩存中沒有數據,業務系統需要再次去存儲系統查詢數據。

緩存雪崩

指當緩存失效(過期)後引起系統性能急劇下降的情況。

常見的解決方法有兩種:

* 更新鎖機制:對緩存更新操作進行加鎖保護,保證只有一個線程能夠進行緩存更新,未能獲取更新鎖的線程要麼等待鎖釋放後重新讀取緩存,要麼直接返回空值或者默認值。

* 後臺更新機制:緩存本身的有效期設置為永久,後臺線程定時更新緩存。

緩存熱點:對於特別熱點的數據,可以複製多份緩存副本,將請求分散到多個緩存服務器上,減輕緩存熱點導致的單臺服務器壓力。


分享到:


相關文章: