1.缓存的基本原理
缓存是指将数据存放到相对比较高速访问的存储介质中,比如内存,方便系统处理。一方面缓存的访问速度快,还可以把计算好的数据写入缓存中,大大减少了系统对数据计算的时间,以及频繁的操作数据库。
缓存的本质是一个内存的hash表,网站的应用中,数据缓存以一对key, value的形式存储在内存hash表中。
缓存主要存储那些‘读’比较高,很少变化的数据,如商品目录,商品中涉及的属性,以及相关的一系列结构数据,当程序读取数据时,先到缓存读取数据,读取不到时再去数据库读取数据,再写入缓存中,后续客户请求同一个商品的时候可以直接在缓存中得到,而不用再继续操作数据库,但是要注意的时,缓存中的数据并非可靠的,不可过度依赖缓存,需要注意当发现商品结构数据有变动的时候需要及时更新缓存中变动的商品。
2.合理使用缓存
使用缓存的确可以提高很多性能上的好处,但是不合理的使用缓存非但不能提高系统性能,还会成为系统累赘,甚至风险。在有些实际应用中,需要滥用缓存,过渡依赖缓存的系统,导致系统结构混乱,最终导致瘫痪,数据丢失等。
如果缓存中保存的时频繁修改的数据,就会出现数据写入缓存后,应用还来不及访问缓存中的数据,数据已经被更新,导致数据失效,徒增系统负担。正常来说,数据写入后放入缓存中的数据在被下一次更新前被读取2次及以上才是才有意义。比如读写比较高的微博,当发布后写入缓存中,可能被读取百万千万次。
没有热点的访问,缓存使用内存作为存储,付出的代价是及其昂贵的,如果缓存的数据被有被访问,或者极少数的访问,那么这种数据不应该放入缓存中,在遵循互联网的二八定律,百分之八十的访问在百分之二十的数据上,那么这百分之二十的数据就应该放入缓存中。
数据不一致与脏读,一般会对缓存设置一个失效时间,一旦超过失效时间,就应该从数据库中重新加载,因此应用要容忍一定时间的数据不一致,如修改了一个商品的数据,如果没有采用及时写入缓存的策略,那么就需要等带缓存中改商品数据到失效时间之后才会更新到缓存中,在互联网应用中,这种延迟是可以接受的,如果要解决这种延迟,需要对数据修改后立即修改缓存中的数据,但是这样需要谨慎,需要考虑到事物中数据的一致性。
缓存可用性,缓存数据的丢失,并不会影响系统的可用性,但是要考虑,当系统过分依赖缓存后,当缓存系统崩溃,或者数据丢失后,在面对高并发请求后对数据库带来的压力,数据库可能会因为承受不住如此打的压力导致宕机,今儿导致整个系统的不可用。这种情况被称作为缓存雪崩,发生这种故障甚至不能简单重启缓存服务器和数据库服务器来恢复系统的正常运行。实践中,有的系统通过缓存热备份等手段来提供缓存的可用性:当某台缓存服务器宕机了,立即将缓存访问的热点切换到热备份服务器上。但是这种设计显然违背缓存的初衷,缓存根本就不应该当作一个可靠的数据源来使用。通过分布式缓存服务器集群来解决,将缓存数据分摊到不同的缓存服务器中,当某一台缓存服务器宕机,只会丢失部分数据,从新从数据库加载这部分数据并不会对数据库造成影响。 所谓的设计,架构,是一个软件系统,项目,产品最高层次的规划,难以改变的决定,这些规划决定了事物未来的法藏方向和最终的蓝图。所以产品设计之初就需要一个明确的定位。
缓存预热,缓存中存放的是热点数据,当系统最初启动的时候,如果这些热点数据并没有在缓存中,可能最初系统的性能和数据库的负载读不太好,最好在系统启动之初就把热点数据加载好,这个缓存预加载手段叫做缓存预热,对于一些商品,城市地名,运营商,可以最初就加载到缓存进行预热。
缓存穿透,如果因为不恰当的业务,或者恶意的攻击,瞬间高并发的读取一个缓存与数据库都不存在的数据,会对数据库造成极大的压力,导致崩溃,为了预防这种手段,可以在读取缓存的时候读取不到,在读取数据库的时候也读取不到的时候,通过简单的对策把数据key对应的值设为Null。