java中如何实现本地缓存?( 二 )

本地缓存常见问题
1. 缓存一致性 。二级缓存和数据库中的数据必须一致 。一旦数据被修改 , 本地缓存和远程缓存应在数据库修改的同时同步更新 。
解决方案1:使用MQ 。
目前的部署一般都是集群部署,不同节点有多个本地缓存 。可以利用MQ的广播模式,在数据修改时向MQ发送消息 , 由节点监听并消费该消息,删除本地缓存,达到最终一致性 。
 
解决方案二:Canal+MQ 。
如果你的业务代码中不想发送MQ消息,也可以应用近年来比较流行的方法:订阅数据库变更日志,然后操作缓存 。Canal订阅Mysql的Binlog日志,当发生变化时向MQ发送消息 , 从而也实现了数据的一致性 。
2.如何提高缓存命中率?

  • 根据业务场景设计合理的时效性 。
缓存适用于读多写少的场景,尽可能关注访问频率高、时效性要求不高的热点业务 。访问频率越高,点击率越高 。时效性越低,缓存时间越长,相同key、相同请求数下命中率越高 。
  • 设计合理的缓存粒度 。
缓存的粒度越小,缓存命中率越高 。单个key缓存的数据单元越小 , 被改变的可能性就越小 。
  • 设计合理的缓存过期策略 。
这里的缓存过期策略并不是redis内置的定期删除和惰性删除策略,而是根据业务场景优化了key的过期时间 。例如,如果用户的关键信息同时过期 , 那么当多个用户同时查询时,都会落入数据库,也就是说避免缓存同时失效 。
  • 合理的缓存预加载 。
redis缓存必须从数据库加载 , 所以当第一次使用数据时,redis需要从数据库加载数据 。我们可以在用户访问之前将需要的数据提前加载到缓存中 , 这样用户第一次访问时就可以直接去缓存而不用去查询数据库 。
  • 防止缓存崩溃和击穿 。
缓存击穿和崩溃也会影响缓存命中率 。当然,如果发生的话 , 应用失败的可能性很大 。
  • 设计合理的缓存容量 。
注意缓存容量,如果太小 , 会触发redis内存淘汰机制 。线上redis一般配置maxmemory-policy allkeys-lru算法进行内存消除 。
这样就会删除一些key,造成缓存穿透,从而降低缓存命中率,所以需要合理配置缓存容量 。

【java中如何实现本地缓存?】


推荐阅读