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


需求概述

積分排名在很多項目都會出現,大家都不會陌生,需求也很簡單,積分排名主要滿足以下需求:

 

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

 

 

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

常規積分排名處理

這里列舉下日常對於排名的常規做法和缺陷。

1. 數據庫解決方案

這是最簡單的做法,數據存儲在數據庫里面,然后利用數據庫做排序處理。

這里分兩種情況:

1.1單庫/單表

參與排名的數據量小的時候的做法,所有數據存儲在一張表上。

查詢操作示例:

查詢用戶名次:

SELECT count(*) as rank FROM 積分表 WHERE 積分 > (SELECT 積分 FROM 積分表 WHERE uid=’用戶ID’)

 

查詢前N名:

SELECT uid, 積分 FROM 積分表 ORDER BY 積分 DESC LIMIT 0,N

 

1.2 分庫/分表

對於這種情況數據不在一塊,在查詢操作上跟上面單表情況的區別就是,分庫/分表需要做,查詢任務切割和查詢結果合並處理。

缺陷:

查詢排名效率低,會造成掃描大量的記錄,甚至全表掃描,性能低,在數據量大、高並發的情況下這種方案是不可用的。

 

2. 采用常規排序算法

思路上就是把積分排序處理從數據庫轉移出來,自己實現排序和查詢處理。

實際排名業務的特點:

 

  • 每次用戶的積分更新都會在一個小的積分范圍內波動。
  • 已有的積分數據都是已排序的。

 

 

常見的幾種排序算法大家都熟知這里就不列舉了。

缺陷:

對於海量數據排序處理,簡單的使用常規排序算法並不合適,要么就是排序造成大量的數據移動、要么就是對已排序的數據查詢名次效率不高。

高效的排名算法

前面的排名算法都是針對積分進行排序,然后通過統計積分高於自己的人數獲得排名。

要想知道某個用戶的名次,只需要知道比這個用戶高分的人數,不一定需要對積分做排序。

 

在這里換個思路不對積分進行排序,僅僅是統計每個積分區間的人數,用積分區間的形式去統計相應的人數,下面是算法描述。

 

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