時間輪在Kafka的實踐

1. 引子

從2個面試題說起,第一個問題: 如果一臺機器上有10w個定時任務,如何做到高效觸發?

具體場景是:

有一個APP實時消息通道系統,對每個用戶會維護一個APP到服務器的TCP連接,用來實時收發消息,對這個TCP連接,有這樣一個需求:“如果連續30s沒有請求包(例如登錄,消息,keepalive包),服務端就要將這個用戶的狀態置爲離線”。

其中,單機TCP同時在線量約在10w級別,keepalive請求包較分散大概30s一次,吞吐量約在3000qps。

怎麼做?

常用方案使用time定時任務,每秒掃描一次所有連接的集合Map<uid, last_packet_time>,把連接時間(每次有新的請求更新對應連接的連接時間)比當前時間的差值大30s的連接找出來處理。

另一種方案,使用環形隊列法:

三個重要的數據結構:

  1. 30s超時,就創建一個index從0到30的環形隊列(本質是個數組)
  2. 環上每一個slot是一個Set<uid>,任務集合
  3. 同時還有一個Map<uid, index>,記錄uid落在環上的哪個slot裏

這樣當有某用戶uid有請求包到達時:

  1. 從Map結構中,查找出這個uid存儲在哪一個slot裏
  2. 從這個slot的Set結構中,刪除這個uid
  3. 將uid重新加入到新的slot中,具體是哪一個slot呢 => Current Index指針所指向的上一個slot,因爲這個slot,會被timer在30s之後掃描到
  4. 更新Map,這個uid對應slot的index值

原文鏈接:【https://www.infoq.cn/article/ErdajpJ5EpIr65IczxZI】。未經作者許可,禁止轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章