iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
Build on AWS

AWS架構師的自我修養:30天雲端系統思維實戰指南系列 第 21

Day 11-7 | 資料庫設計哲學:需求解析、技術選型與 Schema 設計策略(七) - 核心設計策略AWS實戰解析:微服務資料庫模式

  • 分享至 

  • xImage
  •  

7. 微服務資料庫模式

有沒有覺得很奇怪。在討論 微服務資料庫模式之前,我們已經在前面的諸多核心設計策略中討論到它了,微服務資料庫模式究竟何德何能得以成為一種設計策略? 為什麼它不是一種單純的工具模式?

我們換個場景,這次我們不談圖書館,我們來經營一家現代化的專業餐廳廚房(餐廳名稱叫做 OverCook) - 一個在討論系統設計時最常被舉例的案例 : 服務生-API <=> 系統-廚房 <=> 資料庫-冰箱。

為什麼 微服務資料庫模式 本身也是一個「核心策略」? 看起來明明像是其他策略的「應用」?

這是因為,在開一家餐廳前,主廚(架構師)第一個要做的 戰略決策,不是「該買哪一把刀」,而是 「這家餐廳的廚房應該如何組織?」 。我們當然可以用 單體式(Monolith) 的要求廚房內的所有夥伴十項全能,每個人都能負責從洗菜、切菜、炒菜、燉湯到甜點的所有工作,但這樣子成本太高了,切換不同工作內容前的前置作業(記憶體、緩存還原)、環境整潔(VM integration)都必須要確保所有流程 不會出錯!

這是非常重要的議題,要注意,我們選擇 單體式(Monolith) 的時候也意味著: 一旦廚房失火,或是將沒有依照標準預製的惡臭前置備料放入冰箱(資料庫),可能整個餐廳流程瞬間爆炸。最終我們面對的是餐廳破產宣告與川流不息的客訴信件。

但假如我們建立一個由多個專業站點組成的廚房團隊。有專門的「冷盤站」、專門的「燒烤站」、專門的「醬汁站」和專門的「甜點站」。一旦單一服務出現問題,我們可以立即隔離排除並嘗試重新啟動或清空資料庫。

「微服務資料庫模式」 不是與其他策略並列的工具,它是驅動和包含其他策略的頂層藍圖,關於運作效能風險承擔能力服務成本 的權衡核心策略 。

核心哲學:**權力下放與領域自治 (Decentralized Data Ownership & Domain Autonomy)**
抽象概念:從「共享大冰箱」到「各站點的專業工具箱」

傳統單體式架構的哲學是「中央集權」,所有資料都由一個中央資料庫統一管理。而微服務資料庫模式的核心哲學恰好相反,它是「權力下放」。它主張資料的所有權和責任,應該與其所屬的 業務領域(Domain)緊密綁定

換句話說,用戶服務 就應該是「用戶資料」的唯一主人和權威,訂單服務 就應該是「訂單資料」的唯一主人和權威。任何其他服務都無權直接碰觸不屬於自己的資料。這是一種資料應用設計上的資料 邊界化責任制 ,而非單純技術上的統一。

想像一下廚房的運作模式:

  • 單體式架構: 整個廚房共享一個巨大、混亂的中央大冰箱(Shared Database)。燒烤師傅的生肉、甜點師傅的奶油、冷盤師傅的生魚片全都塞在一起。當甜點師傅想調整冰箱溫度時,可能會導致生肉變質,引發災難。
  • 微服務架構: 每個專業站點(燒烤站、甜點站)都有自己 專屬的、為其任務優化的工具箱與小型備料冰箱 (Database per Service) 。燒烤站有高溫烤架,甜點站有恆溫烤箱。它們各自管理自己的食材,互不干擾。

這個抽象概念就是:為每個獨立的業務能力,配備一套獨立的、客製化的資料管理方案。

要實現這種「權力下放」的哲學,必須遵循以下幾條不可逾越的設計原則:

  1. 每個服務一個資料庫叢 (Database per Service)
  • 原則:這是黃金準則。每個微服務必須擁有自己私有的持久化儲存。絕不允許多個服務共享同一個資料庫 Schema,甚至同一個資料庫實例。
  • 哲學:每個站點(服務)擁有自己獨立的工具和備料(資料庫)。我們不會強迫甜點師傅用烤肉的鐵板來做舒芙蕾,因為他們的「領域」需求完全不同。燒烤站關心肉的熟度,甜點站關心麵粉的筋度。
  • 目的:確保服務之間的松耦合 (Loose Coupling)。讓每個團隊可以獨立地選擇最適合其業務的資料庫技術(SQL, NoSQL, Graph...),並能獨立地修改、演進自己的資料模型,而無需通知或協調其他團隊。
  1. 只能透過 API 進行通訊 (Communication Through APIs Only)
  • 原則:一個服務如果需要另一個服務的資料,必須透過該服務公開的 API 來請求,嚴禁直接跨服務連接資料庫。
  • 哲學:所有的需求必須嚴格依照流程與規範說法進行資料間的應用,冰箱中寫著 "鹽巴" 罐子,我們無法確保裡面的內容物真的是 "鹽巴",可能已經被重新調整風味過程為了松露鹽,也有可能早就用來裝糖了 - 這可能是上一個違反規定直接查找資料庫的人更新後的內容
  • 目的:保護服務的封裝性 (Encapsulation)。API 是服務之間公開的「合約」,確保了資料的存取是有管理的、安全的、可監控的。直接存取資料庫等於是「從後門闖入」,破壞了所有的規則和自治權。
  1. 擁抱最終一致性 (Embrace Eventual Consistency)
  • 原則:對於需要跨越多個服務的業務流程(例如:下訂單同時需要扣庫存和處理支付),放棄傳統的跨資料庫 ACID 事務。轉而使用 Saga、事件溯源 等模式來協調。
  • 哲學:一位客人點了一份「海陸大餐」,包含一份牛排和一份龍蝦。這需要「燒烤站」和「海鮮站」協同工作,這不是一個單一同步的動作,它是一個由多個獨立步驟組成的「故事 (Saga)」。
  • 目的:在分散式系統中實現彈性 (Resilience) 和可擴展性 (Scalability)。我們放棄了讓所有站點同時鎖定資源的「強一致性事務」,接受系統在極短時間內可能存在狀態不一致,但保證透過異步事件的「事件」和「補償」處理,最終會達到正確的、一致的狀態。

資料庫拆分策略

  • 依據業務域拆分

    • 用戶服務:用戶基本資料、認證資訊
    • 訂單服務:訂單、支付、物流
    • 商品服務:商品目錄、庫存、價格
    • 推薦服務:用戶行為、推薦演算法
  • 跨服務資料一致性

    • Saga 模式:分散式事務協調
    • 事件溯源:異步最終一致性
    • 補償模式:失敗回滾機制

AWS 實現微服務資料庫架構設計

微服務資料庫模式在現實世界中有許多成功的應用案例,這是微服務架構的基石,現代化的大型應用大多都會使用此模式。

情境一:電商平台

# 典型的電商平台微服務拆分
服務劃分 = {
    "用戶服務": {
        "職責": "用戶註冊、登入、個人資料管理",
        "資料庫": "PostgreSQL (ACID 保證用戶資料一致性)",
        "核心資料": ["用戶基本資料", "認證資訊", "偏好設定"]
    },
    "商品服務": {
        "職責": "商品目錄、搜尋、分類管理",
        "資料庫": "Elasticsearch (快速全文搜尋)",
        "核心資料": ["商品資訊", "分類標籤", "搜尋索引"]
    },
    "訂單服務": {
        "職責": "訂單建立、狀態追蹤、歷史記錄",
        "資料庫": "DynamoDB (高併發寫入能力)",
        "核心資料": ["訂單詳情", "交易記錄", "物流狀態"]
    },
    "庫存服務": {
        "職責": "庫存管理、庫存扣減、補貨通知",
        "資料庫": "Redis + PostgreSQL (快取 + 持久化)",
        "核心資料": ["實時庫存", "預留庫存", "補貨計畫"]
    },
    "推薦服務": {
        "職責": "個性化推薦、用戶行為分析",
        "資料庫": "Neo4j (圖形資料庫處理關係)",
        "核心資料": ["用戶行為圖譜", "商品關聯性", "推薦演算法模型"]
    }
}

情境二:金融科技平台

# 金融科技平台的微服務架構
金融服務劃分 = {
    "帳戶服務": {
        "職責": "帳戶開立、KYC、帳戶狀態管理",
        "資料庫": "PostgreSQL (強一致性需求)",
        "合規要求": "符合金融監管,資料不可遺失"
    },
    "交易服務": {
        "職責": "轉帳、支付、交易記錄",
        "資料庫": "PostgreSQL + Redis (ACID + 高速處理)",
        "特殊需求": "支援高併發、防止重複扣款"
    },
    "風控服務": {
        "職責": "風險評估、異常檢測、反洗錢",
        "資料庫": "Neo4j + ClickHouse (關係分析 + 時序分析)",
        "核心能力": "實時風險計算、關聯性分析"
    },
    "報表服務": {
        "職責": "財務報表、監管報告、分析儀表板",
        "資料庫": "ClickHouse (OLAP 分析型資料庫)",
        "資料來源": "從其他服務異步匯聚資料"
    }
}

情境三:IoT 物聯網平台

# IoT 平台的微服務與資料分層策略
IoT服務架構 = {
    "設備管理服務": {
        "職責": "設備註冊、狀態監控、韌體更新",
        "資料庫": "MongoDB (彈性 Schema 適應不同設備)",
        "挑戰": "設備類型多樣化、Schema 經常變更"
    },
    "數據收集服務": {
        "職責": "即時數據接收、數據驗證、初步處理",
        "資料庫": "InfluxDB (時序資料庫)",
        "特性": "高寫入吞吐量、時間序列優化"
    },
    "分析服務": {
        "職責": "數據分析、趨勢預測、異常檢測",
        "資料庫": "ClickHouse + S3 (冷熱分層)",
        "架構": "熱數據快速查詢、冷數據長期儲存"
    },
    "通知服務": {
        "職責": "告警通知、狀態推送、報告生成",
        "資料庫": "Redis (快速讀寫緩存)",
        "整合": "與消息佇列深度整合"
    }
}

以下是在 AWS 雲端平台上實現微服務資料庫模式的具體架構設計:

graph TB
    subgraph "客戶端層 (Client Layer)"
        A1[Web App]
        A2[Mobile App]
        A3[Third Party API]
    end

    subgraph "API 閘道層 (API Gateway Layer)"
        B[Amazon API Gateway]
        B --> B1[認證授權]
        B --> B2[請求路由]
        B --> B3[限流控制]
    end

    subgraph "微服務層 (Microservices Layer)"
        C1[🔐 用戶服務<br/>AWS Lambda]
        C2[🛍️ 商品服務<br/>AWS Lambda]
        C3[📋 訂單服務<br/>AWS Lambda]
        C4[📦 庫存服務<br/>AWS Lambda]
        C5[🤖 推薦服務<br/>AWS Lambda]
    end

    subgraph "資料庫層 (Database Layer)"
        D1[🐘 Amazon RDS<br/>PostgreSQL<br/>用戶資料]
        D2[🔍 Amazon OpenSearch<br/>商品搜尋]
        D3[⚡ Amazon DynamoDB<br/>訂單資料]
        D4[💾 Redis Cluster<br/>庫存緩存]
        D5[🕸️ Amazon Neptune<br/>推薦圖譜]
    end

    subgraph "事件驅動層 (Event-Driven Layer)"
        E1[📨 Amazon EventBridge<br/>事件總線]
        E2[📬 Amazon SQS<br/>訂單佇列]
        E3[📬 Amazon SQS<br/>庫存佇列]
        E4[📬 Amazon SQS<br/>通知佇列]
    end

    subgraph "數據分析層 (Analytics Layer)"
        F1[📊 Amazon Kinesis<br/>實時數據流]
        F2[🏠 Amazon S3<br/>數據湖]
        F3[🔧 AWS Glue<br/>ETL 處理]
        F4[📈 Amazon QuickSight<br/>商業智慧]
    end

    subgraph "監控與安全層 (Monitoring & Security)"
        G1[📋 Amazon CloudWatch<br/>監控日誌]
        G2[🔒 AWS IAM<br/>身份權限]
        G3[🚨 AWS X-Ray<br/>分散式追蹤]
    end

    %% 客戶端到API Gateway
    A1 --> B
    A2 --> B
    A3 --> B

    %% API Gateway 到微服務
    B --> C1
    B --> C2
    B --> C3
    B --> C4
    B --> C5

    %% 微服務到對應資料庫
    C1 --> D1
    C2 --> D2
    C3 --> D3
    C4 --> D4
    C5 --> D5

    %% 事件驅動通訊
    C3 --> E1
    E1 --> E2
    E1 --> E3
    E1 --> E4
    E2 --> C4
    E3 --> C5
    E4 --> C1

    %% 數據分析流
    C1 --> F1
    C2 --> F1
    C3 --> F1
    F1 --> F2
    F2 --> F3
    F3 --> F4

    %% 監控整合
    C1 --> G1
    C2 --> G1
    C3 --> G1
    C4 --> G1
    C5 --> G1

    %% 安全整合
    B --> G2
    C1 --> G3
    C2 --> G3
    C3 --> G3
    C4 --> G3
    C5 --> G3

    classDef clientStyle fill:#e1f5fe
    classDef gatewayStyle fill:#f3e5f5
    classDef serviceStyle fill:#e8f5e8
    classDef databaseStyle fill:#fff3e0
    classDef eventStyle fill:#fce4ec
    classDef analyticsStyle fill:#f1f8e9
    classDef monitoringStyle fill:#fff8e1

    class A1,A2,A3 clientStyle
    class B,B1,B2,B3 gatewayStyle
    class C1,C2,C3,C4,C5 serviceStyle
    class D1,D2,D3,D4,D5 databaseStyle
    class E1,E2,E3,E4 eventStyle
    class F1,F2,F3,F4 analyticsStyle
    class G1,G2,G3 monitoringStyle

跨服務交易的 Saga 模式實現

sequenceDiagram
    participant Client as 客戶端
    participant API as API Gateway
    participant Order as 訂單服務
    participant Inventory as 庫存服務
    participant Payment as 支付服務
    participant Notification as 通知服務
    participant EventBridge as EventBridge
    participant SQS1 as SQS-庫存佇列
    participant SQS2 as SQS-支付佇列
    participant SQS3 as SQS-通知佇列

    Client->>API: 提交訂單請求
    API->>Order: 建立訂單
    Order->>Order: 保存訂單 (狀態: PENDING)

    Order->>EventBridge: 發布 OrderCreated 事件
    EventBridge->>SQS1: 路由到庫存佇列
    EventBridge->>SQS2: 路由到支付佇列

    SQS1->>Inventory: 處理庫存扣減
    alt 庫存充足
        Inventory->>Inventory: 扣減庫存
        Inventory->>EventBridge: 發布 InventoryReserved 事件
    else 庫存不足
        Inventory->>EventBridge: 發布 InventoryFailed 事件
        EventBridge->>Order: 觸發訂單取消補償
    end

    SQS2->>Payment: 處理支付
    alt 支付成功
        Payment->>Payment: 完成扣款
        Payment->>EventBridge: 發布 PaymentCompleted 事件
        EventBridge->>Order: 更新訂單狀態為 CONFIRMED
        EventBridge->>SQS3: 路由到通知佇列
        SQS3->>Notification: 發送確認通知
    else 支付失敗
        Payment->>EventBridge: 發布 PaymentFailed 事件
        EventBridge->>Inventory: 觸發庫存釋放補償
        EventBridge->>Order: 觸發訂單取消補償
    end

這個架構設計體現了微服務資料庫模式的核心優勢:

  1. 服務自治:每個服務選擇最適合的資料庫技術
  2. 松耦合:透過事件驅動實現服務間的異步通訊
  3. 可擴展性:各服務可獨立擴展
  4. 容錯性:單一服務故障不影響整體系統
  5. 技術多樣性:不同服務可使用不同的技術棧

上一篇
Day 11-6 | 資料庫設計哲學:需求解析、技術選型與 Schema 設計策略(六) - 核心設計策略AWS實戰解析:冷熱資料分層 -以TSMC晶圓IoT、LLM Training為例
下一篇
Day 11-8 | 資料庫設計哲學:需求解析、技術選型與 Schema 設計策略(八) - 核心設計策略AWS實戰解析:圖資料庫設計思維 - 以Uber Eats Neptune架構為例
系列文
AWS架構師的自我修養:30天雲端系統思維實戰指南28
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言