Redis作为最为常用的非关系型数据库,具有十分优秀的性能,Redis的多种存储数据结构可以适应各种场景。
为什么使用Redis实现排行榜?
- Redis作为一款缓存数据库,性能优异,使用Redis可以提升服务存取数据的性能。
- Redis的zset(有序集合)数据结构,天然具备作为排行榜的优势。
怎么使用Redis实现排行榜?
- 使用Redis的zset数据结构,其中key为固定值,value为排行榜名称,score为排行分数。
- 我们记录点击数,每点击一次,排行榜所在的排名越高。
- Redis的zset数据结构,使用的是从小到大的排序方式,所以我们使用负数来作为排名分数,每点击一次,排行榜的分数-1。
具体实现
搭建开发环境
Redis实现排行榜的项目环境,与Redis实现商品秒杀完全一致,需要的可以到Redis实现商品秒杀中去查看项目环境。
Dao层
- Dao层接口
/**
* 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层实现
@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层接口
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层实现
@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);
}
}
测试功能
@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名为:孙八排名分数为:-194.0
第2名为:张三排名分数为:-184.0
第3名为:赵六排名分数为:-170.0
第4名为:田七排名分数为:-153.0
第5名为:王五排名分数为:-151.0
第6名为:李四排名分数为:-148.0