HC0000

导航

redis缓存优化数据读取速度

缓存读取

原理,通过读取缓存增快数据读取速度,减轻数据库访问压力。
读取方面,首先通过读取缓存是否有数据,没有数据就去数据库里读取数据,并带会给缓存。
更新方面,只要增删改了数据,那么先更新数据库,再删除缓存

并且更新缓存时做个休眠,维持数据一致性。
防止出现如下图情况:
image
用户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;
    }
}

posted on 2025-08-15 15:26  HC0000  阅读(10)  评论(0)    收藏  举报