banner
xiaoya

xiaoya

從零開始學架構

從零開始學架構#

架構基礎#

概念#

  • 系統與子系統

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

    子系統也是由一群關聯的個體所組成的系統,多半是更大系統中的一部分。

    例如微信本身是一個系統,同時又包含聊天、支持、朋友圈等子系統。

    朋友圈這個系統又包含動態、評論、點讚等子系統。

  • 模組與元件

    軟體模組:是一套一致且互相有緊密關聯的軟體組織,它包含程式和資料結構兩部分。

    軟體元件:定義為自包含的、可編程、可重用的、與語言無關的軟體單元,軟體元件可以很容易地被用於組裝應用程式。

    例如學生資訊管理系統,從邏輯角度拆分,可以分為登入註冊模組、個人資訊模組、個人成績模組;從物理角度可以拆分成 nginx、web 伺服器、MySQL。

    • 從邏輯角度,拆分系統得到的就是模組
    • 從物理角度,拆分系統得到的就是元件
    • 劃分模組是為了職責分離,劃分元件為了單元重用。
  • 框架與架構

    軟體框架:為了實現某個業界標準或完成特定基本任務的軟體組織規範,也指為了實現某個軟體元件規範時,提供規範所要求之基礎功能的軟體產品。

    軟體架構:是指軟體系統的基礎結構,創造這些基礎結構的準則,以及對這些準則的描述。

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

架構設計的目的:為了解決複雜度帶來的問題。#

複雜度來源#

  • 高性能

    • 單機的複雜度

      • 考慮多進程、多線程、進程間通信、多線程並發等。
    • 集群的複雜度

      • 任務分配

        • 一個任務分配器多個業務伺服器,逐漸演變到多個任務分配器和多個業務伺服器。
      • 任務分解

        • 將複雜的業務系統拆分成小而簡單的多個系統配合的業務系統

        • 任務分解提升性能的原因

          • 簡單的系統更容易做到高性能
          • 可以針對單個任務進行擴展,也並且系統拆分越細越好,因為過多的子系統,使用者一次訪問需要多個迭代地調用,才能得到響應結果。
  • 高可用

    • 透過 “冗餘” 來實現高可用。

      • 計算高可用

      • 存儲高可用

      • 狀態決策高可用

        • 獨裁式:僅存在一個決策者,其他都是上報者。
        • 協商式:兩個獨立的個體通過交流資訊,然後根據規則進行決策。
        • 民主式:多個獨立的個體通過投票的方式進行狀態決策。
  • 可擴展性

    • 為了應對將來需求變化而提供的一種擴展能力,當有新的需求出現時,系統不需要或僅需要少量修改就可以支持,無需整個系統重構或重建。

      • 正確預測變化
      • 完美封裝變化
  • 低成本

    • 只有創新才能達到低成本目標

      • 例子

        • NoSQL (Redis,Memcache 等) 的出現是為了解決關係型資料庫無法應對高並發訪問帶來的訪問壓力。
        • 全文搜索引擎 (Sphinx、Elasticsearch、Solr) 的出現是為了解決關係型資料庫 like 搜索的低效問題。
        • Hadoop 的出現是為了解決傳統檔案系統無法應對海量資料存儲和計算的問題。
  • 安全

    • 功能安全

      • 常見的 XSS 攻擊、CSRF 攻擊、SQL 注入、Windows 漏洞、密碼破解等,本質上是因為系統存在漏洞,才讓駭客有機可乘。
    • 架構安全

      • 主要依靠防火牆,為隔離網路

        • DDos

          分佈式拒絕服務攻擊 (英文意思是 Distributed Denial of Service,簡稱 DDoS) 是指處於不同位置的多個攻擊者同時向一個或數個目標發動攻擊,或者一個攻擊者控制了位於不同位置的多台機器並利用這些機器對受害者同時實施攻擊。由於攻擊的發出點是分佈在不同地方的,這類攻擊稱為分佈式拒絕服務攻擊,其中的攻擊者可以有多個。

  • 規模

    • 功能越來越多,導致系統複雜度指數級上升
    • 資料越來越多,系統複雜度發生質變

架構設計原則#

合適原則:合適優於業務領先#

簡單原則:簡單優於複雜#

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

高性能架構#

存儲高性能#

  • 關係資料庫

    • 讀寫分離:將訪問壓力分散到集群中的多個節點,但是並沒有分散存儲壓力。

    • 分庫分表:既可以分散訪問壓力,又可以分散存儲壓力。

      • 業務分庫:分散存儲和訪問壓力

        • 引入問題

          • join 操作問題

            • 原本在同一資料庫的表分散到不同資料庫中,導致無法使用 SQL 的 join 查詢。
          • 事務問題

            • 原本在同一資料庫中不同的表可以在同一個事務中修改,業務分庫後,表分散到不同的資料庫中,無法通過事務統一修改。
          • 成本問題

            • 原來只需要 1 台伺服器就能處理的事情,可能需要擴展為 3 台或者更多。
      • 分表

        • 垂直分表:適合將表中某些不常用且佔了大量空間的列拆分出去。

          • 引入問題

            • 因為表資訊被分散到多個表中,導致原來一次查詢,現在可能需要 2 次或者更多。
        • 水平分表:適合表行資料特別大的表,例如單表行記錄超過 5000 萬條。

          • 引入問題

            • 路由:水平分表後,某條資料具體屬於哪個切分後的子表,需要增加路由算法進行計算

              • 範圍路由
              • Hash 路由
              • 配置路由
            • count () 操作

              • 原始對表進行 count () 操作,切分後需要 表個數 * count (*)
            • 記錄數表

              • 新建一張表,記錄每次插入或刪除子表資料後,表的記錄數。
    • 實現方法

      • 程式碼封裝:在程式碼中抽象一個資料訪問層來實現讀寫分離、分庫分表

      • 中介軟體封裝:獨立一套系統出來,實現讀寫分離和分庫分表操作

      • 實現複雜度:分庫分表比讀寫分離要複雜得多。

        • 讀寫分離實現時,只需識別 SQL 操作是讀操作還是寫操作介面,即通過關鍵字 SELECT、UPDATE、INSERT、DELETE 就可以判斷。
        • 分庫分表除了要判斷操作類型,還需要判斷 SQL 中具體要操作的表、操作函數(count、order by、group by),然後根據不同的操作進行不同的處理。
    • 存在缺點

      • 關係資料庫存儲的是行記錄,無法存儲資料結構
      • 關係資料庫的表結構 schema 擴展很不方便
      • 關係資料庫在大資料場景下 I/O 較高
      • 關係資料庫的全文搜索功能比較弱
  • NoSQL

    • 關係資料庫

    • NoSQL 的本質是犧牲 ACID 特性中的某個或某些特性,作為關係資料庫的補償。

    • 常用的 NoSQL 方案有如下 4 類

      • K-V 存儲:解決關係資料庫無法存儲資料結構的問題,以 Redis 為代表。

      • 文檔資料庫:解決關係資料庫強 schema 約束的問題,以 MongoDB 為代表。

        文檔資料庫最大特點是 no-schema, 可以存儲和讀取任意的資料,資料格式一般為 JSON.

        優勢:

        新增欄位簡單;

        歷史資料不會出錯;

        可以很容器存儲複雜資料。

      • 列式資料庫:解決關係資料庫大資料場景下 I/O 問題,以 HBase 為代表。

        例如,統一某城市超重人員的數量,只需讀取體重這一列的資料即可。

      • 全文搜索引擎:解決關係資料庫的全文搜索性能問題,以 Elasticsearch 為代表。

  • 快取

    • 基本原理:將可能重複使用的資料放到記憶體中,一次生成,多次使用,避免每次使用都去訪問存儲系統。

    • 面臨的問題

      • 快取穿透:訪問了快取中不存在的資料,導致業務系統需要再次訪問資料庫,導致對資料庫伺服器造成壓力。
      • 快取擊穿:單個高熱資料過期的瞬間,資料訪問量較大,未命中快取後,發起了大量對同一資料的資料庫訪問,導致對資料庫伺服器造成壓力
      • 快取預熱:系統啟動前,提前將相關的快取資料直接加載到快取系統。
      • 快取雪崩:由於大量的熱資料設置了相同或接近的過期時間,導致快取在某一時刻密集失效,大量請求全部轉發到 DB,導致存儲系統受到巨大壓力,最終導致系統崩潰

計算高性能#

  • 單伺服器高性能

    • PPC (Process per Connection),每次有新的連接就新建一個進程專門處理這個連接的請求。

    • prefork:提前創建進程,便於後續直接使用

    • TPC (Thread per Connection),每次有新的連接就新建一個線程專門處理這個連接的請求。

    • prethread:提前創建線程,便於後續直接使用

    • Reactor (非阻塞同步網路模型):核心組件包括 Reactor 和處理資源池,其中 Reactor 負責監聽和分配事件,處理資源池負責處理事件。

      • 1. 父進程中 mainReactor 物件通過 select 監控連接建立事件,收到事件後通過 Acceptor 接收,將新的連接分配給某個子進程。
      • 2. 子進程 subReactor 將 mainReactor 分配的連接加入連接隊列進行監聽,並創建一個 Handler 用於處理連接的各種事件。
      • 3. 當有新的事件發生時,subReactor 會調用連接對應的 Handler 來進行響應。
      • 4.Handler 完成 read ——> 業務處理 ——> send 的完整業務流程。
      • 圖片
    • Proactor (異步網路模型):核心組件包括 Proactor 和異步操作處理器。

      • 1.Proactor Initiator 負責創建 Proactor 和 Handler,並將 Proactor 和 Handler 都通過 Asynchronous Operation Processor 註冊到內核。
      • 2.Asynchronous Operation Processor 負責處理註冊請求,並完成 I/O 操作。
      • 3.Asynchronous Operation Processor 完成 I/O 操作後通知 Proactor。
      • 4.Proactor 根據不同的事件類型回調不同的 Handler 進行業務處理。
      • 5.Handler 完成業務處理,Handler 也可以註冊新的 Handler 到內核進程。
      • 圖片
  • 集群高性能

    • 本質:通過增加更多的伺服器來提升系統整體的計算能力

    • 複雜性:增加任務分配器,以及選擇一個合適的任務分配算法。(任務分配器,更通俗的叫法是 負載均衡器)

    • 負責均衡分類

      • DNS 負載均衡:實現地理級別的負載均衡。例如北方使用者訪問北京的機房;南方使用者訪問深圳的機房。
      • 硬體負載均衡:通過單獨的硬體設備來實現集群級別的負載均衡。這類設備和路由器交換機類似,可以理解為一個用於負載均衡的基礎網路設備。
      • 軟體負載均衡:通過負載均衡軟體實現機器級別的負載均衡。
    • 負載均衡架構

      • 實際使用的時候,可以靈活地使用上述三種負載均衡方法,首先通過 DNS 負載均衡找到最近城市的伺服器 ip, 通過硬體負載均衡找到城市對應的集群組,最後通過軟體負載均衡在集群組內找到所需的集群。
    • 負載均衡的算法

      • 任務平分類:輪詢、加權輪詢
      • 負載均衡類:負載最低優先
      • 性能最優類:響應時間最短優先
      • Hash 類:根據任務的某些關鍵資訊進行 hash 運算,從而映射到指定主機

高可用架構#

CAP#

  • CAP 理論
  • BASE 理論

高可用的本質是通過冗餘來實現#

存儲高可用#

  • 常用的高可用存儲架構有主備、主從、主主、集群、分區。

    • 主備複製:客戶端的操作都是通過主機完成,備機僅起到備份作用,不參與實際業務讀寫操作。

    • 主從複製:主機負責讀寫操作,從機只負責讀操作,不負責寫操作。

    • 主備倒換與主從倒換

      • 設計關鍵

        • 1. 主備間狀態判斷:包括狀態傳遞的渠道和狀態檢測的內容。
        • 2. 倒換決策:倒換時機、倒換策略、自动程度。
        • 3. 資料衝突解決:故障主機恢復後,資料如何同步。
      • 常見架構

        • 互連式:主備直接建立狀態傳遞的渠道。
        • 中介式:主備機之間不直接連接,而都去連接中介,並且通過中介來傳遞狀態資訊。
        • 模擬式:主備之間並不傳遞任何狀態資料,而是備機模擬成一個客戶端,向主機發起模擬的讀寫操作,根據讀寫的響應情況來判斷主機的狀態。
    • 主主複製

      • 概念:兩台主機都是主機,互相將資料複製給對方,客戶端可以任意挑選其中的一台機器進行讀寫操作。
      • 很多資料不能雙向複製:例如使用者註冊 ID、庫存等。
    • 資料集群

      • 概念:集群就是多台機器組合在一起形成一個統一的系統。(主備、主從、主主架構本質上隱含一個假設:主機能夠存儲所有資料。)

      • 集群分類

        • 資料集中集群

        • 資料分散集群

          • Elasticsearch 集群
      • 分佈式事務算法

        • 目的:保證分散在多個節點上的資料統一提交或回滾,以滿足 ACID 要求。

        • 二階段提交 (Two-Phase Commit Protocol,2PC)

          • Commit 請求階段和 Commit 提交階段
        • 三階段提交 (Three-Phase Commit Protocol,3PC)

          • 提交判斷階段;提交準備階段;提交執行階段。(針對二階段提交算法存在的單點故障問題,引入準備階段,當協調者故障後,參與者可以通過超時提交來避免一直阻塞。)
      • 分佈式一致性算法

        • 目的:保證同一份資料在多個節點上的一致性

        • 機制:複製狀態機

          • 副本:多個分佈式伺服器組成一個集群,每個伺服器都包含完整狀態機的一個副本。
          • 狀態機:狀態機接受輸入,然後執行操作,將狀態改變為下一個狀態。
          • 算法:使用算法來協調各個副本的處理邏輯,使得副本的狀態機保持一致。
        • 算法:Paxos、Raft、ZAB

    • 資料分區

      • 概念:指將資料按照一定的規則進行分區,不同分區分佈在不同的地理位置上,每個分區存儲一部分資料,通過這種方式來規避地理級別的故障所造成的巨大影響。

      • 需要考慮的問題

        • 資料量:資料量越大,分區規則會越複雜,考慮的情況也越多。

        • 分區規則:洲際分區、國家分區、城市分區

        • 複製規則

          • 集中式:存在一個總的備份中心,所有分區的資料備份到備份中心。
          • 互備式:每個分區備份另外一個分區的資料。
          • 獨立式:每個分區自己有獨立的備份中心。

計算高可用#

  • 主備

    • 冷備:備機業務未啟動
    • 熱備:備機業務已啟動
  • 主從

  • 對稱集群:集群中每個伺服器的角色一致,可以執行所有任務。

  • 非對稱集群:集群中的伺服器分為多個不同的角色,不同的角色執行不同的任務。

業務高可用#

  • 異地多活

    • 目的:應對系統級的故障。

    • 架構:同城異區、跨城異地、跨國異地。

    • 設計技巧

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

      • 2. 核心資料的最終一致性

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

        • 訊息隊列
        • 二次讀取
        • 存儲系統同步
        • 回溯讀取
        • 重新生成資料方式
      • 4. 只保證絕大部分使用者的異地多活

    • 設計步驟:業務分級、資料分類、資料同步、異常處理

  • 介面級的故障應對方案

    • 降級:將某些業務或介面的功能降低,可以是只提供部分功能,也可以是完全停掉所有功能。

      • 系統後門降級
      • 獨立降級系統
    • 熔斷:通過設定閾值,來應對依賴的外部系統故障的情況。

    • 限流:只允許系統能夠承受的訪問量進入,超出部分的請求將丟棄。

      • 基於請求限流
      • 基於資源限流
    • 排隊:讓使用者等待很長時間,才能得到處理或長時間等待後仍然無法得到響應。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。