精华内容
下载资源
问答
  • redis实现排行榜

    2018-08-27 21:38:18
    redis实现简单排行榜,和消息处理。
  • Redis实现排行榜

    2020-03-19 21:40:36
    Redis作为最为常用的非关系型数据库,具有十分优秀的性能,Redis的多种存储数据结构可以适应各种场景。 Redis作为一款缓存数据库,性能优异,使用Redis...Redis的zset(有序集合)数据结构,天然具备作为排行榜的优势。

    Redis作为最为常用的非关系型数据库,具有十分优秀的性能,Redis的多种存储数据结构可以适应各种场景。

    为什么使用Redis实现排行榜?

    • Redis作为一款缓存数据库,性能优异,使用Redis可以提升服务存取数据的性能。
    • Redis的zset(有序集合)数据结构,天然具备作为排行榜的优势。

    怎么使用Redis实现排行榜?

    • 使用Redis的zset数据结构,其中key为固定值,value为排行榜名称,score为排行分数。
    • 我们记录点击数,每点击一次,排行榜所在的排名越高。
    • Redis的zset数据结构,使用的是从小到大的排序方式,所以我们使用负数来作为排名分数,每点击一次,排行榜的分数-1。

    具体实现

    搭建开发环境

    Redis实现排行榜的项目环境,与Redis实现商品秒杀完全一致,需要的可以到Redis实现商品秒杀中去查看项目环境。

    Dao层

    • Dao层接口
    /**
     * Redis实现排名
     * @author hrp
     * 2020/3/19 16:56
     */
    public interface SortDao {
        /**
         * 点击功能,修改排名,每点击一次,排名分数+1
         * @param key
         * @param name
         * @param score
         */
        void onClick(String key,String name,Double score);
    
        /**
         * 获取所有排名
         * @param key
         * @param start
         * @param end
         * @return
         */
        Set<String> getSort(String key, Long start, Long end);
    
        /**
         * 获取单个的排名分数
         * @param key
         * @param name
         * @return
         */
        Double getScore(String key,String name);
    }
    
    • Dao层实现
    @Repository
    public class SortDaoImpl implements SortDao {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        @Override
        public void onClick(String key, String name, Double score) {
            redisTemplate.boundZSetOps(key).incrementScore(name,score);
        }
    
        @Override
        public Set<String> getSort(String key, Long start, Long end) {
            return redisTemplate.boundZSetOps(key).range(start, end);
        }
    
        @Override
        public Double getScore(String key, String name) {
            return redisTemplate.boundZSetOps(key).score(name);
        }
    }
    

    Service层

    • Service层接口
    public interface SortService {
        /**
         * 点击功能,修改排名,每点击一次,排名分数+1
         * @param name
         * @param score
         */
        void onClick(String name,Double score);
    
        /**
         * 获取所有排名
         * @return
         */
        Set<String> getSort();
    
        /**
         * 获取单个的排名分数
         * @param name
         * @return
         */
        Double getScore(String name);
    }
    
    • Service层实现
    @Service
    public class SortServiceImpl implements SortService {
    
        @Autowired
        private SortDao sortDao;
    
        private final static String KEY = "sort";
    
        @Override
        public void onClick(String name, Double score) {
            sortDao.onClick(KEY,name,score);
        }
    
        @Override
        public Set<String> getSort() {
            return sortDao.getSort(KEY,0L,-1L);
        }
    
        @Override
        public Double getScore(String name) {
            return sortDao.getScore(KEY,name);
        }
    }
    

    测试功能

    @SpringBootTest
    @RunWith(SpringRunner.class)
    public class SortTest {
    
        @Autowired
        private SortService sortService;
    
        private final static String[] NAME = {"张三","李四","王五","赵六","田七","孙八"};
    
        @Before
        public void onClick(){
            for (int i = 0; i < 1000; i++) {
                String name = NAME[new Random().nextInt(6)];
                sortService.onClick(name,-1.0);
            }
        }
    
        @Test
        public void test(){
            Set<String> set = sortService.getSort();
            int i = 1;
            for (String str : set) {
                Double score = sortService.getScore(str);
                System.out.println("第"+i+"名为:"+str+"排名分数为:"+score);
                i++;
            }
    
        }
    }
    

    测试结果

    1名为:孙八排名分数为:-194.02名为:张三排名分数为:-184.03名为:赵六排名分数为:-170.04名为:田七排名分数为:-153.05名为:王五排名分数为:-151.06名为:李四排名分数为:-148.0
    
    展开全文
  • Redis 实现排行榜

    2019-12-09 11:04:33
    不再介绍数据库做实时排行榜的弊端,直接介绍Redis的有序集合的强大作用。 1、从MongoDB中导入数据到Redis

    不再介绍数据库做实时排行榜的弊端,直接介绍Redis的有序集合的强大作用。
    有序集合的数据和集合一样,不能重复,但每个元素又可以关联一个分数,这个分数可以重复。
    需要注意的是,redis版本和命令变化较大,注意运行环境。
    运行环境:
    redis 库版本:3.3.11
    redis版本:3.2.1

    1、从MongoDB中导入数据到Redis

    生成数据:

    import pymongo
    import random
    
    handler = pymongo.MongoClient('mongodb://127.0.0.1:27017').chapter_9.rank_data
    
    for i in range(10000, 10100):
        data = {'user_id': i,
                'score': round(random.random() * 1000, 1)}
        handler.insert_one(data)
    

    导入到有序集合中:

    import pymongo
    import redis
    
    
    handler = pymongo.MongoClient('mongodb://127.0.0.1:27017').chapter_9.rank_data
    client = redis.Redis()
    
    rows = handler.find({}, {'_id': 0})
    for row in rows:
        client.zadd("rank",{row['user_id']:row['score']})
    

    zadd的第二个参数应该是字典。
    查看导入的数据:
    在这里插入图片描述

    2、显示特定排名

    import redis
    
    client = redis.Redis()
    
    count = client.zcard('rank')
    print(f'当前共有{count}人')
    position = client.zrevrank('rank', 10086)+1
    print(f'用户‘10086’的排名为{position}')
    

    在这里插入图片描述

    3、显示全部排名

    import redis
    
    client = redis.Redis()
    
    rank = client.zrevrangebyscore("rank", 100000, 0, withscores=True)
    for index,one in enumerate(rank):
        print(f'排名:{index+1}, 用户ID:{one[0].decode()}, 积分:{one[1]}')
    

    在这里插入图片描述

    展开全文
  • 主要给大家介绍了关于redis实现排行榜的简单方法,文中通过示例代码介绍的非常详细,对大家学习或者使用redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • 主要给大家介绍了关于如何利用redis实现排行榜的小秘诀,文中通过示例代码介绍的非常详细,对大家学习或者使用redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • redis实现排行榜销量排名功能

    千次阅读 2019-06-11 20:34:54
    redis实现排行榜销量排名功能: https://github.com/kingrocy/springboot/tree/master/springboot-redis
    展开全文
  • php+redis实现排行榜demo

    千次阅读 2018-09-17 11:57:41
    php+redis实现排行榜demo 本周上班因为任务分配的原因,跑回去写redis去了.本周继续复习redis,感觉对于redis的实践开始有了新的认识.核心依旧是作为缓存,而不是拿关系型数据库来用.扯远了,本周又写了一些模块,其中...

    php+redis实现排行榜demo


    本周上班因为任务分配的原因,跑回去写redis去了.本周继续复习redis,感觉对于redis的实践开始有了新的认识.核心依旧是作为缓存,而不是拿关系型数据库来用.扯远了,本周又写了一些模块,其中比较好用的是使用redis来实现排行榜,确实好用,快的多,要比传统上使用mysql,存入到数据库中(当然如果能有效利用缓存也能吧速度提升一个数量级,但是还是不如redisdemo稳定),再利用mysql引擎排序来快的多,缺点是需要独立一个zset来保存排行榜.

    有序集合和跳跃表

    提到排行榜的数据结构,最开始毫无疑问我是想到当初写的大根堆,这样的二叉树实现的数据结构的堆排序,从而实现排行榜.不过在redis中使用了更为简单的跳跃表 (当然在工程上通常会更复杂一点,这一类算法,通常会在较小的集合上用另一种简单的数据结构代替复杂数据结构)来实现有序集合.通过有序集合(zset)我们可以实现排行榜这样高效排序.

    功能实现和分析

    通过有序集合保存对应的分数和节点,这是一个非常简单的数据结构.redis的zset提供了众多的接口函数来实现对应的功能.

    在这里我有两个实现思路.
    - 一个是对于需要所有节点都在排行榜里面的,会将所有的节点都放入zset中
    - 只需要特定数量的排行榜.比如我只需要前20件热销商品(或者说这一类需求最集中),这样我只维护一个大小为20的zset,对于最新的分数,会尝试重新插入现有的集合中,并除去最低或者最高的分数.理论上这个算法,在总分数的数量极大之后会更快.

    当然在这里我先实现的第一种思路,这种思路比较简单,所有的插入更新都直接使用zset更新.如果以后有新的需求我会尝试使用第二个思路.

    在这里只实现两个功能,
    - 能够查询每个节点的分数和名次 通过zRevRange函数获取;
    - 能够按名次查询排名前N名的节点通过zRevRank函数获取;

    代码

    这里使用phpredis扩展来实现redis的链接

    <?php
    namespace Leaderboard;
    
    /**
     * 使用rediszset的的商品排行榜
     * @author yiwang
     *        
     */
    class RedisLeaderboard
    {
    
        /**
         *
         * @var object redis client
         */
        private $redis;
        /**
         *
         * @var string 放置排行榜的key
         */
        private $leaderboard;
    
        /**
         * 构造函数
         * @param object $redis 已连接redis的phpredis的对象
         * @param string $leaderboard 字符串,排行榜的key名
         */
        public function __construct($redis = [], $leaderboard = '')
        {
    
            if ($redis) {
              $this->redis = $redis;
            } else {
              $this->redis = new \Redis();
              $this->redis->connect('127.0.0.1');
            }
    
            if ($leaderboard) {
                //这里不会检查当前的key值是否存在,是为了方便重新访问对应的排行榜
                $this->leaderboard = $leaderboard;
            } else {
                $this->leaderboard = 'leaderboard:' . mt(1, 100000);
                while (!empty($this->redis->exists($this->leaderboard))) {
                    $this->leaderboard = 'leaderboard:' . mt(1, 100000);
                }
            }
    
        }
        /**
         * 获取当前的排行榜的key名
         * @return string
         */
        public function getLeaderboard()
        {
            return $this->leaderboard;
        }
        /**
         * 将对应的值填入到排行榜中
         * @param  $node 对应的需要填入的值(比如商品的id)
         * @param number $count 对应的分数,默认值为1
         * @return Long 1 if the element is added. 0 otherwise.
         */
        public function addLeaderboard($node, $count = 1)
        {
            return $this->redis->zAdd($this->leaderboard, $count, $node);
        }
        /**
         * 给出对应的排行榜
         * @param int $number 需要给出排行榜数目
         * @param bool $asc 排序顺序 true为按照高分为第0
         * @param bool $withscores 是否需要分数
         * @param callback $callback 用于处理排行榜的回调函数
         * @return [] 对应排行榜
         */
        public function getLeadboard($number, $asc = true, $withscores = false,$callback = null)
        {
            if ($asc) {
                $nowLeadboard =  $this->redis->zRevRange($this->leaderboard, 0, $number -1, $withscores);//按照高分数顺序排行;
            } else {
                $nowLeadboard =  $this->redis->zRange($this->leaderboard, 0, $number -1, $withscores);//按照低分数顺序排行;
            }
    
    
            if ($callback) {
                //使用回调处理
                return $callback($nowLeadboard);
            } else {
                return $nowLeadboard;
            }
        }
        /**
         * 获取给定节点的排名
         * @param string $node 对应的节点的key名
         * @param string $asc 是否按照分数大小正序排名, true的情况下分数越大,排名越高
         * @return 节点排名,根据$asc排序,true的话,第一高分为0,false的话第一低分为0
         */
        public function getNodeRank($node, $asc = true)
        {
            if ($asc) {
                //zRevRank 分数最高的排行为0,所以需要加1位
                return $this->redis->zRevRank($this->leaderboard, $node);
            } else {
                return $this->redis->zRank($this->leaderboard, $node);
            }
        }
    
    }
    
    
    展开全文
  • Redis实现排行榜设计

    千次阅读 2020-10-16 17:10:21
    redis排行榜功能看似简单易用,但在实际应用中却遇到了很多问题,需要通过适当的操作来设计这个功能。接下来就来理清排行榜的设计思绪吧 1.排行榜的key设计 排行榜一般按照时间段进行分类,分别有周榜,月榜和年榜...
  • SpringBoot继承Redis实现排行榜 项目文件结构 1、修改maven文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=...
  • java+redis实现排行榜排名 主要通过redis的sorted set完成 首先新建一个set结构容器,用于放数据——zset.add(key,value,score); key作为我们存储的整个大集合,value存放的就是我们的元素的名称节点(类似map的key...
  • 本节基于华为云DCS Redis实践所编写,用于指导您在以下场景使用DCS Redis实现排行榜功能。 目录 场景介绍 代码示例 实践指导 运行结果 华为云DCS Redis介绍 场景介绍 在网页和APP中常常需要用到榜单的功能,...
  • 基于redis实现简单、高效的销售排行榜功能 默认查看排行榜列表 还可以查看具体排行列表信息 基于redis和lua的限流
  • mysql+redis实现排行榜

    2020-07-12 13:08:02
    代码逻辑:把mysql中的玩家分数表的数据导到redis中,使用redis中的有序集合zset来实现数据递减排行并返回结果(排行榜) 我们要明确用redis排行榜的意义,如果在mysql中有一张游戏的玩家分数表,那么我们用简单的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,874
精华内容 5,949
关键字:

redis实现排行榜

redis 订阅