Rails 實現 db 讀寫分離也是今天的主題。
相信很多過電商的朋友, 都遇到過 限時搶購
或是 限量商品
的情況
大量的請求, 可能會導致網站暫時掛掉, 而讓消費者跑掉或頭數的情況。
所以在這種活動前, 可能就是 無限制擴充 Server ($$$)
但其實這大量的請求中, 有很大的請求來至 讀取(SELECT)
, 實際真的寫入(INSERT、UPDATE、DELETE) db 一定會比 讀取(SELECT)
來得少。
那其實我們可以往 讀寫分離
這個方向去解決。
剛好 Rails 6.1
就支援了 Multiple Databases with Active Record
但今天的範例會使用 Rails 7
要如何設置你的 database.yml
1 | database.yml |
其中 replica
複製品的意思。
primary
為 master
主要負責 寫入
, e.g., POST、PUT、PATCH、DELETE
primary_replica
為 slave
主要負責 讀取
, e.g., GET, HEAD
Create an abstract class for your model
1 | # frozen_string_literal: true |
由此可見, 我們分別設定了 寫
跟 讀
的 db 分別指向哪個。
其實這樣就已經設定好, 我們的讀寫分離了。
寫入 master
的時候會同時複製一份到你的 replica
上。
為了驗證讀寫分離, 對 db 的請求有多少, 所以我在 GCP
上, 使用了 Cloud DB
跟 Replicas
來驗證
先驗證資料是否有同步好了!
這是 master 目前的樣子
這是 replica 目前的樣子
我做了第一次 create
master 有存入這筆資料
同時 replica 也同步了
有此可見資料是同步的。
但因為服務要錢, 所以真的要測試大流量就先止步了
總結
雖然這樣就做好簡單的設定, 但其實還有非常多的進階設定可以做, 水也很深。
例如:
- 加入
HA
連監聽 db 是否活著, 發現 master 掛掉了, 自動把replica
轉成 master,
就不會有資料不同步的問題 - 當寫入後複製資料時有些許時間差
- 多 db 多 replica 的存在, 兩個不同資料庫, 但 table 有關連的時候,
- 在特定的
action
只能做讀
, 只要寫入就噴錯, 等等。
在現在這種電商時代, 如何把使用者留著, 甚至在大流量時不暫時掛掉, 都是相當重要的
包括 redis
也可以做到這種架構!
以上為心得分享, 因為偏架構的部分, 還是第一次寫這種文章, 還希望有錯的地方可以指教!
-W