每一秒钟的时间都值得铭记

0%

Redis实现排行榜

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

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

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

    怎么使用Redis实现排行榜?

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

    具体实现

搭建开发环境

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

Dao层

  • Dao层接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 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层实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@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层接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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层实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@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);
}
}

测试功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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
2
3
4
5
6
1名为:孙八排名分数为:-194.0
2名为:张三排名分数为:-184.0
3名为:赵六排名分数为:-170.0
4名为:田七排名分数为:-153.0
5名为:王五排名分数为:-151.0
6名为:李四排名分数为:-148.0
坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------