一个大型稳健成熟的分布式系统的背后,往往会设计众多的支撑组件,将这些支撑系统成为分布式系统的基础设施。进行系统架构设计所依赖的基础设施,还包括分布式协作及配置管理组件、分布式缓存组件、持久化存储组件、分布式消息系统、搜索引擎、以及CDN系统、负载均衡系统、运维自动化系统等,还有实时计算系统、离线计算系统、分布式文件系统、日志收集系统、监控系统、数据仓库等。此处主要讲讲缓存系统组件。
缓存组件层
缓存系统带来的好处:
- 加速读写。缓存通常是全内存的,比如Redis、Memcache。对内存的直接读写会比传统的存储层如MySQL,性能好很多。由于单台机器的内存资源和承载能力有限,并且如果大量使用本地缓存,也会使相同的数据被不同的节点存储多份,对内存资源造成较大的浪费,因此才催生出了分布式缓存。
- 降低后端的负载。在高并发环境下,大量的读、写请求涌向数据库,磁盘的处理速度与内存显然不在一个量级,从减轻数据库的压力和提供系统响应速度两个角度来考虑,一般都会在数据库之前加一层缓存。
缓存系统带来的成本:
- 数据不一致性:在分布式环境下,数据的读写都是并发的,上游有多个应用,通过一个服务的多个部署(为了保证可用性,一定是部署多份的),对同一个数据进行读写,在数据库层面并发的读写并不能保证完成顺序,也就是说后发出的读请求很可能先完成(读出脏数据)
- 代码维护成本:加入缓存后,需要同时处理缓存层和存储层的逻辑,增加了开发者维护代码的成本。
- 运维成本:引入缓存层,比如Redis。为保证高可用,需要做主从,高并发需要做集群。
缓存的更新
缓存的数据一般都是有生命时间的,过了一段时间之后就会失效,再次访问时需要重新加载。缓存的失效是为了保证与数据源真实的数据保证一致性和缓存空间的有效利用性。常见的缓存更新策略:
- LRU/LFU/FIFO等算法:三种算法都是属于当缓存不够用时采用的更新算法。只是选出的淘汰元素的规则不一样:LRU淘汰最久没有被访问过的,LFU淘汰访问次数最少的,FIFO先进先出。适合内存空间有限,数据长期不变动,基本不存在数据一不致性业务。比如一些一经确定就不允许变更的信息。要清理哪些数据是由具体的算法定的,开发人员只能选择其中的一种,一致性比较差。
- 超时剔除:给缓存数据手动设置一个过期时间,比如Redis expire命令。当超过时间后,再次访问时从数据源