java基于Redis 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。
话不多说先上效果图
数据存储格式
前面说了,用户排行需要用户的昵称,头像,甚至还有可能需要用户id,所以我是这样存储的。
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下来之后跑一跑就知道怎么回事了。
源码下载
源码地址:https://download.csdn.net/download/nxw_tsp/25866908
源码下载后详情请看:README.MD