比如说要按玩家的筹码排行,基本思路是把玩家的筹码做为score,把玩家的ID做为value插入到redis的有序集中。虽然这个key里面的数据会有很多,但是我们需要的只是前面200个玩家。这时玩家查询的时候,我们只需要反序查出前面的200个玩家就可以了。

离线统计排行榜

打个比方,有一个用户信息表保存在redis,类型为hashmap。key为用户ID,value为用户对象的json串。每个json串都含有筹码字段userChips,等级字段userLevel,胜局字段userWin,总参加局数字段userJoin。现在需要统计用户的筹码排行,等级排行和胜率排行。用户排行d_chips_top,等级排行d_level_top和胜率排行d_win_top在redis中的格式都为有序集。

进行统计的脚本文件top.sh如下:

#!/bin/bash
cd /www
echo "del d_chips_top" | redis-cli -p 6382
echo "del d_level_top" | redis-cli -p 6382
echo "del d_win_top" | redis-cli -p 6382
if [ -f result.txt ]
then
    rm -rf result.txt
fi
if [ -f userId.txt ]
then
    rm -rf userId.txt
fi
if [ -f userChips.txt ]
then
    rm -rf userChips.txt
fi
if [ -f userLevel.txt ]
then
    rm -rf userLevel.txt
fi
if [ -f userWin.txt ]
then
    rm -rf userWin.txt
fi
if [ -f userJoin.txt ]
then
    rm -rf userJoin.txt
fi
if [ -f user.txt ]
then
    rm -rf user.txt
fi
echo "hgetall d_user" | redis-cli -p 6382 >> user.txt
cat user.txt | grep -Po '"userId":.*?[^\\]"' | awk -F'userId":' '{print $2}'|awk -F, '{print $1}' > userId.txt
cat user.txt | grep -Po '"userChips":.*?[^\\]"' | awk -F'userChips":' '{print $2}'|awk -F, '{print $1}' > userChips.txt
cat user.txt | grep -Po '"userLevel":.*?[^\\]"' | awk -F'userLevel":' '{print $2}'|awk -F, '{print $1}' > userLevel.txt
cat user.txt | grep -Po '"userWin":.*?[^\\]"' | awk -F'userWin":' '{print $2}'|awk -F, '{print $1}' > userWin.txt
cat user.txt | grep -Po '"userJoin":.*?[^\\]"' | awk -F'userJoin":' '{print $2}'|awk -F, '{print $1}' > userJoin.txt
paste userId.txt userChips.txt userLevel.txt userWin.txt userJoin.txt >result.txt
cat result.txt | while read userId userChips userLevel userWin userJoin
    do
        echo "zadd d_chips_top "$userChips $userId | redis-cli -p 6382
        echo "zadd d_level_top "$userLevel $userId | redis-cli -p 6382
        if [ $userJoin -gt 0 ];then
            re=`echo "scale=4;$userWin/$userJoin"|bc`
            rate=`echo "scale=0;$re*10000"|bc`
            echo "zadd d_win_top "$rate $userId | redis-cli -p 6382
        else
            echo "zadd d_win_top "0 $userId | redis-cli -p 6382
        fi
    done

if [ -f result.txt ]
then
    rm -rf result.txt
fi
if [ -f userId.txt ]
then
    rm -rf userId.txt
fi
if [ -f userChips.txt ]
then
    rm -rf userChips.txt
fi
if [ -f userLevel.txt ]
then
    rm -rf userLevel.txt
fi
if [ -f userWin.txt ]
then
    rm -rf userWin.txt
fi
if [ -f userJoin.txt ]
then
    rm -rf userJoin.txt
fi
if [ -f user.txt ]
then
    rm -rf user.txt
fi
echo "排行榜数据生成完毕..."

大概思路是,把用户信息从redis导出为文本。再从这个文本里面提取需要的数据。然后把这几个数据文件合并。最后处理合并后的文件,把数据插入到redis里面。

关于排行榜的设计可参考云风所写的:谈谈陌陌争霸在数据库方面踩过的坑(排行榜篇)

(完)