java基于Redis Zset实现排行榜功能

  • 前言
  • 做之前要思考的问题?
  • Zset怎么存储需要的多个字段?
  • 话不多说先上效果图
  • 数据存储格式
  • 代码
  • 源码下载


闲暇之余,整理了一下之前利用Redis Zset数据类型实现的排行榜功能。

前言

排行榜功能之所以选用redis是因为,参加的用户数据量较大,有将近20万人,如果前100名排行从数据库中查的话也不是不可以,但相对于redis来说,还是不够看的,所以当时就把排行榜的功能做在了redis里。

做之前要思考的问题?

Redis数据类型那么多,到底用哪个数据类型呢?
我们可以根据需求特点来进行选型,首先排行榜是有序的,并且不能有重复的数据,根据这个特点,发现Zset这个数据类型符合我们的要求。

Zset怎么存储需要的多个字段?

Zset只可以存储value和score,需要用户的昵称和头像以及用户id和分数,这怎么存储啊。首先我们可以把排序值分数存储在score中,至于用户昵称,头像和用户id我们可以用分隔符分开一起存进value中。例如10002#王二#https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83erHB8aIib1R0B0iadpMmHRsyLF2loxLia7Mx3aZv9obHGgUJcl0ibBBys4QRZwAL0J5a81VRfU1jHBexg/132

Java 客户端开发包选用的是Jedis。

话不多说先上效果图

redis积分排行榜 redis排行榜保存前100名_redis


redis积分排行榜 redis排行榜保存前100名_redis_02

数据存储格式

前面说了,用户排行需要用户的昵称,头像,甚至还有可能需要用户id,所以我是这样存储的。

redis积分排行榜 redis排行榜保存前100名_排行榜_03


value里存了多个字段用#分割开,用的时候通过split()得到一个数组,就可以拿到这些数据啦,当然,你也可以存储为json格式等等。

代码

//ServiceImp层的 两个方法

Jedis jedis = new Jedis("127.0.0.1", 6379);

    @Override
    public List<UserScore> getUserScoreList() {
        // 按照用户分数多少排行,取出前五名
        Set<Tuple> tuples = jedis.zrevrangeWithScores("user-score", 0, 4);
        List<UserScore> list = new ArrayList<>();
        int ranking = 0;
        for (Tuple tuple : tuples) {
            UserScore us = new UserScore();
            String element = tuple.getElement();
            String[] arr = element.split("#");
            us.setScore((int) tuple.getScore());
            ranking++;
            us.setRanking(ranking);
            us.setName(arr[1]);
            us.setImg(arr[2]);
            list.add(us);
        }
        return list;
    }

@Override
    public Long insertUserScore(UserScore userScore) {
        String value = userScore.getUserid()+"#"+userScore.getName()+"#"+userScore.getImg();
        final Long zadd = jedis.zadd(Constants.USER_SCORE, userScore.getScore(), value);
        return zadd;
    }
//controller层的三个方法
 @RequestMapping("/")
    public ModelAndView home() {

        ModelAndView view = new ModelAndView("index");

        List<UserScore> rankingList = userService.getUserScoreList();
        view.addObject("rankingList", rankingList);
        return view;
    }

    @RequestMapping("/add")
    public ModelAndView add() {

        ModelAndView view = new ModelAndView("add");

        return view;
    }

    @RequestMapping("/addUserScore")
    public ModelAndView addUserScore(UserScore userScore) {

        ModelAndView view = new ModelAndView("index");
        Long zadd = userService.insertUserScore(userScore);
        if(zadd !=null && zadd!=0){
            List<UserScore> rankingList = userService.getUserScoreList();
            view.addObject("rankingList", rankingList);
        }
        return view;
    }

代码很简单,只是没有上过手的觉得会很麻烦。
如果这些代码还不能满足你的话,看源码吧。源码down下来之后跑一跑就知道怎么回事了。

源码下载

源码下载后详情请看:README.MD

redis积分排行榜 redis排行榜保存前100名_redis_04