內行人才知道的系統設計面試指南讀書第一章 — 使用者人數

J米的學習日記
8 min readSep 11, 2022

很久沒在 Medium 寫文章了,一方面是前同事 Win 推坑創建自己 Hugo Blog 後,想把文章重點轉移到自架的 Blog,但通車隨筆時,聽著 Spotify 感覺上還是可以記錄個簡單的知識或概念,因此,目前把這邊當作讀書心得、工作、生活經驗類別方式做書寫,在自己 Blog 會紀錄偏向技術文的程式碼,詳細的比較,紀錄於前一篇 自架網站 Hugo V.S. Medium 的選擇與優缺點紀錄

每天讀個書,順便讀完用自己的話解釋看看,日後回頭看,也比較好吸收。

圖片來源:書籍封面

Table of Contents

1. 輸入網址背後幫你做的事情

2. 資料庫

3. 資料庫擴展

4. Load Balancer 負載平衡器

5. 資料庫複寫機制

6. 快取 Cache

7. CDN 內容傳遞網路

8. 無狀態網路層

9. 訊息佇列 (Message queue)

10. 總結

輸入網址背後幫你做的事情

了解使用者輸入網域名稱後,背後的機制(當作複習XD)

  1. 使用者於瀏覽器輸入網域名稱 (Ex: https://some-website.com)
  2. 瀏覽器向 DNS 詢問其真實的 IP 地址 (Ex: 118.96.168.1)

如果想像成真實世界,可以說一個故事,小明小美要約會有一天相約在老地方吃飯,因地點不明確,有了以下對話:

  • 小明: 我們約老地方吃飯,東經 121.5 度,北緯 23.5 度
  • 小美: 你跟鬼說話嗎? 幾度幾度我怎知道在哪? 我要生氣囉!
  • 小明: 對不起啦! 台北中山區忠孝北路 520 號 3 F ,fall in love 餐酒館
  • 小明: 不要生氣了,我對你的愛是 愛你無法度
  • 小美: (已讀)

因此在網路的世界中,上面的 fall in love 餐酒館就是網域名稱, 東經 121.5 度,北緯 23.5 度 跟 台北中山區忠孝北路 520 號 3 F 就是 IP 位址,對於人們來說, fall in love 餐酒館是比較好溝通且容易記得的。

3. 取得 IP 位址,瀏覽器發出 HTTP Request 到 Web 伺服器

此階段,作者為了讓讀者容易理解,跳過 CDN / Load Balancer 等機制,後續應該會提到。

4. Web 伺服器回送 HTML 或 JSON Response 給瀏覽器做渲染 (Rendering)。

資料庫

有 RDBMS 關聯式(Ex: MySQL 等) & NoSQL 非關聯式(Redis, MongoDB 等),要選哪一種,當然根據需求、市場與成本考量有關

RDBMS 關聯式資料庫

  1. 有固定 Schema
  2. 各資料關聯架構事先要設想好,正規化設計,可減少重複資料
  3. ACID 特性
  4. 後續資料量大時,擴展不易
  5. 資料量大時, IO 高

NoSQL 非關聯式資料庫

  1. 顧名思義,各資料表間沒有關聯,因此沒有 ACID 特性,處理非結構化資料
  2. 沒有固定格式,不需事先定義好 Schema,同一個資料表,會出現不同資料格式,後續改變、擴展容易,畢竟沒什麼章法
  3. 你把 NoSQL 每一筆資料想成文件,容易理解,每個文件都是獨特的
  4. 存在漏資料風險,必須小心
  5. 超低延遲,推薦用 Redis

資料庫擴展

  1. 垂直擴展 vertical scaling,又稱為 往上擴展 scale-up,想象成升級設備,你的筆電升級 RAM 那般,有上限的,也花錢,出現於流量初期,風險高,畢竟只有一台伺服器。
    常見的硬體升級有 CPU、記憶體、硬碟空間
    優點:初期配置容易、簡單升級
    缺點:升級成本高
  2. 水平擴展 horizontal scaling,又稱為 往外擴展 scale-out,又可叫 分片(Sharding),想像成多台伺服器,彼此資料同步,一台掛掉,其他台會 cover,後續作者會說明資料庫讀寫分離機制。
    機制:將資料根據分配到不同的資料庫,例如:除以四取餘數去儲存至不同資料庫,取資料也用相同邏輯去取得,分片有分片鍵 (Sharding key),又可叫分區鍵 (Partition key),由一個或多個欄位組成,可以確認其資料分配的方式,藉由分片鍵可以找到正確的資料庫,讓操作者在檢索時,更有效率。
    優點:均勻分散資料、避免單機故障、讀寫分離
    缺點:邏輯複雜化

Load Balancer 負載平衡器

這是一個很玄的東西,剛寫程式的前三個月常聽到資深前端討論著,某個前端頁面沒改變,你必須讓 Load Balancer 辨識其檔案 tag 已改變了等等討論!

不知道你是否參加過健康檢查,某些檢查健檢站,擠滿了人,會有護士確認你哪些項目還沒做,幫你人工配置去較少的檢查站,接下來,我要講的概念就有異曲同工之處!

Load Balancer 就是在瀏覽器發送至網站伺服器前,中間的守衛,只是該守衛會評估系統中 — 水平擴展的網頁伺服器,計算出每台現在的流量,將你的請求找到最佳的伺服器去處理。

為什麼說 Load Balancer 是守衛?

  1. 它代表外網 IP,因此有心人士或是網頁伺服器真實位址不會暴露出來
  2. 想要存取內網資料,都要先經過 Load Balancer
  3. 當其中一台伺服器暫時無法連線,Load Balancer 也會幫你導到其他伺服器

資料庫複寫機制

資料庫只有一台嗎?是新手常有的疑問,畢竟 Local 端,我們只連線到 MySQL 一台。

因此,答案揭曉,資料庫不只一台,而且還會分成主從式架構(Master/Slave),專業分工起來,才不會面對大量需求時,一台資料庫爆炸,全部都爆。

我們歸納一下資料庫的動作,CRUD,Crate/Read/Update/Delete,因此,主從式想把異動資料庫與查詢資料庫切開,Master 只支援寫入(Create/Update/Delete),Slave 只負責讀(Read),其資料是 Master 副本的資料庫。

所以為什麼這樣做?要解決什麼情境?

  1. 當大流量時,很多人在同一時間進行查詢,有可能無法負荷瞬間的高流量
  2. 防止亂搞,通常對外部系統的資料庫,需求不需要寫入功能,建議使用 Slave 給外部使用即可
  3. 資料庫突然有一台面對 Slow query 故障離線,可以馬上配置一台新的資料庫處理需求,如果恰巧 Master 在處理時故障離線,會將 Slave 升級為 Master,Master 馬上進行複製,取代故障資料庫。

快取 Cache

顧名思義,就是快速取得,那反思一下,所有東西都要快取嗎?常用的東西才快取吧!

快取要解決的問題是不要過度對資料庫調用,因此,當需求到伺服器端時,伺服器會先問,這包資料是否有快取,沒有快取才去操作資料庫。

快取的好處有很多,節省流量、快、減少資料庫負擔等等。

其他,快取機制,可以參考延伸閱讀。

CDN 內容傳遞網路

CDN 也算是使用快取的一種。在日益壯大的網際網路中,因為發送請求端與伺服器端地理位置越來越遠,CDN 因應而生,會針對 CSS、HTML、Javascript 等靜態內容進行快取。

因此當使用者造訪網站時,CDN 會按照使用者最近的 CDN 伺服器提供靜態內容。

好處:

  1. 改善網頁載入時間
  2. 節省流量成本
  3. 方便設定過期檔案時間
  4. 減少資料庫負載

無狀態網路層

無狀態(Stateless)的意思,表示每次請求都是全新的,這一次請求,無法取得上次請求的詳細資訊,這也是為什麼 HTTP 稱為無狀態協定。

那如何分辨使用者已經登入了呢?可以利用 Cookie & Session,將 Session 資料儲存於 RDBMS or NoSQL 資料庫中,就是所謂的無狀態網路層。

將 Session 內敏感資訊存在RDBMS or NoSQL 資料庫中,創建一個專屬的 Session ID,Client 端發送請求時,隨 Cookie 一併戴上,經由這個獨一無二的 Session ID 在去資料庫取得使用者敏感資訊。

好處:

  1. 敏感資訊存在伺服器端,畢竟客戶端的資訊有風險的
  2. 自動擴展 Autoscaling 方便,沒有狀態情況下,添加或刪除伺服器,還是能找到上一次登入的資料

訊息佇列 (Message queue)

這概念十分實用,新手學程式常聽到的兩個名詞,同步與非同步。

同步:等待期間無法做其他事情,必須等待目前事情做完,才可接續做

非同步:可先把要做的事情丟到一個緩衝區,等待系統慢慢消化,等待期間可以繼續做其他事情

因此,訊息佇列是一種保存在記憶體的可持久元素,可以將要做的事情放在這個緩衝區,等待其消化。

應用情境:

  1. 非主流程的工作,例如:貨到付款的通知
  2. 無法立即得到回應的工作,例如:打 Api 到其他系統取得回應,記錄於資料庫

總結

圖片來源:系統設計書籍第一章 31 頁

這張圖是第一章的精華,看完第一章,很像在看過去學習的自己,每個名詞背後的意義,串連起來就是這張圖,就是使用者操作瀏覽器,向伺服器拿到資源後,渲染到前端的結果。

延伸閱讀

  1. [筆記] RDBMS v.s. NoSQL
  2. 網站架構原理 — 作為網站開發人員起步時我希望知道的概念
  3. 循序漸進理解 HTTP Cache 機制
  4. [筆記] HTTP Cookies 和 Session 使用

--

--