題目描述
你的任務:設計一個支援多個獨立服務(S1, S2, …)的配額服務,所有服務共享同一個配額限制,確保一致性、並發安全和準確性。
問題分析
這是一道典型的統一存儲配額(Quota)系統設計題,類似 Google Drive、iCloud、OneDrive 的後端模式。多個服務(例如相冊、文檔、郵箱等)共享同一個配額,系統需要做到:
- ✅ 跨服務的總配額一致性
- ✅ 並發寫入不重複計數、不卡死
- ✅ 對每個服務的獨立計數
- ✅ 面向客戶端的查詢與寫入 API
- ✅ 高並發、高擴展
這道題考察的是你對分佈式計數器、事務、鎖機制、配額檢查流程以及系統擴展性的理解,是高頻的系統設計面試題。
核心演算法
1. 配額消費(帶樂觀鎖)
def consume_quota(user_id: int, service: str, size: int) -> bool:
"""
消費配額,使用樂觀鎖保證並發安全
"""
max_retries = 3
for attempt in range(max_retries):
# 1. 讀取當前配額
quota = db.query(
"SELECT total_quota, used_quota, version "
"FROM user_quota WHERE user_id = %s",
user_id
)
# 2. 檢查是否超額
if quota.used_quota + size > quota.total_quota:
return False # 配額不足
# 3. 嘗試更新(樂觀鎖)
affected = db.execute(
"UPDATE user_quota "
"SET used_quota = used_quota + %s, "
" version = version + 1, "
" updated_at = NOW() "
"WHERE user_id = %s AND version = %s",
size, user_id, quota.version
)
if affected > 0:
# 4. 更新服務級別統計
db.execute(
"INSERT INTO service_usage (user_id, service_name, used_quota) "
"VALUES (%s, %s, %s) "
"ON DUPLICATE KEY UPDATE used_quota = used_quota + %s",
user_id, service, size, size
)
# 5. 記錄日誌
log_quota_change(user_id, service, 'ADD', size,
quota.used_quota, quota.used_quota + size)
# 6. 更新快取
cache.delete(f"quota:{user_id}")
return True
# 版本衝突,重試
time.sleep(0.01 * (2 ** attempt)) # 指數退避
return False # 重試失敗
優化策略
1. 快取策略
- 讀快取:配額查詢結果快取 60 秒
- 寫穿透:更新配額時刪除快取
2. 資料庫優化
- 分庫分表:按 user_id 雜湊分片
- 讀寫分離:查詢走從庫,寫入走主庫
3. 並發控制
- 樂觀鎖:使用 version 欄位避免超賣
- 重試機制:衝突時指數退避重試
總結
Snowflake 的配額系統設計題考察點:
- 並發控制:樂觀鎖 vs 悲觀鎖
- 一致性保證:事務、版本號
- 性能優化:快取、分片、索引
- 可擴展性:水平擴展、非同步處理
- 監控告警:配額使用率、異常檢測
oavoservice 專注於 Snowflake / Google / Amazon 等大廠面試輔導,提供 OA 代做、VO 即時輔助等服務。如需幫助,歡迎聯繫我們。
需要面試真題? 立刻聯繫微信 Coding0201,獲得真題。