一、什么是热点数据
在很短的时间内,许多数据要被多次查询(像双十一购物,查询商品)
二、为什么要使用redis
redis是非关系型数据库,Redis将数据存储在内存上,避免了频繁的IO操作,接下来,让大家正真感受下redis的魅力
三、场景
短时间内有大量的请求来获取用户列表的数据,每次都需要从数据库进行查询
1、原思路
技术:SpringBoot+mysql
每次都从mysql数据库中查出对应的数据
代码如下:
entity类(实现序列化接口):
/**
* 用户实体类*/
public classUser implements Serializable {private static final long serialVersionUID = 1L;private intid;privateString name;private intage;public User(int id, String name, intage) {this.id =id;this.name =name;this.age =age;
}public intgetId() {returnid;
}public void setId(intid) {this.id =id;
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
@OverridepublicString toString() {return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
controller层:
/*** 控制层*/@RestControllerpublic classRedisController {
@AutowiredprivateRedisService redisService;
@GetMapping("/queryUserList")publicString queryUserList(){long start =System.currentTimeMillis();//采用多线程进行模拟
ExecutorService fixThreadPool = Executors.newFixedThreadPool(3);//创建执行任务
Runnable runnable = () ->{
redisService.queryUserList();
};//循环执行
for(int i = 0;i < 10000;i++){
fixThreadPool.execute(runnable);
}
// 用来计算操作时间fixThreadPool.shutdown();longend;while(true){if(fixThreadPool.isTerminated()) {
end= System.currentTimeMillis() -start;break;
}
}return "程序运行时间为:"+end + "毫秒";
}
}
service层:
/*** 业务层*/@Servicepublic classRedisService {
@Autowiredprivate RedisTemplateredisTemplate;
@AutowiredprivateRedisMapper redisMapper;public ListqueryUserList(){
List userList =redisMapper.queryUserList();returnuserList;
}
}
dao层:
java:
/*** dao层*/@Mapperpublic interfaceRedisMapper {public ListqueryUserList();
}
xml:
/p>
"https://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
select * from user
运行:
查看结果:
嗯。。。。。50s,用户体验应该不算太好
2、整合redis
思路:
SpringBoot集成redis不再多说,基本思路就是用户首次访问从数据库中取值,之后每次进行判断只要redis中有数据,就从redis中取值,其中涉及到多线程访问早造成的内存穿透问题,采用双重检查的形式解决。
其他层没有变化,业务层的新代码如下:
/*** 业务层*/@Servicepublic classRedisService {
@Autowiredprivate RedisTemplateredisTemplate;
@AutowiredprivateRedisMapper redisMapper;public ListqueryUserList(){//设置序列化
RedisSerializer redisSerializer = newStringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
List userList = (List)redisTemplate.opsForValue().get("userList");//防止首次访问该接口有大量用户,造成内存穿透,使redis没有效果
if(null ==userList){synchronized (this){if(null ==userList){
System.out.println("从mysql中查询数据中。。。。。。");//从数据库中查询数据
userList =redisMapper.queryUserList();
System.err.println(userList);//放入redis
redisTemplate.opsForValue().set("userList",userList);
}
}
}else{
System.out.println("从redis中查询数据中。。。。。。");
}returnuserList;
}
再次访问结果如下:
比原来的快:18倍左右
这是首次访问呦(需要查一次mysql)
再来访问一次:
不得不说redis果然快(快了75倍)
四、总结
redis集成SpringBoot用于查询热点数据果然好用,接下来在看看redis的其他应用场景。