dot Redis 8 来了——它是开源的

了解更多

什么是排行榜?

排行榜的概念——一个显示领先竞争对手排名、当前分数(或其他数据点)的记分板——对于电脑游戏世界至关重要,但如今排行榜不仅仅用于游戏。它们关乎游戏化,这是一种更广泛的应用,可以包括任何具有共同目标的人群(同事、学生、销售团队、健身小组、志愿者等)。

排行榜可以通过公开展示每个团队成员的当前排名来鼓励群体中的健康竞争。它们还提供了一种清晰的方式来查看整个团队在朝着目标迈进时的持续成就。

游戏化排行榜

通过排行榜对任务和目标进行游戏化是一种很好的激励方式,可以不断向人们提供他们在与其他群体成员比较时的排名反馈。做得好,这可以带来健康的竞争,从而增强团队凝聚力。

以下是一家公司可能用来激励员工参与其员工健康计划的简单排行榜图形示例。

在此示例中,员工可以看到排名靠前的竞争对手及其当前分数。他们还可以看到比赛剩余的时间和激励奖品。当然,随着数据变化(例如用户上传已验证的步数),排名也会实时变化。

排行榜有两种类型

绝对排行榜 根据某种全局指标对所有竞争对手进行排名。通常这些显示组中排名靠前的成员,例如前 10 名。

相对排行榜 根据数据的不同方面对参与者进行排名,以便根据更狭窄或相对的标准对成员进行分组。这可能需要复杂的计算才能以多种方式滑动数据。例如,一个常见的游戏场景是显示给定竞争对手及其上方和下方竞争对手排名的视图。

观看我们关于排行榜最佳实践的技术讲座

当今排行榜面临的挑战

在我们互联网连接的世界中,热门游戏的排行榜可以由成千上万甚至数百万竞争对手共享。这也适用于排行榜的非传统用途,例如健身和健康应用、社交媒体,或客户服务、物流或欺诈防范等内部组织任务。

用于排行榜的数据不断更新,用户希望以多种方式查看数据。这使得排行榜成为实时分析的绝佳示例,也展示了您的数据层处理读取、写入、排序和其他关键操作的速度。

排行榜带来的技术挑战包括

  • 数百万用户的海量规模
  • 对大量属性进行数学计算(以多种方式分析数据以获得数据的不同视图)
  • 提供高可用的实时排行榜访问
  • 允许用户在社交媒体上分享他们的排行榜统计数据
  • 允许用户在排行榜上他们感兴趣的属性发生变化时接收通知
  • 允许应用程序在全球范围内的行动发生地以完全分布式的方式更新排行榜,同时也能从任何位置提供排行榜状态的全局视图

实时提供这些数据并保持系统可用性超出了许多 Web 技术的范围。然而,这是 Redis Enterprise 通过为此类用例构建的数据结构以及 Redis Enterprise 提供的各种部署选项所解决的挑战。

为什么选择 Redis Enterprise?

Redis 中的有序集合(ZSET)是内置的数据结构,使排行榜易于创建和操作。

Redis Enterprise 基于无共享、对称架构,使数据集大小能够线性、无缝增长,无需修改应用程序代码。

Redis Enterprise 提供多种高可用性模型,并允许您以地理分布方式部署 Redis,同时在需要时为用户提供本地延迟。

不影响性能的多种持久性选项(每次写入或每秒的 AOF 和快照)确保您在发生故障后无需重建数据库服务器。

通过对内存(RAM、持久内存或 Flash)的智能分层访问,支持超大数据集,确保您可以在不显著影响性能的情况下扩展数据集以满足用户的需求。

深入了解有序集合

使用 Redis 的 ZADD 命令很容易创建一个有序集合。例如,想象将一组玩家添加到排行榜。每个玩家包括一个屏幕名称和玩家分数,分数会随着时间不断变化

将玩家添加到有序集合中,只需使用 ZADD 命令并传递集合名称、分数和玩家姓名即可轻松完成

ZADD players 200 Fred

如果集合尚不存在,Redis 将创建它。如果集合存在,则 Redis 会将新数据添加到现有集合中。有序集合中的每个项目都必须是唯一的,因此如果玩家名称(成员)不存在,则会将其添加到集合中。但如果成员已存在,则其值将被设置为提供的新值。内置的有序集合命令可让您轻松执行快速、原生的排序和报告操作。

例如,ZRANGE 命令返回成员范围。ZRANGEBYSCORE 返回指定分数范围内的成员范围。ZRANK 返回指定成员的排名。

Redis 使得使用 ZINCRBY 命令增加任何玩家的分数变得容易,只需传入成员名称和要增加的分数即可。

此外,您可以为您的游戏/应用程序管理多个有序集合。例如,一个全局有序集合包含所有锦标赛的总得分,然后每个锦标赛有多个有序集合。然后您可以使用 Redis 在有序集合之间进行操作的独特能力,例如使用ZUNIONSTORE 进行带权重和不带权重的联合操作。

这些简单的数据示例不显示图形类型数据,但这正是 Redis 有序集合强大之处的一部分:它是内存中的纯数据,不绑定于任何视图。这意味着您可以使用这些数据以您喜欢的任何方式显示它。

如何创建排行榜

让我们快速概览一下如何在 Node.js 中以及与现有 Web 应用程序一起实现排行榜。使用 Node 包管理器 (NPM),通过简单的命令 npm install redis 即可轻松将 Redis 添加到您的 Web 应用程序中。

一旦将 Redis Node 包安装到您的 Web 应用程序项目中,您就可以通过 JavaScript API 访问 Redis 功能。(node_redis Github 存储库的官方文档可以帮助您入门。)

为了演示,让我们使用有序集合创建一个简单的内存数据库。我们将创建名为 player:[uniqueId] 的成员,其中 uniqueId 是一个整数值,当用户加入比赛时,您的 JavaScript 或 Python 代码可以轻松生成它。

分数可以是您想要用来排名玩家的任何数字数据(公司健康计划中的每日步数、电脑游戏中击落的外星人等等)。

基本玩家数据将如下所示

leaderboard-playerdata

现在来看看一段可用于显示数据的 Node.js 代码。

使用哈希存储多个值

您可以创建一个可按多个变量切分的数据集。为此,将数据存储在表示每个竞争对手的结构中很有帮助。Redis 提供了一种这样的结构,称为哈希。哈希可以存储与一个键关联的众多名称-值对。

您可以使用一个简单的数字键作为哈希中的唯一标识符,然后将该唯一键与一个有序集合关联,该集合将包含分数和键。通过这种方式,您可以快速获取您的顶级竞争对手或一组竞争对手的分数。然后,如果您想要更多数据,可以使用存储在有序集合中的键值轻松地从哈希中获取。

创建 Redis 哈希很简单。这个名为 allPlayers 的哈希使用以下格式

hset [ 唯一 ID (用于标识哈希)] [属性名称] [属性值] ...

接下来,创建一个名为 player:100 的新哈希,并添加一个名为 screenName 属性,其值为 Fred。您可以只将哈希键设置为 100,但使用 [stringID:IntegerID] 格式会使其更易读。当您添加另一个玩家时,您将创建一个新的哈希键,如 player:101。

hset player:100 screenName Fred

如果您想检索存储在特定哈希中的所有属性和值(名称-值对),只需使用此命令

hgetall player:100

您可以看到此时有一个名称-值对。

1) "screenName"
2) "Fred"

哈希是一个灵活的结构,并且很容易动态添加属性和值。

想象一下您想保存玩家上次登录的日期

hset player:100 lastLoggedIn 2019-07-30

现在当您再次调用 hgetall 时,您会看到

1) "screenName"
2) "Fred"
3) "lastLoggedIn"
4) "2019-07-30"

只需将每个用户及其唯一的 ID 添加到您的 allPlayers 哈希中即可。然后您可以将这些与包含每个玩家分数的有序集合关联起来。

这里有一个快速图表,展示了如何将您的数据关联起来

leaderboard-datachart

添加哈希(player:NNN)后,您就有了列表,并且可以在向有序集合添加数据时利用这些玩家数据键。这就是您如何利用 Redis 内存数据库的强大功能来处理跟踪每个玩家排名的庞大数据集(数百万玩家!),同时保持惊人的速度。

现在您可以轻松地实现一个使用 Node 和 node_redis 包拉取数据的解决方案,以便在您的 Web 应用程序上保持排行榜的新鲜度。使用 node_redis 包 API 完成这项工作很容易,它允许您按名称 (playerRank) 拉回有序集合。

Redis Enterprise 对于保持排行榜新鲜并让用户不断回来查看他们的排名至关重要。

想了解更多?

观看我们最近关于使用 Redis 实现排行榜最佳实践的技术讲座!

Intro to Leaderboards