使用缓存的正确姿势

1.缓存是现在系统中必不可少的模块,并且已经成为了高并发高性能架构的一个关键组件。这篇博客我们来分析一下使用缓存的正确姿势。

缓存能解决的问题

  • 提升性能

    绝大多数情况下,select 是出现性能问题最大的地方。一方面,select 会有很多像 join、group、order、like 等这样丰富的语义,而这些语义是非常耗性能的;另一方面,大多数应用都是读多写少,所以加剧了慢查询的问题。

    分布式系统中远程调用也会耗很多性能,因为有网络开销,会导致整体的响应时间下降。为了挽救这样的性能开销,在业务允许的情况(不需要太实时的数据)下,使用缓存是非常必要的事情。

  • 缓解数据库压力

    当用户请求增多时,数据库的压力将大大增加,通过缓存能够大大降低数据库的压力。​

缓存的适用场景

  • 对于数据实时性要求不高

    对于一些经常访问但是很少改变的数据,读明显多于写,适用缓存就很有必要。比如一些网站配置项。

  • 对于性能要求高

    比如一些秒杀活动场景

更新模式

这是最常用的缓存模式了,具体的流程是:

  • 失效:应用程序先从 cache 取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
  • 命中:应用程序从 cache 中取数据,取到后返回。
  • 更新:先把数据存到数据库中,成功后,再让缓存失效。

这里当更新缓存的时候,可能会有一些坑,需要避免。

1.先更新数据库,再更新缓存。(注意是更新缓存,而不是删除缓存)。这种做法最大的问题就是两个并发的写操作导致脏数据。

  两个并发更新操作,数据库先更新的反而后更新缓存,数据库后更新的反而先更新缓存。这样就会造成数据库和缓存中的数据不一致,应用程序中读取的都是脏数据。

2.先删除缓存,再更新数据库。这个逻辑是错误的。因为两个并发的读和写操作导致脏数据。

  假设更新操作先删除了缓存,此时正好有一个并发的读操作,没有命中缓存后从数据库中取出老数据并且更新回缓存,这个时候更新操作也完成了数据库更新。此时,数据库和缓存中的数据不一致,应用程序中读取的都是原来的数据(脏数据)

理论上最合适,也最推荐的方式就是,先更新数据库,然后删除缓存,注意是删除缓存

 

缓存是通过牺牲强一致性来提高性能的。所以使用缓存提升性能,就是会有数据更新的延迟。这需要我们在设计时结合业务仔细思考是否适合用缓存。然后缓存一定要设置过期时间,这个时间太短太长都不好,太短的话请求可能会比较多的落到数据库上,这也意味着失去了缓存的优势。太长的话缓存中的脏数据会使系统长时间处于一个延迟的状态,而且系统中长时间没有人访问的数据一直存在内存中不过期,浪费内存。

 

 

 

posted @ 2018-05-17 11:04  tianye_guazi  阅读(160)  评论(0编辑  收藏  举报