架构师训练营第二期 第 5 周总结
缓存的关键指标:缓存命中率
影响缓存命中率的主要指标:
1、缓存键集合大小。缓存键集合是应用能生成的所有键的数量。从统计学上看,应用生存的唯一键越多,重用的机会越小。一定要减少可能的缓存键数量,提高缓存的效率。
2、缓存可使用的内存空间。它直接决定了缓存对象的平均大小和缓存对象数量。物理上能缓存的对象越多,缓存命中率就越高。
3、缓存对象生存时间(TTL)。对象缓存的时间越长,缓存对象被重用的可能性就越高。但 TTL 需要根据实际业务场景来设置,为了避免数据的不一致性,它与数据变动频繁的程度负相关。
常见的缓存实现形式
1、代理缓存:代理服务器提供的缓存。如用户通过代理服务器上网,代理服务器中缓存了用户要访问的页面,可直接返回。未命中,再访问 web 服务器。
2、反向代理缓存: 和代理缓存类似。反向代理是部署在数据中心的服务器(提高请求处理效率,降低处理负载的压力),该缓存也是代理数据中心的请求内容。
3、多层反向代理缓存:
在请求资源的地方,通常上基于 HTTP、URL 协议的,都可以加一层反向代理,应用反向代理缓存优化。
以图中为例,请求访问前端 web 服务器前,先访问反向代理服务器(顺便做了负载均衡);请求到达前端 web 服务器,准备访问 webservice 前,也会访问反向代理服务器。目的也是利用缓存减少负载压力。
4、内容分发网络 CDN
用户可以直接请求数据中心,也可以通过 CDN 来请求数据中心。CDN 可能存储了 URL 请求的资源内容。
动态的 URL 请求的是数据中心的服务器。否则容易导致数据的不一致,出现脏数据的现象。
静态的 URL 请求的是 CDN 服务器的,访问 CDN 服务器。CDN 之前的总结提到过,是部署在运营商机房,离当前用户较近(物理上)的服务器。
5、CDN 同时处理动态与静态的请求
所有请求都用过 CDN,动态的请求通过 CDN 转发到对应的前端服务器上。
通读缓存(read-through):上述的缓存均是通读缓存。通读缓存指:如果有数据,则直接返回,如缓存中没有数据,则在缓存服务器上,继续向原始服务器发起请求去拉去数据。客户端只连接着缓存服务器,不连接着原始服务器。
与通读缓存有所区分的,是旁路缓存。
旁路缓存(cash-aside): 客户端连接着缓存服务器与原始服务器。客户端会先向缓存服务器请求,如没有数据,再请求原始服务器,同时,会把结果回写到缓存服务器,以供下次使用。
我们在应用程序中常用的对象缓存(通常是 key-value 形式),基本实旁路缓存。
举例:浏览器缓存,应用程序内部对象缓存,共享内存,本地缓存服务器。本地缓存服务器可部署集群。
自然,缓存服务器也可部署在独立的服务器上,形成集群(分布式对象缓存),如果资源不足,通过添加机器的方式解决。这种远程分布式缓存是我们互联网系统中主要使用的架构方案(如 redis)。
Memcached 的 shared-nothing 机制
memcached 的服务器之间(如图右侧集群中的三台服务器)不进行任何的通信,由客户端根据路由算法决定每次的读写,访问集群中的哪台服务器。集群添加删除机器,由客户端来感知与操作。
假定路由算法是根据 3 取模,原先三台服务器依次按照结果 0,1,2 来决定访问的服务器。此时,新加了一台缓存服务器,为了能让它纳入路由算法里,得变更为按 4 取模。那么已缓存的数据,在变更路由算法后,它的 KEY 值,按 4 取模所得的结果会与原来按 3 取模的结果不一致,会访问到错误的服务器,自然拿不到数据,最终走到了数据库。大量这样的请求会导致数据库压力骤然上升,甚至崩溃。
我们需要实现这样一个目标:添加,删除缓存服务器,不会影响已缓存在其他服务器上缓存的访问。在该背景下,需要引入一致性哈希算法的概念。
redis 原生集群
其中各节点彼此关联的目的之一:获悉与变更桶的分配(变更主要源于节点数量的变动)。
评论