大家發現了吧,現在面試八股文好像問的少了,反倒是場景題多了起來,畢竟現在AI如此強大,總揪着這點底層基礎也沒多大意思。
面試官張嘴閉嘴高併發、大數據量倒是真的,別管實際業務是不是高併發,但是你不會是進不來擰螺絲的。
就像之前有同學被問:“某音百萬用户同時給一個視頻點贊,讓你來要怎麼設計?”,這類題肯定見過吧。
咱們來簡單拆解下這題,我是一個小學習,知識量有限,不喜勿噴。
這道題到底考察什麼?
別上來就想用什麼技術,先明確面試官的考察點,才能答到點子上:
- 高併發寫入能力:百萬人同時操作,瞬間 QPS 能衝到幾十萬,如何避免數據庫被打垮?這是考察你對流量削峯的理解;
- 數據一致性:用户點贊後必須立刻看到 已贊 狀態,點贊數可以有輕微延遲,但不能錯、不能丟,這是對最終一致性的考察;
- 系統可用性:就算後端服務波動,用户點贊操作也得成功,不能出現點了沒反應的情況,考察容錯和降級思路;
- 資源優化:百萬次請求直接懟數據庫肯定不行,如何用緩存、消息隊列等中間件減輕壓力,考察技術選型能力。
換位思考
很多人一上來就糾結怎麼讓百萬次點贊實時寫入數據庫,其實跑偏了。
咱們站在用户角度想:
- 用户點擊點贊後,最關心的是
有沒有點贊成功,而不是當前贊數到底是 10086 還是 10087; - 贊數是給所有用户看的
公共數據,輕微延遲用户完全感知不到(就算數據丟了,用户也很難發現,只是會想“咦”我之前點贊過一個視頻沒了,就沒然後了); - 核心需求是:操作成功率 99% + 客户端狀態實時反饋 + 贊數最終準確。
想通這一點,方案就清晰了:把實時寫入數據庫的壓力,轉移到中間件上,用異步 + 緩存的思路解決高併發。
選取方案
咱們一步步拆解,從用户點擊點贊按鈕開始,整個流程是這樣的:
1. 用户點贊:先寫消息隊列,客户端直接反饋成功
用户點擊點讚的瞬間,客户端不會直接調用數據庫接口,而是做兩件事:
- 向後端發送點贊請求,後端收到後,不操作數據庫,直接把用户ID + 視頻ID + 點贊狀態(贊 / 取消贊)封裝成一條消息,寫入 Kafka;
- Reids 記錄 用户ID + 視頻ID 的點贊狀態,增加 視頻ID 的贊數量
- 只要消息成功寫入 Kafka,後端就立刻返回點贊成功給前端,客户端馬上顯示已贊狀態。
為啥選 Kafka 我就不説了。
2. 客户端:本地記錄狀態,避免重複點贊
客户端收到點贊成功後,除了顯示已贊,還要在本地存儲記錄當前用户對該視頻已點贊。
這樣做的好處是:
- 防止用户短時間內重複點擊點贊,前端直接攔截,減少無效請求;
- 就算後續緩存沒更新,用户自己看到的狀態也是準確的,不影響個人體驗。
3. 查贊數:直接讀 Redis,不用查數據庫
其他用户查看視頻時,需要顯示贊數,這時候客户端會調用查詢贊數接口,後端的處理邏輯是:
- 不查數據庫,直接從 Redis 裏讀取該視頻的贊數緩存;
- Redis 讀性能極高,支持每秒幾十萬次查詢,完全能扛住百萬用户同時查看的壓力;
- 這裏的贊數可能不是實時最新的,但只要延遲在可接受範圍內,用户完全沒感覺。
4. 後台任務:定時同步 Redis 和數據庫,保證最終一致
這一步是兜底,負責把 Kafka 裏的點贊消息處理掉,同時更新 Redis 和數據庫:
- 後端持續從 Kafka 里拉取點贊消息;
- 啓動一個定時任務,把 Redis 裏所有視頻的贊數,批量同步到數據庫裏;
- 同步時要注意冪等性:比如用户先贊後取消,最終狀態是未贊,避免重複計算導致贊數錯誤。
批量同步,攢一批數據(比如 1 萬條)再批量更新,大大減少數據庫的寫入壓力。
而且定時任務可以根據業務調整頻率,比如高峯期每 1 分鐘同步一次,低峯期每 10 分鐘同步一次,靈活適配流量。
方案優勢
這套方案沒有複雜的架構,但的確能解決百萬級點讚的高併發問題,核心優勢在於幾種中間件的組合使用:
- 高可用:Kafka 保證消息不丟失,Redis 保證查詢不卡頓,就算數據庫暫時掛了,用户點贊和查贊數都不受影響;
- 易擴展:如果後續點贊量漲到千萬級,只需要增加 Kafka 的分區數、Redis 的集羣節點,就能輕鬆扛住;
- 低成本:不用複雜的分佈式事務,不用實時計算框架,用最基礎的中間件就能實現,開發和維護成本都低。
寫在最後
其實很多高併發場景,比如點贊、評論、秒殺,核心思路都是異步解耦 + 緩存兜底。
面試官考察的不是你知道多少冷門技術,而是你能不能看透問題本質,用户要的是 體驗 和 成功,不是 實時準確。
不過,這套方案看似簡單,但覆蓋了 “削峯、緩存、異步、最終一致性” 等核心考點,面試時把這個邏輯講清楚,再結合 Kafka 的消息可靠性、Redis 的高性能、定時任務的批量處理,面試官起碼會覺得你 懂行。
如果實際業務中,贊數延遲要求極高(比如直播場景,需要實時顯示贊數),也可以把定時同步改成 Kafka 消費後實時更新 Redis,數據庫異步同步,本質還是換湯不換藥~