從關聯式資料庫到分散式系統:演進的四個階段(增強版)

從關聯式資料庫到分散式系統:演進的四個階段(增強版)

前言

在現代軟體開發中,從傳統的關聯式資料庫(RDBMS)轉向分散式系統是一個常見的挑戰。這種轉變並非一蹴可幾,而是經歷了多個階段的演進。本文將詳細闡述這個過程中的四個關鍵階段,從系統設計、資料分割、部署策略到組織結構的變革。這不僅是技術的演進,更是思維模式的轉變。

第一階段:單體式架構與中央化資料庫

特徵

  • 應用程式:單體式架構(Monolithic Architecture)。所有功能模組,如使用者管理、產品目錄、訂單處理等,都集中在一個龐大的程式碼庫中。
  • 資料庫:單一的中央化關聯式資料庫(如 MySQL、PostgreSQL)。這是系統中唯一的資料來源(Single Source of Truth)。
  • 部署:應用程式和資料庫通常部署在同一台或少數幾台伺服器上。擴展(Scaling)主要是透過垂直擴展(Vertical Scaling),即增加單一伺服器的硬體資源(如 CPU、記憶體)來實現。

優點

  • 開發簡單:所有開發人員都在同一個程式碼庫中工作,易於協調和管理。
  • 資料一致性強:ACID(原子性、一致性、隔離性、持久性)交易得到完全保障,資料操作相對簡單。
  • 部署直接:只需部署一個應用程式,流程清晰。

挑戰

  • 擴展性受限:垂直擴展有其物理極限,且成本高昂。資料庫的寫入操作成為效能瓶頸。
  • 開發效率下降:隨著業務邏輯日益複雜,單體應用變得臃腫,修改一小部分功能可能影響全局,導致開發和測試週期變長。
  • 技術債累積:單一的技術棧難以適應所有業務需求,新技術的引入變得困難。
  • 可靠性低:任何一個模組的故障都可能導致整個系統崩潰。

第二階段:服務導向架構(SOA)與資料庫讀寫分離

隨著業務量的增長,單體架構的瓶頸日益凸顯。為了應對這些挑戰,系統開始向服務導向架構(SOA)演進。

架構演變

  • 應用程式解耦:單體應用被拆分成多個獨立的服務,每個服務對應一組相關的業務功能(例如,使用者服務、訂單服務)。這些服務透過定義良好的 API(如 RESTful API)進行通訊。
  • 資料庫讀寫分離:為了緩解資料庫的讀取壓力,引入了讀寫分離(Read-Write Splitting)機制。
    • 主資料庫(Master):處理所有寫入操作(INSERT, UPDATE, DELETE)。
    • 從資料庫(Slave):複製主資料庫的資料,處理所有讀取操作(SELECT)。
    • 資料複製通常是異步的,這會帶來最終一致性(Eventual Consistency)的挑戰。

資料庫層面的挑戰

  • 資料延遲:主從複製的延遲(Replication Lag)可能導致剛寫入的資料無法立即被讀取到,需要應用程式層面進行適當的處理(例如,對於某些關鍵操作,強制從主資料庫讀取)。
  • 單點故障:主資料庫仍然是單點,一旦發生故障,整個系統的寫入功能將會中斷。

部署與維運

  • 服務可以獨立部署,提高了靈活性。
  • 然而,服務的數量增加,使得部署和監控變得更加複雜。DevOps 的概念開始受到重視。

第三階段:微服務與資料庫去中心化

SOA 在一定程度上解決了問題,但隨著服務粒度的進一步細化,系統逐漸演變為微服務架構(Microservices Architecture)。

微服務的崛起

  • 服務粒度更細:每個微服務只專注於一項單一的業務功能,做到「高內聚、低耦合」。
  • 獨立資料儲存:這是與 SOA 最顯著的區別之一。每個微服務擁有自己獨立的資料庫,其他服務不能直接存取其資料庫,只能透過該服務提供的 API 進行互動。
  • 技術異構性:團隊可以為自己的微服務選擇最適合的技術棧(語言、框架、資料庫)。例如,使用者服務可能使用關聯式資料庫,而日誌服務則可能使用 NoSQL 資料庫如 Elasticsearch。

資料庫去中心化的實踐

  • 按業務領域分割:資料庫根據業務領域(Business Domain)進行垂直分割。例如,訂單資料庫和使用者資料庫被完全分開。
  • NoSQL 的引入:對於需要高擴展性和靈活性的場景,如社交網路的動態、物聯網的感測器資料等,開始大量採用 NoSQL 資料庫(如 Cassandra, MongoDB)。

挑戰

  • 分散式交易:跨多個微服務的資料一致性成為一個巨大的挑戰。傳統的兩階段提交(Two-Phase Commit, 2PC)因效能問題在微服務中很少使用。取而代之的是基於最終一致性的模式,如 Saga 模式或事件溯源(Event Sourcing)。
  • 服務治理:服務發現、負載平衡、熔斷機制、分散式追蹤等問題變得至關重要,需要引入如 Consul, Istio, Jaeger 等複雜的基礎設施。
  • 資料聚合:當需要跨多個服務進行資料查詢和報表分析時,資料聚合變得非常困難。通常需要建立一個獨立的資料倉儲或資料湖來解決這個問題。

第四階段:分散式資料庫與雲原生架構

微服務解決了應用層的擴展性問題,但單個微服務的資料庫本身仍然可能成為瓶頸。第四階段的演進核心是解決資料層的水平擴展問題,並全面擁抱雲原生。

資料庫的水平擴展

  • 資料庫分片(Sharding):當單一資料庫的資料量和寫入負載達到極限時,需要對資料庫進行水平分割,即分片。
    • 分片鍵(Shard Key):選擇一個合適的欄位(如 user_id, order_id)作為分片鍵,根據一定的規則(如 HASH 或 RANGE)將資料分佈到不同的資料庫實例(分片)上。
    • 中間層代理:通常需要一個資料庫中間層(如 ProxySQL, TiDB)來處理分片邏輯,對應用程式透明化底層的資料庫分佈。

分散式資料庫的興起

  • 與其自行管理複雜的分片邏輯,不如直接採用原生支援水平擴展的分散式資料庫。
  • NewSQL 資料庫:如 Google Spanner, CockroachDB, TiDB,它們既保留了關聯式資料庫的 ACID 特性,又具備 NoSQL 的高擴展性。
  • 特定用途的分散式資料庫:如時間序列資料庫 InfluxDB,圖資料庫 Neo4j,滿足特定場景的需求。

全面雲原生化

  • 容器化與編排:使用 Docker 進行應用程式封裝,使用 Kubernetes (K8s) 進行大規模容器編排,實現自動化的部署、擴展和管理。
  • 基礎設施即程式碼(IaC):使用 Terraform, Ansible 等工具,以程式碼的方式管理和配置所有基礎設施資源,實現版本控制和可重複性。
  • 無伺服器(Serverless):對於事件驅動的輕量級計算,採用 AWS Lambda, Google Cloud Functions 等,進一步降低維運成本。

組織與文化的演變

  • DevOps 文化深入人心:開發(Dev)和維運(Ops)團隊緊密協作,共同對產品的整個生命週期負責。
  • SRE(網站可靠性工程):引入 SRE 角色,用軟體工程的方法來解決維運問題,設定服務等級目標(SLO),並管理錯誤預算(Error Budget)。
  • 去中心化團隊:「你建的,你來跑(You build it, you run it)」。每個微服務團隊都是一個全功能的團隊,擁有從開發到部署、維運的全部自主權。
📝
Source History
🤖
Analyze with AI