熱點探測使用場景
- MySQL 中被頻繁訪問的數據 ,如熱門商品的主鍵 Id
- Redis 緩存中被密集訪問的 Key,如熱門商品的詳情需要 get goods$Id
- 惡意攻擊或機器人爬蟲的請求信息,如特定標識的 userId、機器 IP
- 頻繁被訪問的接口地址,如獲取用戶信息接口 /userInfo/ + userId
使用熱點探測的好處
提升性能,規避風險
對于無預期的熱數據(即突發場景下形成的熱 Key),可能會對業務系統帶來極大的風險,可將風險分為兩個層次:
- 對數據層的風險
正常情況下,Redis 緩存單機就可支持十萬左右 QPS,并能通過集群部署提高整體負載能力。對于并發量一般的系統,用 Redis 做緩存就足夠了。但是對于瞬時過高并發的請求,因為 Redis 單線程原因會導致正常請求排隊,或者因為熱點集中導致分片集群壓力過載而癱瘓,從而擊穿到 DB 引起服務器雪崩。 - 對應用服務的風險
每個應用在單位時間所能接受和處理的請求量是有限的,如果受到惡意請求的攻擊,讓惡意用戶獨自占用了大量請求處理資源,就會導致其他人畜無害的正常用戶的請求無法及時響應。
因此,需要一套動態熱 Key 檢測機制,通過對需要檢測的熱 Key 規則進行配置,實時監聽統計熱 Key 數據,當無預期的熱點數據出現時,第一時間發現他,并針對這些數據進行特殊處理。如本地緩存、拒絕惡意用戶、接口限流 / 降級等
京東熱點探測
- 熱點規則:配置熱 Key 的上報規則,圈出需要重點監測的 Key
- 熱點上報:應用服務將自己的熱 Key 訪問情況上報給集中計算單元
- 熱點統計:收集各應用實例上報的信息,使用滑動窗口算法計算 Key 的熱度
- 熱點推送:當 Key 的熱度達到設定值時,推送熱 Key 信息至所有應用實例
- 熱點緩存:各應用實例收到熱 Key 信息后,對 Key 值進行本地緩存
client
熱key上報,key的訪問次數積攢起來,等待每半秒發送一次。
為了防止阻塞IKeyCollector使用兩個ConcurrentHashMap切換,實現輪流提供讀寫、暫存key的操作。上報時譬如采用定時器,每隔0.5秒調度一次push方法。在上報過程中,不應阻塞寫入操作。所以計劃采用2個HashMap加一個atomicLong,如奇數時寫入map0,為1寫入map1,上傳后會清空該map。
熱key新增/刪除,監聽有新key推送事件,收到來自于worker的新增key
worker
收集各應用實例上報的信息,使用滑動窗口算法計算 Key 的熱度。當 Key 的熱度達到設定值時,推送熱 Key 信息至所有應用實例。和dashboard那邊的推送主要區別在于,給app推送每10ms一次,dashboard那邊1s一次。