點贊系統的設計
隨着社交網絡的蓬勃發展,點贊功能逐漸成爲了一個網站中不可或缺的功能。因爲點贊功能不僅可以讓用戶更直觀地瞭解自己的視頻、文章等內容被多少人認可,而且也提升了用戶互動體驗感。下面我們來聊聊通用的點贊系統設計的方案。
1、點贊系統的數據表設計
在設計數據表的時候我們需要知道點贊系統需要完成的基礎功能有哪些,點贊系統通常需要實現以下功能:
(1)用戶可以點贊一個視頻、文章、評論等內容
(2)用戶可以查看一個視頻、文章、評論等內容的點贊數
(3)用戶可以取消對視頻、文章、評論等內容的點贊
針對如上所示的功能,我們可以設計一張點贊記錄表和點贊計數表來記錄數據,如下是兩張表的字段設計:
點贊計數表中記錄了稿件(視頻、文章、評論等等)被點贊和取消點讚的總數,用作總的點贊數據展示;點贊記錄表用於記錄哪些用戶在何時給哪個稿件點贊或取消點贊。
2、系統設計
2.1 點贊數據寫入的設計方案
點贊系統一般流量是比較大的,特別是在某個稿件突然成爲熱點之後,那麼流量就會突增上來,爲了應對大流量,我們在設計點贊系統的時候採用 MQ 來做削峯處理,整個點贊數據寫入的流程如下所示:
(1)用戶發送來點贊請求,經過 Nginx 和網關轉發到點贊服務上,點贊服務組裝必要的數據(稿件的 id、稿件用戶 id 等數據)發送 MQ 消息,併發響應客戶端寫入點贊數據成功。
(2)點贊服務消費 MQ 消息,首先要保存點讚的數據,在保存點贊數據的時候需要做一些邏輯檢驗工作,如下的流程圖所示:
首先根據用戶的 id 和點讚的稿件 id 查詢數據庫獲取用戶的點贊記錄數據,根據查詢的結果分如下的情況分析:
(a)如果沒有查詢到用戶的點贊記錄數據,那麼直接保存用戶的點贊記錄到記錄表中,將點贊計數表中的總的點贊數量加 1。
(b)如果已經存在了用戶的點贊記錄,那麼就需要根據點讚的時間和點讚的動作進一步的檢查
(b1)數據表中的點贊時間 > MQ 中用戶的點贊時間,說明可能存在重複的點贊,此時我們這表 MQ 消息直接丟棄。
(b2)數據表中的點贊時間 < MQ 中用戶的點贊時間,比較數據庫中當前的用戶點贊狀態是否爲點贊,如果是點贊狀態那麼當前的 MQ 也不消費了,如果是數據庫中狀態是取消狀態,那麼 MQ 消息我們就需要消費,此時修改記錄表的數據狀態爲點贊狀態、點贊計數表中當前的稿件的點贊數量加 1。
(3)點讚的數據寫入緩存中從而減輕數據庫的壓力,點贊記錄和點贊計數表的設計如下所示:
在 redis 中稿件的點贊總數可以採用 String 類型的數據結構來緩存,點贊記錄數據採用 Zset 的數據格式來存緩存數據,這裏需要給 redis 設置適當的過期時間。
(4)數據庫的設計採用讀寫分離的架構,使用 canal 來同步數據到從庫中,所有的寫請求都打到主庫上,所有的讀請求都轉發到從庫上。
(5)爲了保證數據的一致性,我們採用定時任務定期從數據庫中同步數據到 redis 上,這樣即使是 redis 在某個時間中寫失敗了,我們通過定時任務的方式將數據補償到 redis 中。
取消的點贊數據的寫入流程也是一樣設計的,只是最終邏輯是要點贊計數表中點讚的數量減 1,取消點讚的數量加 1 的,還要在點贊記錄表中更新或者添加用戶取消點讚的記錄,所以取消點讚的這裏就不在贅述。
2.2 用戶讀取點讚的數據
當點贊數據成功的寫入緩存和數據庫之後,用戶讀取點贊數據的流程如下:
(1)讀請求轉發到點贊服務上之後,點贊服務優先查詢 redis 中是否存在數據,如果有數據的情況下,直接響應數據給客戶端。
(2)如果 redis 中無點贊數據,那麼此時就需要到數據庫中查詢數據,此時讀取數據庫的時候需要添加鎖,防止短時間內由於緩存失效等原因造成大量的請求直接請求數據庫從而導致數據庫崩潰的問題。數據庫上查詢的數據要緩存一份到 redis 中。
總結:
(1)點贊系統本文介紹的是一種通過 MQ+ 主從架構 +redis 的設計方案來應對大流量
(2)高併發下點贊系統的 redis 緩存推薦使用更新的方案,因爲高併發如果頻繁的刪除緩存就會導致緩存的命中率下降,那麼就發揮不了緩存的作用
(3)主從架構中,主從的通過是通過 canal 來同步的,canal 也是依賴與主庫的 binlog,如果主庫由於系統的壓力較大生成 binlog 速度慢了,就可能會發生從庫和 redis 之間的數據不一致性,此時定時任務可以做數據補償,修復從庫和 redis 之間的數據不一致性
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/lAo-tIOSQWfabq64VII7zw