許多開發者在構建社交或內容平台時,都需要實現類似 QQ 空間的「訪問量」統計功能。面對高併發訪問,若每次請求都直接寫入數據庫,極易造成數據庫壓力過大,甚至導致服務不可用。本文將系統梳理業界通用的高效實現方案,幫助你從架構層面解決這一經典問題。
訪問量統計的本質是「高頻寫入、低頻讀取」。若採用傳統的「請求到來即 UPDATE 數據庫」模式:
在瀏覽器端利用 localStorage 或 Cookie 標記「本會話已統計」,同一用戶同一會話內重複訪問不發送統計請求,從源頭削減 60%~80% 無效流量。
在 Nginx 層面用 shared_dict 做滑動窗口計數,每隔 5~10 秒批量寫入 Redis。示例邏輯:
local visits = ngx.shared.visits
local key = "pv:" .. ngx.var.arg_space_id
local count = visits:incr(key, 1, 0)
if count % 100 == 0 then
ngx.timer.at(0, flush_to_redis, key, count)
end
INCRBY 原子操作實現高併發計數引入 Kafka / RocketMQ / RabbitMQ:
UPDATE ... SET pv = pv + ?| 技巧 | 適用場景 | 收益 |
|---|---|---|
| HyperLogLog 估算 UV | 只需近似值、極大基數 | 記憶體固定 12 KB,誤差 < 0.81% |
| 布隆過濾器去重 | 海量用戶、內存受限 | 以極小誤判率換取巨大空間節省 |
| 分表分庫 | 單表超 5000 萬行 | 寫入性能線性擴展 |
| ClickHouse / Doris OLAP | 多維分析、實時大屏 | 列式存儲 + 向量化查詢,聚合秒級返回 |
![]()
![]()
「先學會走,再考慮跑。沒有放之四海而皆準的設計,從簡單到優化的過程本身就是對技術本質的理解。」—— 曹哲(CSDN 專家)
訪問量統計看似簡單,實則考驗系統設計的分層思想與權衡能力。建議從「單機 Redis + 定時任務」起步,隨業務增長逐步引入消息隊列、OLAP 引擎,切忌一上來就追求「完美架構」。