系统设计 — 缓存

现在的软件系统设计中,基本上已经很难脱离缓存的去考虑问题,或者已经不能脱离缓存,在不同的层面有不同的缓存,我们现在使用的互联网的一些基础设施也都在使用缓存,那么就先看看缓存的优缺点吧。
优点:
1.提高系统的响应速度,就数据放在离用户最近的地方,让请求直接从缓存中获取数据,而不是每次都需要到服务器进行加载。
2.减少网络带宽压力,在存在大量并发请求的情况下,很多时候网络带宽会成为瓶颈,而从缓存中获取数据能够降低服务端的带宽压力
3.减少服务端的负载压力,一般服务的资源包含CPU,内存,连接数,磁盘等等(网络归属到外部资源中),这些资源是非常有限的,对于一些请求能够通过缓存很好的处理掉,那么就能腾出更多的资源去处理其他更重要的业务
4.在网络失效的情况下,亦能提供一个静态的服务
缓存和无状态约束
WEB的关键架构原则之一就是服务器和服务不应维护应用的状态。这个约束有助于分布式应用的容错和横向扩展。但是缺点也很明显,由于应用的状态不会持久保存在服务商,那么每次请求都需要和服务器交换应用的状态。这个就会增加消息的大小和带宽的消耗(在上章也提到了),缓存也就能很好的解决这个问题,将会话信息保留在离客户端最近的地方。

缺点或者不适用场景
1.对于数据统计需求或是内部对于一些请求存在计数功能,那么就不适合使用缓存,例如一个秒杀行动,服务端会对单位时间内进入的请求做一个判断是否是恶意请求,然后再做出处理,这个时候缓存就不应该出现
2.因为缓存会弱化分布式服务的一致性,那么对于一些强一致性的数据就不应该使用缓存
3.响应中包含了特定于用户的敏感的或是个人的数据,则不应该被放入缓存中
4.数据变化频繁,导致缓存的和重新验证响应的开销反而高于服务器简单的给每个请求一个响应。

缓存的类型:
大体上可以分为一下三类
本地缓存:就是在客户端的缓存,例如浏览器的缓存,或是内存或是磁盘中
代理缓存:这个可以存储很多不同数据源上的表述,这个主要是在企业的防火墙内部或是外部,ISP和任何一个虚拟网络组织都可以讲部分数据缓存在代理桑
反向缓存:反向代理一般放在应用服务器的前面,在这层可以做很多缓存,典型的有squid,varnish,apache traffic server等

一致性
前面也提到过,缓存会弱化数据的一致性,那么如何保证数据的一致性呢,一般的手段有以下三种
1.失效模式:就是缓存数据的源头,维护一个消费者列表,就是在数据发生变化的时候,通知缓存改更新数据了。但是如此做就违背了服务不应该维护应用状态的要求。
2.验证模式:每次请求缓存数据的时候,缓存服务器向数据源发起一个请求,这个请求只带一个版本标示,询问数据源的数据是否发生变化了,若是无变化,那么直接返回数据,如是发生变化,缓存服务器再次发起一个请求,获取最新数据,返回给客户端,如此就是每次请求都会发起一个验证消息,优点是:保证数据的一致性,但是会有一次小量的带宽消耗,有助于提高可伸缩性和性能,减少延迟。
3.到期模式:就是在缓存服务器上选择一个缓存到期时间,到指定时间后,就自动失效,再次从数据源拉取数据。这个模式的缺点就是无法保证缓存中的数据是最新的,但是对于服务器的负载和带宽要求是最低的。

针对以上三种模式,第一种基本可以完全否定,对于第二三种可以组合使用,对于敏感的数据,对于一致性要求较高的数据可以采用验证模式,对于数据的要求并不是很高的,可以采用验证模式。
以上三种都是针对缓存的读要求,那么对于写的要求,基本也是反向的验证模式+到期模式,对于缓存中的写数据,要么实时的更新到数据源,要么就是定时的将数据更新到数据源中。第二种在发生crash时候容易造成数据的丢失,第一种会有带宽上的消耗,及性能上也比不上第二种,但是能保证数据的一致性。这个在现实中的世界例子就是redis的写数据更新模式AOF和Rdb。

作者: inter12

在这苦短的人生中,追求点自己的简单快乐

发表评论

电子邮件地址不会被公开。 必填项已用*标注