架构第 5 周总结

用户头像
Geek_Gu
关注
发布于: 2020 年 10 月 25 日

缓存可以有多层,比如负载均衡层,应用层和数据库层之间,应用层都可以应用缓存。

在架构中将请求尽量挡在上层,因为越往下层,对于并发的承受能力越差;缓存命中率是最重要的一个监控项,越是热点的数据,缓存的命中率就越高。

缓存不仅仅是一种组件的名字,更是一种设计思想,可以认为任何能够加速读请求的组件和设计方案都是缓存思想的体现。通常是两种方式来实现:使用更快的介质;缓存复杂运算的结果。



缓存的主要作用是提升访问速度,从而能够抗住更高的并发。缓存比较适合于读多写少的业务场景,并且数据最好带有一定的热点属性。这是因为缓存毕竟会受限于存储介质不可能缓存所有数据,那么当数据有热点属性的时候才能保证一定的缓存命中率。比如说类似微博、朋友圈这种 20% 的内容会占到 80% 的流量。所以,一旦当业务场景读少写多时或者没有明显热点时,比如在搜索的场景下,每个人搜索的词都会不同,没有明显的热点,那么这时缓存的作用就不明显了。其次,缓存会给整体系统带来复杂度,并且会有数据不一致的风险。当更新数据库成功,更新缓存失败的场景下,缓存中就会存在脏数据。对于这种场景,可以考虑使用较短的过期时间或者手动清理的方式来解决。再次,之前提到缓存通常使用内存作为存储介质,但是内存并不是无限的。因此在使用缓存的时候要做数据存储量级的评估,对于可预见的需要消耗极大存储成本的数据,要慎用缓存方案。同时,缓存一定要设置过期时间,这样可以保证缓存中的会是热点数据。最后,缓存会给运维也带来一定的成本,运维需要对缓存组件有一定的了解,在排查问题的时候也多了一个组件需要考虑在内。

缓存的读写策略

旁路缓存策略

读穿/写穿策略

写回策略

缓存高可用

客户端方案就是在客户端配置多个缓存的节点,通过缓存写入和读取算法策略来实现分布式,从而提高缓存的可用性。

中间代理层方案是在应用代码和缓存节点之间增加代理层,客户端所有的写入和读取的请求都通过代理层,而代理层中会内置高可用策略,帮助提升缓存系统的高可用。

服务端方案有Redis 在 2.4 版本中提出了 Redis Sentinel 模式来解决主从 Redis 部署时的高可用问题,它可以在主节点挂了以后自动将从节点提升为主节点,保证整体集群的可用性。

缓存穿透

缓存穿透其实是指从缓存中没有查到数据,而不得不从后端系统(比如数据库)中查询。

少量的缓存穿透不可避免,对系统是没有损害的。

大量穿透解决方案:

回种空值

数据库中并不存在用户的数据,这就造成无论查询多少次数据库中永远都不会存在这个用户的数据,穿透永远都会发生,当从数据库中查询到空值或者发生异常时,可以向缓存中回种一个空值。但是因为空值并不是准确的业务数据,并且会占用缓存的空间,所以给这个空值加一个比较短的过期时间,让空值在短时间之内能够快速过期淘汰。

布隆过滤器

以存储用户信息的表为例进行讲解。首先初始化一个很大的数组,比方说长度为 20 亿的数组,接下来选择一个 Hash 算法,然后将目前现有的所有用户的 ID 计算出 Hash 值并且映射到这个大数组中,映射位置的值设置为 1,其它值设置为 0。新注册的用户除了需要写入到数据库中之外,它也需要依照同样的算法更新布隆过滤器的数组中相应位置的值。那么当需要查询某一个用户的信息时,先查询这个 ID 在布隆过滤器中是否存在,如果不存在就直接返回空值,而不需要继续查询数据库和缓存,这样就可以极大地减少异常查询带来的缓存穿透。



用户头像

Geek_Gu

关注

还未添加个人签名 2019.09.09 加入

还未添加个人简介

评论

发布
暂无评论
架构第5周总结