redis缓存优化数据读取速度
缓存读取
原理,通过读取缓存增快数据读取速度,减轻数据库访问压力。
读取方面,首先通过读取缓存是否有数据,没有数据就去数据库里读取数据,并带会给缓存。
更新方面,只要增删改了数据,那么先更新数据库,再删除缓存
并且更新缓存时做个休眠,维持数据一致性。
防止出现如下图情况:
用户B在redis缓存中没有拿到数据,从数据库中取到了旧数据数据,因为网络延迟,用户A更新完数据库后,删除了缓存,用户B才把旧数据更新会redis中,这样会造成数据redis和数据库中的数据不一致。
于是,延迟删除缓存,有利于等待旧数据更新完在缓存之后,再次清空redis,保证旧数据不会再被写入到redis中。
备注:
1、为了防止缓存雪崩(所有缓存在同一时间内同时失效),可以通过设置缓存时间为随机时间,这样就不会造成所有的缓存在同一时间内同时失效的情况
2、为了防止缓存穿透(数据库和缓存中都没有数据),被用户频繁访问,从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒
3、为了防止缓存击穿(缓存中没有数据,数据库中有数据),并发用户访问同一数据。解决:(1)设置缓存设置热点数据永远不过期。(2)接口限流与熔断,降级。(3)加个互斥锁,从数据库中读取数据的时候增加锁,减轻大量并发用户同时访问数据库的情况。
@RestController
@RequestMapping("/user/order")
public class UserOrderController extends BaseController {
@Autowired
private UserOrderService userOrderService;
@Autowired
private RedisCache redisCache;
@GetMapping("/list")
public AjaxResult list() {
List<UserOrderEntity> list = redisCache.getCacheObject(orderList.list.getValue());
if(list != null){
success(list);
}
list = userOrderService.list();
if (!list.isEmpty()){
// 随机时间存储
redisCache.setCacheObject(orderList.list.getValue(),list, (new Random()).nextInt(100)*60*60, TimeUnit.SECONDS);
}else{
redisCache.setCacheObject(orderList.list.getValue(),list, 30, TimeUnit.SECONDS);
}
return success(list);
}
@PostMapping
public AjaxResult add(@RequestBody UserOrderEntity userOrder) {
userOrderService.save(userOrder);
try {
Thread.sleep(500);
return success(redisCache.deleteObject(orderList.list.getValue()));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
@PutMapping
public AjaxResult update(@RequestBody UserOrderEntity userOrder) {
userOrderService.updateById(userOrder);
try {
Thread.sleep(500);
return success(redisCache.deleteObject(orderList.list.getValue()));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
@DeleteMapping
public AjaxResult delete(Long[] id) {
userOrderService.removeByIds(Arrays.asList(id));
try {
Thread.sleep(500);
return success(redisCache.deleteObject(orderList.list.getValue()));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
补充enum类
public enum orderList {
list("list:order");
private String value;
orderList(String s) {
value = s;
}
public String getValue() {
return value;
}
}