在 Ubuntu 20.04 上使用 Redis 和 PHP 创建排行榜

介绍

您可以使用排行榜对游戏化系统中的玩家进行排名。 这是构建应用程序的重要组成部分,其中多个参与者为特定目标而竞争。 排行榜在电脑游戏中被广泛使用,以向同伴展示他们与其他玩家相比的排名。

今天,您可以在各种应用程序中使用排行榜来对表现进行排名。 例如,您可以使用它根据销售人员在给定时间段内的总销售额对他们进行排名。 同样,您可以在健身追踪器应用程序中实施排行榜,任何连接到您的软件的人都可以参加健身联赛和在线挑战。 在金融行业,您可以使用排行榜来监控和检测可疑交易并减少欺诈。

排行榜最棒的地方是创造一种动力; 他们鼓励参与者努力工作并实现他们的目标。 此外,从某种意义上说,排行榜建立了凝聚力,因为参与者根据每次比赛的标准与志同道合的同龄人分组。

虽然排行榜很棒,但消费和处理来自连接到您的应用程序的数千甚至数百万用户的数据以提供实时分析可能​​不适用于传统 SQL 数据库,因为它们将数据保存到磁盘。 对于此任务,您需要一个内存数据库,该数据库可以在没有任何磁盘 IO 开销的情况下大规模读取、写入、切片和排序数据。 这就是 Redis 服务器的用武之地。

Redis 非常适合快速数据摄取,并且可以处理复杂的数学计算(例如,您需要对数据进行分析和排名以创建排行榜的排序集和属性。它还可以处理每秒执行数千个请求的并发客户端。将从更好的角度来看,Redis 可以以闪电般的速度有效处理来自数千个健身设备的计步数据。

在本指南中,您将创建一个使用 php-redis 库来接受数据并在 Ubuntu 20.04 服务器上创建排行榜。

先决条件

在继续之前,请确保您具备以下条件:

一个 Ubuntu 20.04 服务器。 由于 Redis 使用您的计算机内存进行存储,因此请启动具有多个 vCPU 和大量 RAM 的服务器。 一个 sudo 用户。 灯组。 对于本指南,您可以跳过 第2步 (安装数据库服务器)因为您不需要 MySQL/MariaDB 服务器。 一个Redis服务器

1. 安装 Redis 扩展 PHP

在此步骤中,您将安装一个 PHP 扩展,该扩展允许 PHP 脚本通过应用程序编程接口 (API) 与 Redis 服务器通信。 这是一个快速、灵活、功能齐全且用户友好的 Redis 库。

要安装库,请通过 SSH 连接到您的服务器并更新包信息索引。

$ sudo apt update

接下来,运行以下命令安装 php-redis 延期。

$ sudo apt install -y php-redis

通过执行以下命令重新启动 Apache 网络服务器以加载新扩展。

$ sudo systemctl restart apache2

您现在有一个可用于与 Redis 交互的 PHP 扩展。 接下来,您将创建一个 PHP 脚本,该脚本接受用于排名目的的数据。

2. 创建一个接受用户评分的 PHP 脚本

在开始按升序或降序排列数据之前,您应该使用 Redis ZADD 命令将具有各自分数的成员添加到排序集中 ZSET. 如果您已经在一个集合中包含了一个成员,您可以随时通过调用 ZADD 命令针对现有成员的数据。 在后台,Redis 服务器会更新会员的分数和位置。 这 ZADD 命令适用于您有大量更新的情况,因为它非常快。

通过添加成员的分数 redis-server 命令行界面,您应该使用下面的语法。

$ redis-cli

127.0.0.1:6379> ZADD NAME_OF_THE_SORTED_SET SCORE_VALUE MEMBER_NAME
127.0.0.1:6379> quit

例如,给名为的成员添加 1768 的分数 Fred,使用下面的语法。

$ redis-cli

127.0.0.1:6379> ZADD players 1768 Fred
127.0.0.1:6379> quit

在本指南中,您将创建一个 PHP 脚本,使用 Redis 自动执行整个过程 zadd 功能。 使用 nano 文本编辑器打开一个新的 zadd.php 通过执行以下命令在您的 Web 服务器的根目录中创建文件。

$ sudo nano /var/www/html/zadd.php

然后,在文件中输入以下信息。

<?php 

$redis = new Redis(); 
$redis->connect('127.0.0.1', 6379); 

$seller      = $_POST['seller'];
$total_sales = $_POST['total_sales'];

$redis->zadd('sales_persons', $total_sales, $seller);

echo "You've successfully added the seller's sales into the Redis server.n";

完成编辑后保存并关闭文件。 在上面的文件中,您正在连接到 Redis 服务器。 然后,您正在侦听来自客户端应用程序的两个 HTTP POST 变量。 变量 $_POST['seller'] 保存您希望添加到排序集中的成员名称。 然后,您从 $_POST['total_sales'] 多变的。

在此脚本中,您只是根据员工的销售额接受销售人员数据。 然后,您将每个参与员工的数据添加到名为 sales_persons.

接下来,您将使用 Linux 模拟一些销售记录 curl 命令。 您可能会发现在生产环境中通过 API 从您的发票软件提供销售数据比手动添加更容易,尤其是当您有许多销售人员时,例如网络托管推荐系统。

现在,执行以下命令 7 命令反对 zadd.php 将销售人员的数据添加到 Redis 服务器的脚本。

$ curl --data "seller=JOHN DOE&total_sales=9749" http://localhost/zadd.php
$ curl --data "seller=MARTHA SMITH&total_sales=1822" http://localhost/zadd.php
$ curl --data "seller=PETER JACOB&total_sales=4437" http://localhost/zadd.php
$ curl --data "seller=ESTHER ERIC&total_sales=6849" http://localhost/zadd.php
$ curl --data "seller=JANE ERIC&total_sales=2256" http://localhost/zadd.php
$ curl --data "seller=MARY PATRICK&total_sales=7894" http://localhost/zadd.php
$ curl --data "seller=PETER MARTIN&total_sales=3526" http://localhost/zadd.php

确保在运行每个命令后收到以下输出,以确保数据就位。

...
You've successfully added the seller's sales into the Redis server.

您现在有一个可用的 Redis 排序集,其中填充了一些记录。 接下来,您将使用 Redis ZREVRANGE 函数对数据进行排序。

3. 创建并测试 PHP 排行榜脚本

您应该按照销售额从最高值到最低值的顺序对您的销售数据进行排序。 也就是说,按降序排列。 您可以在命令行界面中通过执行 ZREVRANGE 使用以下语法针对您的排序集。

$ redis-cli

127.0.0.1:6379> ZREVRANGE NAME_OF_THE_SORTED_SET START END WITHSCORES

例如,要获取按升序排列的所有销售人员的列表以及它们之间的关联销售额 0 美元20 万美元,运行以下命令。

$ redis-cli

127.0.0.1:6379> ZREVRANGE sales_persons 0 200000 WITHSCORES

您应该得到以下输出。

 1) "JOHN DOE"
 2) "9749"
 3) "MARY PATRICK"
 4) "7894"
 5) "ESTHER ERIC"
 6) "6849"
 7) "PETER JACOB"
 8) "4437"
 9) "PETER MARTIN"
 10) "3526"
 11) "JANE ERIC"
 12) "2256"
 13) "MARTHA SMITH"
 14) "1822"

从 Redis 服务器命令行界面退出。

127.0.0.1:6379> quit

您将通过使用 zRevRange PHP 脚本中的函数。 这一次,您将使用一些 PHP 函数以更易读的格式构建排行榜。

为此,请使用 nano 打开一个空白 /var/www/html/leaderboard.php 文件。

$ sudo nano /var/www/html/leaderboard.php

接下来,将以下信息输入到 /var/www/html/leaderboard.php 文件。

<?php 

$redis = new Redis(); 
$redis->connect('127.0.0.1', 6379);     

$result = $redis->zRevRange('sales_persons', 0, 200000, true);      

echo  "n" . str_repeat("-", 40);  
echo "nSALES RANK BY HIGHEST SELLERn";
echo  str_repeat("-", 40) . "n";
echo "nRANK  NAME                         SCORE n";
echo  str_repeat("=", 40) . "n";

$i = 1;

foreach($result as $key => $value) {
    echo str_pad($i, 6, " ") . str_pad($key, 17, " ") . str_pad($value, 17, " ", STR_PAD_LEFT) . "n";
    $i++;
}

保存并关闭文件。 在上面的文件中,您正在初始化一个新的 Redis 实例。 然后,您正在调用 $redis->zRevRange 用于检索卖家之间的销售数据的功能 0 美元20 万美元 来自 sales_persons 使用语句排序的集合 $result = $redis->zRevRange('sales_persons', 0, 200000, true);.

该声明 $redis->zRevRange 将销售数据作为数组返回,并且您正在使用 PHP foreach(...) 声明 echo 列出销售人员的姓名及其相关的销售额。 然后,您正在使用 PHP str_repeatstr_pad 函数将数组格式化为人类可读的报告。

为了测试 leaderboard.php 脚本,执行 leaderboard.php 使用 Linux 的脚本 curl 命令。

$ curl http://localhost/leaderboard.php

您现在应该得到以下输出。 如你看到的, 约翰·多伊 销售领先,其次是 玛丽·帕特里克.

----------------------------------------
SALES RANK BY HIGHEST SELLER
----------------------------------------

RANK  NAME                         SCORE
========================================
1     JOHN DOE                      9749
2     MARY PATRICK                  7894
3     ESTHER ERIC                   6849
4     PETER JACOB                   4437
5     PETER MARTIN                  3526
6     JANE ERIC                     2256
7     MARTHA SMITH                  1822

要测试排行榜是否能够在变化时处理实时数据,请执行以下操作 curl 添加命令 2 更多销售记录。

$ curl --data "seller=MARTHA KATE&total_sales=3940" http://localhost/zadd.php
$ curl --data "seller=ZABRON JAMES&total_sales=12400" http://localhost/zadd.php

输出。

...
You've successfully added the seller's sales into the Redis server.

执行 leaderboard.php 再次脚本检查Redis服务器是否更新了排名。

$ curl http://localhost/leaderboard.php

正如您从下面的输出中看到的 约翰·多伊 已被超越 詹姆士.

----------------------------------------
SALES RANK BY HIGHEST SELLER
----------------------------------------

RANK  NAME                         SCORE
========================================
1     ZABRON JAMES                 12400
2     JOHN DOE                      9749
3     MARY PATRICK                  7894
4     ESTHER ERIC                   6849
5     PETER JACOB                   4437
6     MARTHA KATE                   3940
7     PETER MARTIN                  3526
8     JANE ERIC                     2256
9     MARTHA SMITH                  1822

上面的输出证实了确实,Redis 服务器经过了很好的优化,适合处理排行榜。 在生产环境中,您应该轮询 leaderboard.php 脚本并每隔几秒钟在客户端应用程序中显示结果,以获得销售人员的更新排名。 这将鼓励健康的竞争,因为员工很难出现在名单的首位。

在本指南中,您将使用 Redis 排行榜来检查并可能奖励勤奋的销售人员。 这个逻辑在其他不同的场景中非常有用。 例如,如果您有接受信用卡的订阅服务,您可以使用排行榜来检查来自单个客户的排名最高的订单以检测欺诈。 同样,在多作者博客中,您可以使用记分板根据来自博客文章的独特页面浏览量或点击量实时观看表现最佳的博主。

结论

在本指南中,您已经在 Ubuntu 20.04 上运行的 Redis 服务器上使用 PHP 构建了一个实时排行榜脚本。 由于像 MySQL 这样的关系数据库管理系统对于排行榜的表现不是最佳的,您应该使用 Redis 服务器,因为它经过优化,可以每秒处理数千次写入。 Redis 内存处理在设计时考虑到了速度,是最适合以近乎即时的速度处理数千个并发用户的平台。

注:本教程在Vultr VPS上测试通过,如需部署请前往Vultr.com