初始化一些数据
Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
DefaultTypedTuple<String> tuple = new DefaultTypedTuple<>("张三" + i, 1D + i);
tuples.add(tuple);
}
System.out.println("循环时间:" +( System.currentTimeMillis() - start));
Long num = redisTemplate.opsForZSet().add(SCORE_RANK, tuples);
System.out.println("批量新增时间:" +(System.currentTimeMillis() - start));
System.out.println("受影响行数:" + num);
查询下数据,排行榜
Long count = redisTemplate.opsForZSet().count(SCORE_RANK, 0, 300);
System.out.println("统计0-300之间的人数:" + count);
Long aLong = redisTemplate.opsForZSet().zCard(SCORE_RANK);
System.out.println("集合的基数为:" + aLong);
//根据分数正序排名返回 只有value
Set set = redisTemplate.opsForZSet().rangeByScore(SCORE_RANK, 0, 200);
System.out.println(JSON.toJSONString(set));
//返回value何score
Set<ZSetOperations.TypedTuple> s = redisTemplate.opsForZSet().rangeByScoreWithScores(SCORE_RANK, 0, 200);
System.out.println(JSON.toJSONString(s));
对于倒序一般在查询的前面加个reverse就可以了
下面是结果
统计的人数:100
集合的基数为:100
["张三0","张三1","张三2","张三3",…………,"张三98","张三99"]
[{"score":1.0,"value":"张三0"},{"score":2.0,"value":"张三1"},{"score":3.0,"value":"张三2"},{"score":4.0,"value":"张三3"},………… ,{"score":99.0,"value":"张三98"},{"score":100.0,"value":"张三99"}]
//新增/更新 变动则更新成功,否则失败
boolean score = redisTemplate.opsForZSet().add(SCORE_RANK, "王五", 1);
System.out.println("李四分数 :" + score);
//获取个人排名
Long d = redisTemplate.opsForZSet().rank(SCORE_RANK, "王五");
System.out.println(d);
李四分数 :true
1再次执行
李四分数 :false
1
如果设置为2.5,则个人排名返回3
如果倒序,则用reverseRank,个人排名返回98
Double score = redisTemplate.opsForZSet().incrementScore(SCORE_RANK, "李四", 1);
System.out.println("李四分数+1后:" + score);
执行了两次
李四分数+1后:2.0
如果是重构时,db和redis的数据怎么同步才能避免数据不一致?
业务上一般我们都会先查询这个用户,然后判断是否满足加或者减;这个分数已经是算好的,可以使用redis的add操作添加/更新当前数据,建议不用incre,避免多了或是少了都不知道,而add可以保证幂等
然后把所有数据查出来add到redis,如果程序已经执行了就会返回false
然后可以使用查询排行榜接口了
这里有一个问题,我们一般会用username或者userid作为value,取分数 add到redis中,查询排行榜的时候如果是userid-score,我要知道对应的username,后续就查库就可以了,不过一般作为排行榜的服务不关心这个,业务方自己找