性能设计-缓存
共 995字,需浏览 2分钟
·
2021-07-12 22:52
分布式系统或者微服务中最耗性能的地方,就是最后端的数据库。
一般来说,只要小心维护好数据库的四种操作中的三个写操作insert、update和delete,就不太会出现性能问题。
insert一般不会有性能问题,update和delete一般也会有主见,不会太慢。
除非是索引太多,数据库里的数据也太多,这三个操作才会变慢。
绝大多数情况下,select 是出现性能问题最大的地方。
一方面,select 会有很多像 join、group、order、like 等这样丰富的语义,而这些语义是非常耗性能的;
另一方面,大多数应用都是读多写少,所以加剧了慢查询的问题。
分布式系统中远程调用也会消耗很多资源,因为网络开销会导致整体的响应时间下降。
为了挽救这样的性能开销,在业务允许的情况(不需要太实时的数据)下,使用缓存是非常必要的事情。
但缓存技术如何选型,redis还是memcached还是自定义,则需要根据业务场景和具体的架构配套选择。
比如笔者最近参与的一个信贷上云项目,就没有用到redis,而是自己实现了一个简易的jvm本地缓存。
原因在于该银行的技术委员会要求,redis挂了的话,业务要完全不受影响,也就是所谓的退化方案。
开发组开发完本地缓存后,经过性能测试和压力测试,发现完全满足需求。
与其在redis挂了后退化到本地缓存,还不如直接使用本地缓存,因此,redis就被弃用了。
另外,金融系统一般首要考虑的是其正确性和安全性,其次才会考虑性能问题。
因此,这样的方案,看上去是合理的。
Cache Aside 更新模式
这是最常用的设计模式了,其具体逻辑如下。
失效:应用程序先从 Cache 取数据,如果没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从 Cache 中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效。
这是标准的设计模式,包括 Facebook 的论文《Scaling Memcache at Facebook》中也使用了这个策略。
为什么不是写完数据库后更新缓存?主要是怕两个并发的写操作导致脏数据。