利用 Redis 的 Sorted Set 来创建按照相同分数的排名

首先

我正在一个服务上实施排名计算。突然想起不仅可以在应用程序端进行,还可以委托给Redis来处理,于是我写了一段样例代码进行调查,并将其整理成一篇文章。

我想实现的目标

    スコア情報を持つデータがある。Redisを使用して同点順位によるランキングを作成したい

开发环境

    • Redis 4.0.11

 

    • Ruby 2.6.1p33

 

    • gem

redis 4.1.2

实施方法

为了进行操作验证,这次我们使用了Ruby和redis gem进行实现。稍后我会与您分享完整的示例代码。

准备好

首先,使用Redis gem来连接到Redis。一旦连接到Redis,之后可以通过REDIS对象来操作Redis。

require 'redis'

# Redisに接続
REDIS = Redis.new(host: 'localhost', port: 6379)

# 初期化
REDIS.del("ranking")

用Redis的有序集合来实现

在日语中,这被称为排序集合类型,并且当在Redis中注册得分时,Redis会对其进行排序。

使用 zadd 来注册新的数据。数据可以通过以下方式追加。一旦添加,Redis会自动进行排序。

REDIS.zadd("ranking", 200, "A")

要获取已排序的数据,可以使用zrevrange方法。可以从第一位到第十位获取降序排名信息,还可以返回分数信息,只需指定:with_scores => true。

rankings = REDIS.zrevrange("ranking", 0, 10, :with_scores => true)

使用zcount函数进行排名计算。该方法计算指定范围内的分数有多少条目。在下面的示例中,计算指定分数及以上的值有多少条目。这样可以计算出同分排名。

rankings.each do |r|
  # 同点順位計算処理: 同じスコア以上のものが何件あるか算出する
  rank = REDIS.zcount("ranking", r[1], "+inf")
  p r
  p rank
end

样本代码

这次的示例代码在这里。

require 'redis'

# Redisに接続
REDIS = Redis.new(host: 'localhost', port: 6379)

# 初期化
REDIS.del("ranking")

# 検証データを登録
REDIS.zadd("ranking", 200, "A")
REDIS.zadd("ranking", 150, "B")
REDIS.zadd("ranking", 30, "C")
REDIS.zadd("ranking", 200, "D")
REDIS.zadd("ranking", 180, "E")
REDIS.zadd("ranking", 190, "F")
REDIS.zadd("ranking", 250, "G")
REDIS.zadd("ranking", 210, "H")
REDIS.zadd("ranking", 10, "I")
REDIS.zadd("ranking", 30, "J")

# 降順のランキング情報を1件目から10件スコア情報も合わせて取得す
rankings = REDIS.zrevrange("ranking", 0, 10, :with_scores => true)
rankings.each do |r|
  # 同点順位計算処理: 同じスコア以上のものが何件あるか算出する
  rank = REDIS.zcount("ranking", r[1], "+inf")
  p r
  p rank
end

执行结果

看执行结果。重点是第四名。由于有两个得分相同的200分,因此有两个第四名,而190分则从第五名开始。这样就实现了想要的目标。

$ bundle exec ruby ranking.rb
["G", 250.0]
1
["H", 210.0]
2
["D", 200.0]
4
["A", 200.0]
4
["F", 190.0]
5
["E", 180.0]
6
["B", 150.0]
7
["J", 30.0]
9
["C", 30.0]
9
["I", 10.0]
10

终点

这个实现例虽然很常见,但我之前没有使用过 Redis 的 Sorted Set,所以我写了一个示例代码并整理成了一篇文章以进行学习。如果应用程序本身已经可以进行排名计算,那么就没有必要将其交给 Redis。但是在游戏等需要实时性的需求情况下,似乎将其交给 Redis 是更好的选择。

请问您是否能请你担当我的参考?

    • Class: Redis — Documentation for redis/redis-rb (master)

 

    • Command reference – Redis

 

    phpredisを使用してランキング集計を行う – ダメプログラマの技術メモ
广告
将在 10 秒后关闭
bannerAds