Redis leaderboard implementation and matters needing attention and problems

 

Initialize some data

        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);

Query data, ranking

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));

For reverse order, it is generally sufficient to add a reverse in front of the query

Here is the result

Number of people counted: 100
The base of the set is: 100
["Zhang San 0", "Zhang San 1", "Zhang San 2", "Zhang San 3",…………, "Zhang San 98", "Zhang San 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);

Li four score: true
1

Execute again

Li four score: false
1

If set to 2.5, the personal ranking returns to 3

If the order is reversed, reverseRank is used, and the personal ranking returns to 98

Double score = redisTemplate.opsForZSet().incrementScore(SCORE_RANK, "李四", 1);
System.out.println("李四分数+1后:" + score);

Executed twice 

After Lee's fourth score +1: 2.0

If it is during reconstruction, how can the data of db and redis be synchronized to avoid data inconsistency?

In business, we generally query this user first, and then determine whether the addition or subtraction is satisfied; this score is already calculated, you can use the add operation of redis to add/update the current data, it is recommended not to use incre, to avoid more or less I don’t know, but add can guarantee idempotence

Then find out all the data and add to redis, if the program has been executed, it will return false

Then you can use the query leaderboard interface

 

There is a problem here. We usually use username or userid as the value, take the score and add it to redis. When querying the ranking, if it is userid-score, I need to know the corresponding username and check the database later, but generally The service as the ranking list does not care about this, the business side finds it by itself

 

 

 

Guess you like

Origin blog.csdn.net/Goligory/article/details/105810344