Redis中Sort Set如何使用?

本文和大家分享的主要是RedisSort Set相关内容,一起来看看吧,希望对大家学习redis有所帮助。

  游戏服务器需要做一个排行榜实时更新,如果沿用传统的方法,一般是通过后端的定时任务去跑数据来生成排行榜数据,这种方法一方面无法满足产品对功能实时性的要求,另一方面也一定程度上消耗服务器端有限的资源。如果从每次数据库读取数据并进行排名(使用Mysqlsort关键字进行排序),在关卡数据量的级数大时是一种效率低的方法。在查阅大量资料后,发现了Redis中的有序集合(Sort Set)

  Redis有序集合

  Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 2^32 - 1

  应用场景

  Redis有序集合非常适用于有序不重复数据的存储,例如游戏开发中无处不在的排行榜,如等级排行榜,经验排行榜,积分排行榜,历史筹码排行榜等。

  相关命令

  .ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数

  .ZCARD key 获取有序集合的成员数

  .ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合成指定区间内的成员

  .ZRANK key member 返回有序集合中指定成员的索引

  .ZREM key member [member ...] 移除有序集合中的一个或多个成员

  .ZREVRANK key member 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序

  使用场景

  1.输入5个用户的积分(uid, score), 实现top-3的查询某个用户更新积分再次查询top-3.

  2.添加积分:添加 (player0001, 1800), (player0002, 1987), (player0003, 965), (player0004, 4382), (player0005, 0), 并假定 rank sorted setname.

  3.查询5人的积分排行榜;

  4.更新player005的积分;

  5.重新查询5人的积分排行榜;

  PHP实现

  排行榜思想:玩家每次积分发生变动时,更改Redis中相应玩家的积分。当客户端向服务器请求调用GetRank时,php服务器调用zrangeRank函数,返回相应的数据。

  /**

  * 更新排行榜数据

  */

  protected function initRankingList()

  {

  $account = new AccountModel();

  $list = $account->getAccountIdList();

  foreach ($list as $k => $v) {

  $ranks = $this->getStageStar($v["id"]);

  $this->zsetRank($ranks["star"], $ranks["rainbow"], $ranks["wing"], $v["id"]);

  }

  }

  /**

  * 更新某个玩家的排行榜数据

  * @param $playerid

  */

  protected function setPlayerRank($playerid)

  {

  $ranks = $this->getStageStar($playerid);

  $this->zsetRank($ranks["star"], $ranks["rainbow"], $ranks["wing"], $playerid);

  $this->hsetOption($playerid, $ranks["star"], $ranks["rainbow"], $ranks["wing"]);

  }

  protected function setStars($playerid)

  {

  $ranks = $this->getStageStar($playerid);

  $this->hsetOption($playerid, $ranks["star"], $ranks["rainbow"], $ranks["wing"]);

  }

  /**

  * 设置分数

  * @param $star

  * @param $rainbow

  * @param $wing

  * @param $playerid

  *

  * @throws \\Exception

  */

  protected function zsetRank($star, $rainbow, $wing, $playerid)

  {

  if ($this->redis == null) {

  throw new \\Exception("can not connect redis");

  }

  $score = C("STAR_SCORE") * $star + C("RAINBOW_SCORE") * $rainbow + C("WING_SCORE") * $wing;

  $this->redis->zAdd($this->rank, $score, $playerid);

  }

  /**

  * 获取某个用户的排名

  * @param $playerid

  *

  * @return int

  * @throws \\Exception

  */

  protected function zrevRank($playerid)

  {

  if ($this->redis == null) {

  throw new \\Exception("can not connect redis");

  }

  $res = $this->redis->zRevRank($this->rank, $playerid);

  return $res;

  }

  /**

  * 获取某个范围的用户排名

  * @param $start

  * @param $stop

  *

  * @return array

  * @throws \\Exception

  */

  protected function zrangeRank($start, $stop)

  {

  if ($this->redis == null) {

  throw new \\Exception("can not connect redis");

  }

  $res = $this->redis->zRevRange($this->rank, $start, $stop, "WITHSCORES");

  return $res;

  }

  /**

  * 删除某个用户的排名

  * @param $playerid

  *

  * @return int

  * @throws \\Exception

  */

  protected function zdeleteRank($playerid)

  {

  if ($this->redis == null) {

  throw new \\Exception("can not connect redis");

  }

  $res = $this->redis->zRem($this->rank, $playerid);

  return $res;

  }

 

 

来源:简书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值