1. 程式人生 > >從0開始學架構

從0開始學架構

01 | 架構到底是指什麼?

  軟體架構指軟體系統的頂層結構

02 | 架構設計的歷史背景

  20 世紀 60 年代第一次軟體危機引出了“結構化程式設計”,創造了“模組”概念;
  20 世紀 80 年代第二次軟體危機引出了“面向物件程式設計”,創造了“物件”概念;
  20 世紀 90 年代“軟體架構”開始流行,創造了“元件”概念

03 | 架構設計的目的

  是為了解決軟體系統複雜度帶來的問題

04 | 複雜度來源:高效能

  單臺計算機內部為了高效能帶來的複雜度

  多臺計算機叢集為了高效能帶來的複雜度

    任務分配:任務分配的意思是指每臺機器都可以處理完整的業務任務,不同的任務分配到不同的機器上執行。

 

    任務分解

      簡單的系統更加容易做到高效能、可以針對單個任務進行擴充套件

05 | 複雜度來源:高可用

  高可用:系統無中斷地執行其功能的能力,代表系統的可用性程度,是進行系統設計時的準則之一。

  高效能增加機器目的在於“擴充套件”處理效能;高可用增加機器目的在於“冗餘”處理單元

  計算高可用:這裡的“計算”指的是業務的邏輯處理

  儲存高可用:對於需要儲存資料的系統來說,整個系統的高可用設計關鍵點和難點就在於“儲存高可用”

  高可用狀態決策

    1. 獨裁式:獨裁式決策指的是存在一個獨立的決策主體,我們姑且稱它為“決策者”,負責收集資訊然後進行決策;所有冗餘的個體,我們姑且稱它為“上報者”,都將狀態資訊傳送給決策者

    2. 協商式:協商式決策指的是兩個獨立的個體通過交流資訊,然後根據規則進行決策,最常用的協商式決策就是主備決策

    3. 民主式:民主式決策指的是多個獨立的個體通過投票的方式來進行狀態決策。例如,ZooKeeper 叢集在選舉 leader 時就是採用這種方式

06 | 複雜度來源:可擴充套件性

  可擴充套件性:可擴充套件性指系統為了應對將來需求變化而提供的一種擴充套件能力,當有新的需求出現時,系統不需要或者僅需要少量修改就可以支援,無須整個系統重構或者重建

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

  第二種常見的應對變化的方案是提煉出一個“抽象層”和一個“實現層”

07 | 複雜度來源:低成本、安全、規模

  低成本、安全(1. 功能安全、2. 架構安全)、規模

08 | 架構設計三原則

  合適原則:合適優於業界領先

  簡單原則:簡單優於複雜

  演化原則:演化優於一步到位

  設計出來的架構要滿足當時的業務需要

  架構要不斷地在實際應用過程中迭代,保留優秀的設計,修復有缺陷的設計,改正錯誤的設計,去掉無用的設計,使得架構逐漸完善

  當業務發生變化時,架構要擴充套件、重構,甚至重寫;程式碼也許會重寫,但有價值的經驗、教訓、邏輯、設計等(類似生物體內的基因)卻可以在新架構中延續

09 | 架構設計原則案例

10 | 架構設計流程:識別複雜度

  識別複雜度實戰:這個訊息佇列是否需要高效能、這個訊息佇列是否需要高可用性、這個訊息佇列是否需要高可擴充套件性

11 | 架構設計流程:設計備選方案

  第一種常見的錯誤:設計最優秀的方案、第二種常見的錯誤:只做一個方案、第三種常見的錯誤:備選方案過於詳細

  設計備選方案實戰:

    1. 備選方案:採用開源的 Kafka:Kafka 是成熟的開源訊息佇列方案,功能強大,效能非常高,而且已經比較成熟,很多大公司都在使用

    2. 備選方案:叢集 + MySQL 儲存

      採用資料分散叢集的架構,叢集中的伺服器進行分組,每個分組儲存一部分訊息資料。

      每個分組包含一臺主 MySQL 和一臺備 MySQL,分組內主備資料複製,分組間資料不同步。

      正常情況下,分組內的主伺服器對外提供訊息寫入和訊息讀取服務,備伺服器不對外提供服務;主伺服器宕機的情況下,備伺服器對外提供訊息讀取的服務。

      客戶端採取輪詢的策略寫入和讀取訊息。

    3. 備選方案:叢集 + 自研儲存方案  

      在備選方案 2 的基礎上,將 MySQL 儲存替換為自研實現儲存方案,因為 MySQL 的關係型資料庫的特點並不是很契合訊息佇列的資料特點,參考 Kafka 的做法,可以自己實現一套檔案儲存和複製方案(此處省略具體的方案描述,實際設計時需要給出方案)。

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

  最簡派:設計師挑選一個看起來最簡單的方案。

  最牛派:最牛派的做法和最簡派正好相反,設計師會傾向於挑選技術上看起來最牛的方案

  最熟派:設計師基於自己的過往經驗,挑選自己最熟悉的方案

  領導派:領導派就更加聰明瞭,列出備選方案,設計師自己拿捏不定,然後就讓領導來定奪,反正最後方案選的對那是領導厲害,方案選的不對怎麼辦?那也是領導“背鍋”。

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

  常見的方案質量屬性點有:效能、可用性、硬體成本、專案投入、複雜度、安全性、可擴充套件性等

  按優先順序選擇:綜合當前的業務發展情況、團隊人員規模和技能、業務發展預測等因素,將質量屬性按照優先順序排序,首先挑選滿足第一優先順序的,如果方案都滿足,那就再看第二優先順序……以此類推。

  架構師經過思考後,給出了最終選擇備選方案 2,原因:

    排除備選方案 1 的主要原因是可運維性,因為再成熟的系統,上線後都可能出問題,如果出問題無法快速解決,則無法滿足業務的需求;並且 Kafka 的主要設計目標是高效能日誌傳輸,而我們的訊息佇列設計的主要目標是業務訊息的可靠傳輸。

    排除備選方案 3 的主要原因是複雜度,目前團隊技術實力和人員規模(總共 6 人,還有其他中介軟體系統需要開發和維護)無法支撐自研儲存系統(參考架構設計原則 2:簡單原則)。

    備選方案 2 的優點就是複雜度不高,也可以很好地融入現有運維體系,可靠性也有保障

  針對備選方案 2 的缺點,架構師解釋是:

    備選方案 2 的第一個缺點是效能,業務目前需要的效能並不是非常高,方案 2 能夠滿足,即使後面效能需求增加,方案 2 的資料分組方案也能夠平行擴充套件進行支撐(參考架構設計原則3:演化原則)。

    備選方案 2 的第二個缺點是成本,一個分組就需要 4 臺機器,支撐目前的業務需求可能需要12 臺伺服器,但實際上備機(包括伺服器和資料庫)主要用作備份,可以和其他系統並行部署在同一臺機器上。

    備選方案 2 的第三個缺點是技術上看起來並不很優越,但我們的設計目的不是為了證明自己(參考架構設計原則 1:合適原則),而是更快更好地滿足業務需求。

13 | 架構設計流程:詳細方案設計

  例如,Nginx 的負載均衡策略,簡單按照下面的規則選擇就可以了

    輪詢(預設):每個請求按時間順序逐一分配到不同的後端伺服器,後端伺服器分配的請求數基本一致,如果後端伺服器“down

    加權輪詢:根據權重來進行輪詢,權重高的伺服器分配的請求更多,主要適應於後端伺服器效能不均的情況,如新老伺服器混用。

    ip_hash:每個請求按訪問 IP 的 hash 結果分配,這樣每個訪客固定訪問一個後端伺服器,主要用於解決session 的問題,如購物車類的應用。

    fair:按後端伺服器的響應時間來分配請求,響應時間短的優先分配,能夠最大化地平衡各後端伺服器的壓力,可以適用於後端伺服器效能不均衡的情況,也可以防止某臺後端伺服器效能不足的情況下還繼續接收同樣多的請求從而造成雪崩效應。

    url_hash:按訪問 URL 的 hash 結果來分配請求,每個 URL 定向到同一個後端伺服器,適用於後端伺服器能夠將 URL 的響應結果快取的情況。

  1.資料庫表如何設計?

    資料庫設計兩類表,一類是日誌表,用於訊息寫入時快速儲存到 MySQL 中;另一類是訊息表,每個訊息佇列一張表。
    業務系統釋出訊息時,首先寫入到日誌表,日誌表寫入成功就代表訊息寫入成功;後臺執行緒再從日誌表中讀取訊息寫入記錄,將訊息內容寫入到訊息表中。
    業務系統讀取訊息時,從訊息表中讀取。
    日誌表表名為 MQ_LOG,包含的欄位:日誌 ID、釋出者資訊、釋出時間、佇列名稱、訊息內容。
    訊息表表名就是佇列名稱,包含的欄位:訊息 ID(遞增生成)、訊息內容、訊息釋出時間、訊息釋出者。
    日誌表需要及時清除已經寫入訊息表的日誌資料,訊息表最多儲存 30 天的訊息資料。

  2.資料如何複製?

    直接採用 MySQL 主從複製即可,只複製訊息儲存表,不復制日誌表。

  3.主備伺服器如何倒換?

    採用 ZooKeeper 來做主備決策,主備伺服器都連線到 ZooKeeper 建立自己的節點,主伺服器的路徑規則為“/MQ/server/ 分割槽編號 /master”,備機為“/MQ/server/ 分割槽編號/slave”,節點型別為 EPHEMERAL。

    備機監聽主機的節點訊息,當發現主伺服器節點斷連後,備伺服器修改自己的狀態,對外提供訊息讀取服務。

  4.業務伺服器如何寫入訊息?

    訊息佇列系統設計兩個角色:生產者和消費者,每個角色都有唯一的名稱

    訊息佇列系統提供 SDK 供各業務系統呼叫,SDK 從配置中讀取所有訊息佇列系統的伺服器資訊,SDK 採取輪詢演算法發起訊息寫入請求給主伺服器。如果某個主伺服器無響應或者返回錯誤,SDK 將發起請求傳送到下一臺伺服器。

  5.業務伺服器如何讀取訊息?

    訊息佇列系統提供 SDK 供各業務系統呼叫,SDK 從配置中讀取所有訊息佇列系統的伺服器資訊,輪流向所有伺服器發起訊息讀取請求。

    訊息佇列伺服器需要記錄每個消費者的消費狀態,即當前消費者已經讀取到了哪條訊息,當收到訊息讀取請求時,返回下一條未被讀取的訊息給消費者。

  6.業務伺服器和訊息佇列伺服器之間的通訊協議如何設計?

    考慮到訊息佇列系統後續可能會對接多種不同程式語言編寫的系統,為了提升相容性,傳輸協用 TCP,資料格式為 ProtocolBuffer。

14高效能資料庫叢集:讀寫分離

15搞效能資料庫叢集:分庫分表

16高效能NoSQL

  關係型資料庫缺點

    儲存的是行記錄,無法儲存資料結構

    schema擴充套件很不方便

    全文搜尋功能比較弱

  NoSQL方案

    K-V儲存:解決無法儲存資料結構的問題,redis

    文件資料庫:解決強schema約束的問題,MongoDB

      資料格式:json

      新增欄位簡單、歷史資料不會出錯

      不支援事務、無法實現join操作

    列式資料庫,解決大資料場景下的I/O問題,HBase

      讀取多列時效率高、能夠一次性完對多個列的寫操作、具備更高的儲存壓縮比,適用於離線的大資料分析和統計

    全文搜尋引擎:解決全文搜尋效能問題,Elasicsearch

17高效能快取架構

  快取穿透:快取沒有發揮作用

    儲存資料不存在,可以設定預設值(空值或具體值)

    快取資料生成耗費大量時間或者資源,禁止爬蟲或做好監控

  快取雪崩:當快取過期被清除後,業務系統需要重新生成,會引起系統性能急劇下降

    更新鎖:對快取更新進行加鎖保護,保證只有一個執行緒進行快取更新,叢集要採用分散式鎖

    後臺更新:後臺執行緒更新快取,快取本身設定為永久,後臺定時更新

      快取不夠時會踢掉部分快取,在這部分快取沒有到更新時間,會返回空值

        後臺執行緒頻繁讀取快取,發現被踢立即更新,讀取間隔不能太長

        快取失效後,通過訊息佇列傳送通知後臺執行緒進行更新快取,後臺執行緒驗證快取是否存在,不存在就更新

  快取熱點:對於特別熱點的資料,複製多份快取副本,將請求分散到多個快取伺服器,設定過去時間為指定範圍內的隨機值

18單伺服器高效能模式:PPC和TPC

  併發模式關鍵點:如何管理連線、如何處理請求

  I/O模型:阻塞、非阻塞、同步、非同步

  程序模式:但程序、多程序、多執行緒

  PPC:每次有新的連線就新建一個程序專門處理請求

    fork代價高、父子進行通訊複雜、支援的併發連線數量有限

  prefork:提前建立程序

  TPC:共享進行記憶體空間

  

  prethread:預先建立執行緒

19單伺服器高效能模式:Reactor(反應堆)與Proactor

  Reactor:建立程序池,將連線分配給程序,一個程序可以處理多個連線業務

    I/O多路複用

      當多條連線共用一個阻塞物件後,程序只需要在一個阻塞物件上等待,而無須再輪詢所有連線,例如select、epoll、kqueue

      當某條連線有新的資料可以處理時,作業系統會通知程序,程序從阻塞狀態返回,開始進行業務處理

    Reactor負責監聽和分配事件,處理資源池負責處理事件

    Reactor的數量可以變化

    資源池的數量可以變化

    實現方案:單Reactor多執行緒、多Reactor多程序、多Reactor多執行緒

    單Reactor單程序/執行緒

    Reactor物件通過select監控連線事件,收到事件後通過dispatch進行分發

    如果是連線建立的事件,則由Acceptor處理,Acceptor通過accept接受連線,並建立一個handler處理連線後續的各種事件

    如果不是連線事件,則Acceptor會呼叫連線對應的handler來進行響應

  單Acceptor多執行緒

    主執行緒中Reactor物件通過select監控連線事件,收到後通過dispatch進行分發,如果是連線事件,則由Accept處理,通過handler進行後續處理

    如果不是連線建立事件,則Reactor會呼叫連線對應的handler來進行響應

    handler只負責響應事件,不進行業務處理,handler通過read讀取到資料後,會發給processor進行業務處理

    processor會在獨立的子執行緒中完成真正的業務處理,然後將響應結構發給主程序的handler處理,handler收到響應後通過send將響應結構返回給client

    問題:多執行緒資料共享和訪問比較複雜、Reactor承擔所有事件的監聽和響應,只在主執行緒中執行,瞬間高併發時會稱為效能瓶頸

   多Reactor多進行/執行緒

    父程序中mainReactor物件通過select監控連線建立事件,收到事件後通過Acceptor接收,將新的連線分配給某個子程序

    子進行的subReactor將mainReactor分配的連線加入連線佇列進行監聽,並建立一個handler用於處理連線的各種事件

    當有新的事件發生時,subReactor會呼叫連線對應的handler來進行響應

    handler完成read->業務處理->send的完整業務流程

   比單Reactor多執行緒簡單

    父程序和子程序的職責,父程序只負責接收新連線,子程序負責完成後續的業務處理

    父程序和子程序的互動很簡單,父程序只需要把新連線傳給子程序,子程序無須返回資料

    子程序之間是相互獨立的,無須同步共享之類的處理

  Proactor(主動器)是非阻塞同步網路模型

    Proactor Initiator負責建立Proactor和handler,並將Proactor和handler都通過Asynchonous Operation Processor註冊核心

    Asynchonous Operation Processor負責處理註冊請求,並完成I/O操作

    Asynchonous Operation Processor完成I/O操作後通知Proactor 

    handler完成業務處理,handler也可以註冊新的Proactor 到核心程序

20高效能負載均衡:分類及架構

  DNS負載均衡:根據地區分配

    優點

      簡單、成本低:負載均衡工作交給DNS伺服器處理,無須自己開發或者維護負載均衡裝置

      就近訪問,提升訪問速度:dns解析時可以根據請求來源ip,解析成距離使用者最近的伺服器地址,可以儘快訪問速度,改善效能

    缺點

      更新不及時:dns快取的時間比較長,修改dns配置後,由於快取的原因,還是有很多使用者會繼續訪問修改前的ip,這樣的訪問會失敗,達不到負載均衡的目的,並且也影響使用者正常使用業務

      擴充套件性差:dns負載均衡的控制權在域名商那裡,無法根據業務特定針對其做更多的定製化功能和擴充套件特性

      分配策略比較簡單:dns負載均衡支援的演算法少,不能區分伺服器差異,也無法感知後端伺服器的狀態

  硬體負載均衡:通過單獨的硬體裝置來實現負載均衡功能,類似路由器或交換機

    優點:

      功能強大:全面支援各層級的負載均衡,支援全面的負載均衡,支援全域性負載均衡

      效能強大:相比軟體負載均衡的10萬級併發,硬體負載均衡可以達到100萬以上的併發

      穩定性高:商用硬體負載均衡,經過了良好的嚴格測試,經過大規模使用,穩定性高

      支援安全防護:硬體負載均衡還具備防火牆、放DDos攻擊等安全防護

    缺點:

      價格昂貴:普通的F5、好的馬6,最好的Q7

      擴充套件效能差:郵件裝置可以根據業務進行配置,但無法進行擴充套件和定製

  軟體負載均衡

    Nginx的軟體負載均衡

    優點

      簡單:部署和維護都簡單

      便宜:買個linux伺服器,裝軟體就可以使用

      靈活:4層和7層負載均衡可以根據業務進行選擇,也可以根據業務進行方便的擴充套件

    缺點

      效能一般,大約5萬併發

      功能沒有硬體負載均衡強大

      一般不具備防火牆和放ddos攻擊等安全功能

  DNS適用於地理級別、硬體負載均衡適用於叢集級別、軟體負載均衡適用於機器級別

21高效能負載均衡:演算法

  任務平分類:絕對平均或比例平均

    輪詢:按照順序輪流分配到伺服器上。

    加權輪詢:根據伺服器權重進行任務分配,根據硬體配置進行靜態配置,動態計算會更加契合業務,但複雜度更高

  負載均衡類:將任務分配給當前負載最低的伺服器,根據不同業務型別和業務場景用不同指標來衡量

    最小連線數優先的演算法、CPU負載最低優先的演算法

  效能最優類:根據伺服器的響應時間來進行任務分配,優先將新任務分配給響應最快的伺服器

    通過取樣統計任務響應時間,需要選擇合適的週期

  Hash類:負載均衡系統根據任務中的某些關鍵資訊進行hash運算,將相同hash值的請求分配給相同的伺服器

    源地址Hash:將來源於同一個ip地址的任務分配給同一個伺服器進行處理,適合於存在事務、會話的業務。

    IDhash:將某個ID標識的業務分配到同一個伺服器中進行處理,這裡的ID一般是臨時性資料的ID,例如sessionid的hash可以實現使用者每次訪問相同伺服器

22想成為架構師,你必須知道CAP理論

  一致性、可用性、分割槽容忍性

23想成為架構師,你必須掌握的CAP細節

  CAP關注的粒度是資料,而不是整個系統

  CAP是忽略網路延遲的

  正常執行情況下,不存在CP和AP的選擇,可以同時滿足CA

  放棄不等於什麼都不做,需要為分割槽恢復後做準備

  ACID:資料庫管理系統為了保證事務的正確性而提出來的理論。

    原子性:事務中的所有操作要麼全部完成,要麼全部失敗。

    一致性:在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞

    隔離性:資料庫防止多個事務併發執行讀提交、可重複讀、序列化

    永續性:事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失

  BASE:基本可用、軟狀態、最終一致性

    基本可用:分散式系統在出現故障時,允許損失部分可用性,保證核心可用

    軟狀態:允許系統存在中間狀態,而該中間狀態不會允許系統整體可用性

    最終一致性:系統中的所有資料副本經過一定時間後,最終能夠達到一致的狀態

24FMEA方法,排除架構可用性隱患的利器

  FMEA故障模式與影響分析

    給出初始的架構設計圖

    假設架構中某個部件發生故障

    分析此故障對系統功能造成的影響

    根據分析結果,判斷架構是否需要優化

  分析表:

    功能點:使用者角度來看

    故障模式:系統會出現什麼樣的故障,包括故障點和故障形式,描述需要精確,量化描述

    故障影響:當發生故障模式中描述的故障時,功能點具體會受到什麼影響

    嚴重程度:站在業務的角度故障的影響程度,分為“致命、高、中、低、無”五個檔次。嚴重程度=功能點重要程度*故障影響範圍*功能點受損程度,以登入系統為例

    故障原因:不同的故障原因發生概率不同、不同的故障原因檢測手段不一樣、不同的故障原因的處理措施不一樣

    故障概率:某個具體故障原因發生的概率。

      硬體:硬體隨著使用時間推移,故障概率會越來越高

      開源系統:成熟的開源系統bug率低,剛釋出的開源系統bug率相比會高一些

      自研系統:成熟的低,新開發的高

    風險程度:綜合嚴重程度和故障概率判斷某個故障的最終等級,風險程度=嚴重程度*故障概率

    已有措施:針對具體的故障原因,系統現在是否提供了某些措施來一堆

      檢查告警:檢查故障,然後告警,人工處理

      檢查故障後,系統通過備份手段應對

      自恢復:檢測到故障後,系統能夠自己恢復(恢復業務)

    規避措施:為了降低故障傳送概率而採取的手段

      技術手段:為了避免引入的MongoDB丟失資料,在mysql中冗餘一份

      管理手段:為了降低磁碟壞道的概率,強制統一更新伺服器時間超過2年的磁碟

    解決措施:解決問題做的技術手段

      解決密碼暴力破解,增加密碼重試次數限制

      解決拖庫導致資料洩露,將資料庫中的敏感資料加密儲存

      解決非法訪問,增加白名單控制

    後續規劃:針對不足的地方結合風險程式進行排序,給出後續的改進規劃

  實戰:

25高可用儲存架構:雙機架構

  主備複製

    實現

      備機起備份作用,不承擔實際的業務讀寫操作,切換為主機需要人工操作

    優點

      對於客戶端,不需要感知備機的存在

      對於主機和備機,只需要進行資料複製,無須進行狀態判斷和主備切換

    缺點

      備機僅僅只是備份,並沒有提供讀寫操作,硬體成本上有浪費

      故障後需要人工干預,無法自動恢復

    適用於內部的後臺管理系統

  主從複製:主機負責讀寫,從機負責讀操作

    實現

      

    優點

      主機發生故障時,讀操作業務可以繼續執行

      從機提供讀操作,發揮了硬體的效能

    缺點

      客戶端需要感知主從關係,將不同的操作發給不同的機器

      從機提供讀業務,如果主從複製延遲比較大,業務會出現不一致

      故障時需要人工干預

    適用於寫少讀多的業務:例如論壇、bbs、新聞網站

  雙機切換

    設計關鍵:增加切換功能

    主備間狀態判斷:狀態傳遞的渠道以及狀態檢測的內容

    切換決策:切換時機(什麼情況下切換)、切換策略(故障恢復後的處理)、自動程度(是否需要人工確認切換)

    資料衝突解決:故障恢復後,新舊主機資料發生衝突時的處理

  互連式:主備機直接建立狀態傳遞的渠道

    狀態傳遞通道

    客戶端的改變

      

    缺點:多通道只能降低通道故障概率,客戶端可能收到不同的狀態資訊

  中介式:引入第三方中介,通過中介傳遞狀態資訊

    連線更簡單:主備機無效建立通道

    狀態決策更簡單:主備機無效考慮多種型別的連線通道獲取的狀態資訊如何決策的問題

    成熟方案:ZooKeeper

  模擬式:主備機之間並不傳遞任何狀態資料,備機模擬成客戶端,向主機發起模擬的讀寫操作,根據讀寫操作的響應情況判斷主機狀態

  主主複製:兩臺機器都是主機,互相將資料複製給對方,客戶端可以任意挑選機器讀寫

    優點

    缺點

    適用於臨時性,可丟失,可覆蓋的資料場景,例如:session資料(可重新生成)、使用者行為日誌(可丟失)、論壇的草稿資料(可丟失)

26高可用儲存架構:叢集和分割槽

  資料集中叢集:一主多備/從

    主機如何將資料複製給備機

    主機故障後,如何決定新的主機,ZooKeeper通過ZAB演算法解決

    適用於資料量不大,叢集機器數量不多的場景,5臺左右

  資料分散叢集:多個伺服器組成叢集,每臺伺服器都會複製儲存部分資料,同時備份部分資料

    均衡性:保證資料分割槽基本均衡

    容錯性:出現故障時,將原來分配給故障伺服器的資料分割槽分配給其他伺服器

    可伸縮性:叢集容量不夠需要擴充時,能自動將部分資料分割槽遷移到新伺服器,並保證擴容後所有伺服器的均衡性

  

    適用於業務類巨大,機器機器數量龐大的業務場景

   資料分割槽:將資料安裝一定的故障進行分割槽,不同分割槽分佈在不同的地理位置上

    資料量:資料量大小直接決定了分割槽的規則複雜度

    分割槽規則:通過地理位置進行分割槽,包括洲際分割槽、國家分割槽、城市分割槽

    複製規則

      集中式備份:存在一個總的備份中心,所有的分割槽都將資料備份到中心

      擴充套件容易,成本較高

    互備式:每個分割槽備份到另外一個分割槽的資料

      設計複雜、擴充套件麻煩、成本低

    獨立式:每個分割槽自己有獨立的備份中心

      設計簡單,擴充套件容易,成本高

27如何設計計算高可用架構

 1哪些服務執行任務

  每個伺服器都執行、主機執行

2任務如何重新執行

  失敗不處理、工作管理員

3主備

  設計

  備機狀態

  使用場景:使用人數不多,頻率不高的業務,不適合線上業務

4.主從

  方案設計

  優缺點

5對稱叢集:每個伺服器角色一樣

  架構圖

  設計

    選擇分配策略:輪詢或隨機

    檢測伺服器狀態:心跳檢測

6.分對稱叢集:不同伺服器角色不同

  架構示意圖

  方案設計

  複雜度

28業務高可用的保障:異地多活架構

 1.活

2.代價

 

3.架構模式

  1. 同城同區:將業務部署在同一個城市不同區的多個機房
  2. 跨城異地:將業務部署在不同城市的多個機房,適用於資料丟失影響也不大的業務,例如使用者登入(可重新登入)、新聞網站(一天資料變化少)、微博網站(丟失使用者釋出的微博或者評論影響不大)
  3. 跨國異地:業務部署在不同國家的多個機房

 

4.為不同地區使用者提供服務

  例如亞馬遜中國為中國使用者服務,亞馬遜美國為美國使用者服務

5.只讀類業務做多活

  谷歌搜尋業務,各地搜尋結果相同

 29異地多活設計4大技巧

 1.保證核心業務的異地多活

 

  1.註冊問題:一個手機號註冊一個賬戶屬於核心業務規則,不建議修改

  2.使用者資訊問題:無法保證機器時間絕對一致

  3.解決方法:優先實現核心業務的異地多活結構

2.保證核心資料最終一致性

  1.儘量減少機房距離,搭建高速網路

  2.儘量減少資料同步,只同步核心業務相關的資料

  3.保證最終一致性,不保證實時一致性

3.採用多種手段同步資料

  1.訊息佇列方式:通過訊息佇列同步到其他業務中心

  2.二次讀取方式:本地讀取失敗,讀取對端

  3.儲存系統同步方式:通過資料庫的同步機制將資料複製到其他業務中心即可

  4.回源讀取方式

  5.重新生成資料方式

  6.綜合措施

4.只保證絕大部分使用者的異地多活

  1.掛公告:說明現在有問題的原因,可以釋出“技術給個正在緊急處理”

  2.事後對使用者進行補償:送一些業務上可用的代金券

  3.補充體驗

 

30  異地多活設計4步走

 1.業務分級:按照異地的表中將業務進行分級,挑選出核心的業務,只為核心業務設計異地多活,降低方案整體複雜度和實現成本

  訪問量大的業務、產生大量收入的業務

2.資料分類:識別所有的資料及資料特徵

  1.資料量:包括新增、修改、刪除的量,資料量越大,同步延遲的機率越高

  2.唯一性:資料是否要求多個異地機房產生的同類資料必須保證唯一

  3.實時性:實時性要求越高,對同步的要求就越高,方案越複雜

  4.可丟失性:例如session資料

  5.可恢復性:是否可以通過某種手段進行恢復

3.資料同步

  1.儲存式同步

  2.訊息佇列同步:常見的有Kafka、ActiveMQ、RocketMQ,適合無視我想或者無時序性要求的資料

  3.重複生成:資料不同步到異地機房,每個機房生成資料,適合可重複生成的資料,例如session

4.異常處理

  1目的:

  2.措施

    1.多通道同步:採取多種方式進行資料同步

      技術關鍵點:

    2.同步和訪問結合:異地機房通過系統的介面進行資料訪問

      技術關鍵點

     3.日誌記錄:用於使用者故障恢復後對資料進行恢復

      伺服器儲存日誌,資料庫儲存資料

      本地獨立系統儲存日誌

      日誌異地儲存

    4.使用者補償

31.如何應對介面級故障

 1.原因

  內部原因:程式bug死迴圈

  外包原因:黑客攻擊、促銷或者搶購

2.降級:系統將某些業務或者介面的功能降低,可以只提供部分功能,也可以完全停掉所有功能,丟車保帥,保證核心業務

  系統後門降級:系統預留降級操作

  獨立降級系統:將降級操作獨立到一個獨立的系統中

  熔斷:應對依賴的外部系統故障

3.限流:限制訪問量

  1.基於請求限流

    限制總量:限制某個指標的累計上限

    限制時間量:限制一段時間內某個指標的上限

    適用於:負載均衡系統、網關係統、搶購系統

  2.基於資源限流

  3.排隊:讓使用者等待一段時間

    架構圖

    排隊模組:負責使用者的搶購請求,將請求以先入先出的方式儲存下來

    排程模組:負責排隊模組到服務模組的動態排程,不斷檢查服務模組,一旦處理能力有空閒,就從列頭上吧使用者訪問請求調入服務模組,並負責想服務模組分發請求。

32.可擴充套件架構的基本思想和模式

 1.面向流程拆分

  1.分層含義

  2.架構

  3.優勢:大部分只需修改一層,不會出現所有層都同時修改

  4.典型架構:分層架構

2.面向服務拆分

  1.優勢:可以直接擴充套件相關服務,無須修改所有服務

  2.典型架構:SOA、微服務

3.面向功能拆分

  1.每個服務都可以拆分為更多細粒度的功能

  2.架構圖

  3.可以直接擴充套件功能,無須修改所有服務

  4.典型架構:微核心架構

33.傳統的可擴充套件的架構模式:分層架構和SOA

 1.C/S架構、B/S架構:

  劃分物件:整個業務系統

  劃分維度:使用者互動

2.MVC架構、MVP架構:

  劃分物件:單個業務系統

  劃分維度:職責

3.邏輯分層架構

  劃分物件:單個業務子系統或整個系統

  劃分維度:職責

   特定:層層傳遞、效能浪費

4.SOA面向服務的架構

  1.背景

  2.服務:所有業務都是一項服務,當其他系統需要使用這項功能時,無效定製化開發

  3.ESB(企業服務匯流排):將各個不同的服務連線在一起

  4.鬆耦合:減少各個服務間的依賴和互相影響

  5.架構圖

 

34深入理解微服務:銀彈or焦油坑

1.微服務是SOA的實現方式

2.微服務是去掉ESB的SOA

3.微服務是一種和SOA相似但本質上不同的架構理念

4.服務粒度:粒度較小

5.服務通訊:採用統一的協議和格式

6.服務支付:快速交付、自動化測試、持續整合、自動化部署

7.應用場景:適合快速、輕量級、基於web的網際網路系統

8.對比

9.大坑:

  1.服務劃分過細,服務間關係複雜

  2.服務數量太多,團隊效率急劇下降

  3.呼叫鏈太長,效能下降

  4.呼叫鏈太長,問題定位困難

  5.沒有自動化支撐,無法快速交付

  6.沒有服務治理,微服務數量多了後管理混亂

35.微服務架構最佳實踐-方法篇

 1.服務粒度

2.拆分方法

  1.基於業務邏輯拆分:將系統中的業務模組按照職責範圍識別處理,每個單獨的業務模組拆分為一個獨立的服務

  2.基於可擴充套件拆分:將系統中的業務模組按照穩定性排序,將已經成熟和改動不大的服務拆分為穩定服務,將經常變化和迭代的服務拆分為變動服務

  3.基於可靠性拆分:將系統中的業務模組按照優先順序排序,將可靠性要求高的核心服務和可靠性要求低的非核心服務拆分開來,然後重點保證核心服務的高可用