作者:zhanhailiang 日期:2014-12-02
本文将讲解如何基本Redis Sorted Set实现排行榜功能?
首先,请参见Redis数据类型:http://redis.cn/topics/data-types.html
如上所见,Redis有序集合非常适用于有序不重复数据的存储,例如游戏开发中无处不在的排行榜,如等级排行榜,经验排行榜,积分排行榜,历史筹码排行榜等。如果沿用传统的方法,一般是通过后端的定时任务去跑数据来生成排行榜数据,这种方法一方面无法满足产品对功能实时性的要求,另一方面也一定程度上消耗服务器端有限的资源。
以下举例说明如何实现一个积分排行榜:
1. 生成排行榜:
<?php
// vim: set expandtab cindent tabstop=4 shiftwidth=4 fdm=marker:
/**
* @file initRank.php
* @version 1.0
* @author wade
* @date 2014-12-02 21:26:11
* @desc 本文讲述如何基本redis有序集合生成游戏排行榜数据
*/
$redis = new Redis();
$redis->connect('127.0.0.1', '6379');
$scoreKey = 'user:score';
// init rank
$uidList = range(10000, 20000); // 初始化列表
shuffle($uidList);
foreach ($uidList as $uid) {
$score = mt_rand(1, 10000000);
$redis->zAdd($scoreKey, $score, $uid);
}
2. 获取排行榜前50名数据:
<?php
// vim: set expandtab cindent tabstop=4 shiftwidth=4 fdm=marker:
/**
* @file initRank.php
* @version 1.0
* @author wade
* @date 2014-12-02 21:26:11
* @desc 本文讲述如何基本redis有序集合生成游戏排行榜数据
*/
$redis = new Redis();
$redis->connect('127.0.0.1', '6379');
$scoreKey = 'user:score';
// get top 50
// zrange user:score -50 -1 withscores
$top50List = $redis->zRange($scoreKey, -50, -1, TRUE);
var_export($top50List);
查看输出的积分排行榜前50名用户数据如下:
[root@~/wade/codeReview/generate-rank-with-redis-sorted-set]# /usr/local/php/bin/php rank.php
array (
13297 => '9951424',
17470 => '9951938',
17397 => '9952228',
19427 => '9953388',
16800 => '9953838',
19573 => '9954141',
10100 => '9954436',
11310 => '9955425',
19995 => '9955665',
12099 => '9959696',
11619 => '9962507',
17208 => '9962572',
15769 => '9963074',
19104 => '9963218',
16343 => '9965226',
11645 => '9965375',
13185 => '9965506',
18588 => '9968756',
19764 => '9968885',
13172 => '9969011',
18031 => '9970756',
10349 => '9971091',
14612 => '9972515',
17465 => '9974447',
15812 => '9974457',
10341 => '9974813',
15415 => '9974895',
12187 => '9974950',
12426 => '9978519',
13607 => '9979284',
11375 => '9980609',
10921 => '9981700',
16360 => '9983399',
19203 => '9984767',
18970 => '9984776',
12227 => '9984834',
17479 => '9986766',
19803 => '9986937',
19509 => '9987704',
11215 => '9988372',
18280 => '9989817',
10092 => '9990978',
19089 => '9992132',
11744 => '9992693',
12533 => '9994185',
14711 => '9994771',
18623 => '9996266',
16919 => '9997883',
10886 => '9998931',
11263 => '9999083',
)
源码请见:https://github.com/billfeller/generate-rank-with-redis-sorted-set