海量積分數據實時排名算法


問題描述

 

積分排名在很多項目都會出現,積分排名主要滿足以下需求:

  • 查詢用戶名次。
  • 查詢TopN(即查詢前N名的用戶)
  • 實時排名(很多項目是可選的)

當排序的數據量不大的時候,這個需求很容易滿足,但是如果數據量很大的時候比如百萬級、千萬級甚至上億的時候,或者有實時排名需求;這個時候要滿足性能、低成本等需求,在設計上就變得復雜起來了。

 

解決方案

 

高效做法是不對積分進行排序,僅僅是統計每個積分區間的人數,用積分區間的形式去統計相應的人數,下面是算法描述。

 

1. 根據積分范圍創建平衡二叉樹

設[0, N]為積分范圍, 構造的平衡二叉樹如下圖:

每個節點包含兩個數據字段(除了指針):

  • Range: 表示積分范圍。
  • Counts: 表示當前積分區間包含多少人。

 

積分的區間的划分是根據平分的方式,把當前積分范圍一分為二生成兩個子節點,然后遞歸的重復該步驟,直到積分區間無法划分為止(即區間[x, y], x == y)

 

例子:

假設積分范圍為: [0, 5],  構造的平衡二叉樹如下圖:

節點內的數據表示當前積分區間的人數。

 

從上圖可以看出來,所有積分都在葉子節點,葉子節點即最小粒度的積分區間。

 

2. 統計相應積分區間的人數

這里主要有兩種操作:

假設積分為i,

 

添加積分: 

添加積分的過程就是查找積分i, 同時累加查找過程經過的節點計數。

下面給出操作例子,注意觀察操作路徑。

例: 需要添加積分3, 結果如下圖

 

 

接着在添加積分4,結果如下圖

 

接着再添加積分4,結果如下圖

 

 

接着添加積分2,結果如下圖

 

刪除積分

刪除積分的過程也是查找積分i, 區別是查找過程經過的節點計數全部減1。

Ps: 只有積分是存在的情況下,才能做刪除操作,另外用一組標記,標識積分是否存在,這里就不列舉了。

例子: 刪除積分4, 結果如下圖

 

3. 查詢名次操作

查詢某個積分的排名的過程也是查找積分i的過程,下面是查找過程統計節點計數的算法:

對於查找路徑上的任意節點,如果積分在左節點區間,則累加右節點區間的計數。

最終累加計數的結果加1即是積分的名次

例子: 查找積分3的名次

 

藍色節點是查找積分3經過的路徑,紅色節點是需要累加的計數值。

最終結果是:0 + 1 + 1, 積分3的名次是第2名

 

從上面的算法可以看出,對平衡二叉樹的操作,算法復雜度是O(log N), N是最大積分。

在積分范圍不變的情況下,算法復雜度是穩定的,跟用戶量無關,因此可以實現海量用戶積分排名、實時排名算法需要。

 

對於海量積分數據實時排名、這里給出的是核心算法,實際業務的時候還需要增加一些額外的處理,比如uid於積分的映射表用於記錄用戶歷史積分、積分與uid的映射表用於TopN這種查詢前N名的需求、數據持久化、高可用等需求。

 

參考自海量積分數據實時排名處理方式介紹一


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM