认识缓存系统
缓存,是系统性能优化的一种有效手段,通过缓存系统,我们可以弥补某些性能难以提升的场景。 比如:
- 数据库查询复杂的语句,尽管有索引帮忙,却还是相当耗性能;
- 业务计算复杂,每次请求都耗费比较大的算力,响应较慢;
- 读多写少,读取频率远远大于写入。
这些都是典型的可以使用缓存系统来提升系统整体性能的场景。
缓存是什么
基于内存的读写速度远远大于磁盘的前提,缓存将可重复使用的数据放入内存中,避免每次都对存储系统进行访问,使用时从内存中读取。
下面是一个常用的架构模型。
当读取数据时:
程序首先从缓存中获取数据,如果拿到数据,则直接返回给调用方。
如果缓存数据不存在,那么从数据库读出数据,写入到缓存中,同时返回给调用方。
写入更新数据时:
这里涉及到缓存跟数据库的写入时机问题,
图中展示的是应用服务器先将数据写入数据库,然后将缓存设置为失效。
缓存带来的问题
缓存虽好,却给系统引入了复杂性。
缓存失效(雪崩)
什么是雪崩,简单来说,雪崩的瞬间就是当一个请求到来时,系统还没来得及响应回去,后面的请求紧接到来,当系统响应时,请求者已经认为失败而进行重试了,这是一个不断重复放大的过程,最终造成系统连锁反应而服务不可用。
缓存系统的雪崩,就是缓存失效的时候,业务需要重新生成缓存,假设同时要好几百个请求,他们相互之间并不知道对方正在生成缓存,而都去重新生成缓存,造成系统压力过载而形成连锁反应。
这个时候,我们要考虑好的事情就算怎么去维护缓存失效问题。
请求时主动刷新
比如我们正在为一些高频率的API请求做缓存,请求到来时访问缓存系统,如果没有命中缓存,那么自然要去重新生成数据,如果命中缓存,在返回给调用者后(或者之前),检验缓存剩余时间,假设已经到达我们设置的阈值,则主动刷新缓存,避免缓存被动失效。
后台刷新
缓存不由业务进程(线程)维护,而由一个独立的后台服务来维护,定时刷新缓存。
维护时注意缓存空间,如果缓存满了,需要采取策略剔除一些缓存。
锁机制
更新缓存时,采取锁机制,保证同一时间只有一个进程在更新缓存,其他进程等待缓存更新结果,或者提前返回默认值/空值.
注意点在于,现在大多数系统都不是单机单进程系统,使用分布式集群需要引入分布式锁,以保证不同机器之间不会同时生成缓存。
缓存穿透(未命中)
缓存穿透是指,查询的数据不存在,此时缓存也不会有对应的数据,从而造成请求每次都会对存储层进行查询,缓存起不到缓解存储层压力的效果。
另外一种情况也会造成缓存穿透,就是数据是存在的,然而计算耗费时间较久,当缓存失效时,所有流量都会直接进入到存储层查询,造成穿透效果。
当我们可以确定缓存对应的数据是不存在时,将该key对应的值设置为空,那么缓存可以防止查询对存储层造成压力。
缓存热点
缓存的性能很高,但如果突然出现的大量的热点集中式访问,会导致热点数据所在的缓存资源压力大。
这种时候可以考虑将缓存数据做成多份,分散请求到不同的缓存服务器上。
参考
分布式缓存架构基础
极客时间专栏「左耳听风」「从0开始学架构」
- 本文链接:https://keepmoving.ren/architecture/meeting-cache-system/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!