跳至主要内容

30 篇文章 含有標籤「系統設計」

從需求拆解到架構設計、擴展與維運

檢視所有標籤

系統設計系列文18:Database Sharding

· 閱讀時間約 7 分鐘
阿昇
Software Engineer

Day 17 用 CAP Theorem 收尾時提到一句話:這條線會一路貫穿到後面 Sharding、Counter System 這些主題。今天就從 Sharding 開始。

回顧一下 Day 7 做的事:把一個 Database 拆成 Primary 跟多個 Read Replica。

Day 7 的 Primary / Replica Database 架構圖

當時特別澄清過一件事:這樣做還稱不上 Database 的 Horizontal Scaling,因為每個 Replica 裡面裝的都是同一份完整資料。

這代表兩件事還是沒解決:

  1. 寫入量還是被單一 Primary 卡死——不管加幾個 Replica,所有 Write 永遠只能走那一台 Primary,寫入吞吐量的天花板從頭到尾沒變過。
  2. 儲存空間還是受限於單一台機器——如果 PokeThreads 的 Post 表膨脹到幾十億筆,就算 Primary 本身的硬碟塞得下,索引大小、查詢效能也會開始出問題。

Replication 解決的是「太多人同時讀」,但沒解決「資料量太大、寫入太多」,這是 Sharding 要處理的問題。

系統設計系列文17:CAP Theorem - 你無法全都要

· 閱讀時間約 9 分鐘
阿昇
Software Engineer

昨天討論 SQL 該不該換成 NoSQL,最後留下一個疑問,一旦資料開始分散在不同種類的 Storage 上,SQL、NoSQL、Cache 各存一部分。

怎麼確保各處看到的資料是一致的?

現在狀況只會比 Day 7 那種單純的 Primary/Replica 架構更複雜,其實這個問題在當時就已經埋下種子了。當時我們用 Database Replication 解決 Read Scaling:

Day 7 的 Primary / Replica Database 架構圖

留下一個沒細講的伏筆——Replication Lag:Squirtle 剛發的文章,可能要過一小段時間才會出現在某些 Replica 上。

如果只是「晚一點看到自己剛發的文章」,問題還不算太嚴重。但如果今天不是 Replica 同步慢了半拍,而是 Primary 跟 Replica 之間的網路直接斷線呢?系統這時候該怎麼辦?

  • 繼續讓部分節點提供服務,但資料可能不一致?
  • 還是乾脆暫停服務,確保大家看到的資料都一樣?

不管是 Replica 之間、還是 SQL 與 NoSQL 之間,只要資料存在多個地方,就一定會遇到這個問題。這就是分散式系統裡一個非常經典的理論:CAP Theorem。

系統設計系列文16:資料庫是否該用 NoSQL

· 閱讀時間約 5 分鐘
阿昇
Software Engineer

PokeThreads 走到今天,已經不是一個單純的 CRUD 小玩具了,但從 Day 2 開始,Database 一直都是同一種選擇,也就是 SQL。這時候很自然會冒出一個問題:

系統都長這麼大了,是不是該把 SQL 換成 NoSQL?

甚至有人會直接跳到結論:「大型系統不都應該用 NoSQL 嗎?」

今天就來仔細了解這個問題。

系統設計系列文14:API Gateway 負責引導

· 閱讀時間約 5 分鐘
阿昇
Software Engineer

昨天把 Notification 從 PokeThreads 的 Monolith 拆成了獨立的 Notification Service,跟原本的 API Service 之間用 gRPC 溝通:

API Service ⇄ gRPC ⇄ Notification Service

拆完第一個 Service 之後,接下來這個趨勢大概不會停在這裡。假設之後 Search、Media Processing 也陸續被拆成獨立 Service,Client(瀏覽器、App)要面對的後端,就從「一個 Application」變成「一群 Service」:

  • User Service 在哪裡?
  • Feed Service 在哪裡?
  • Search Service 在哪裡?

如果讓 Client 直接記住每個 Service 的位址、各自打各自的 API,那還沒扯到功能,光是「知道要打誰」這件事,就已經讓前端變得很脆弱。

任何一個 Service 的位址一旦改變,所有 Client 都要跟著改。而且如果每個 Service 都要各自驗證使用者身份,Authentication 邏輯就會重複散落在每個 Service 裡。

系統設計系列文13:Monolith vs Microservices

· 閱讀時間約 6 分鐘
阿昇
Software Engineer

到目前為止,PokeThreads 已經具備了 Load Balancer、Read Replica、Cache、Stateless Server、CDN 與 Message Queue,是時候回頭想想,這些元件之間該怎麼有效率地互相溝通了。

不過在談溝通方式之前,先看一眼現在的 Application Server 到底裝了多少東西。

系統設計系列文12:Message Queue 不讓客人等

· 閱讀時間約 6 分鐘
阿昇
Software Engineer

昨天做出了最陽春的 Notification System,採用最直接的同步方式:

Charmander -> POST /posts/:id/like -> Create Like -> Create Notification -> Response

這種方式在系統規模小的時候很合理,但功能一多,API 要做的事情就跟著變多。

假設之後除了 Notification,還要加上 Analytics(資料分析),如果所有事情都得在同一個 Request 裡做完才能回應,這支 API 只會越來越慢。

解法是把「不需要讓使用者等待結果」的工作,從同步流程裡抽出去,變成背景作業,這就要靠 Message Queue (MQ)。

系統設計系列文11:Notification System 初型

· 閱讀時間約 3 分鐘
阿昇
Software Engineer

前面幾天,PokeThreads 的架構已經慢慢演化成分散式系統,不過所有功能都還圍繞在「發文、讀文」上。

只有這麼簡單的功能,實在太像古早時期的社群網站,今天要加入一個現代社群平台幾乎必備的功能:Notification(通知)。

情境很簡單:Pikachu 發了一篇貼文,Charmander 看到之後按下 Like,Pikachu 應該要收到一則「Charmander liked your post」的通知。