分类目录归档:乱想阿陈

乱想阿陈 —— 缓存那些事

“乱想阿陈”系列文章是我未经实践的胡乱意淫。不保证正确,不保证有用。
仅作为自己平时思考一些东西后的记录、抑或是一些突发奇想地东西。


缓存是一个很好的东西,它可以轻易地帮我们抗住以读为主的大流量高并发。

那如何用好缓存?如何设计缓存呢?

1、缓存机制

1.1、 主动更新

当源数据发生变化之后主动来更新缓存。

适合场景:实时性要求高
优点:数据事实
缺点:复杂,难以治理

1.2、 被动更新

一般指的是例如redis设置过去时间的缓存。当缓存过期后,重新访问数据库获取数据然后进行缓存。

适合场景:不经常修改的数据
优点:简单,依赖缓存产品(redis等)的自身过期机制。
缺点:当cache失效的瞬间,正好遇上高并发的话,就可能会发生雪崩情况。

不过这个缺点可以通过巧妙地设计来弥补,但是程序也少许增加了复杂度。当然封装好了,程序员可以无感知的调用。

1.3、 缓存主动RELOAD

缓存永远不过期或者有效期很长,然后后台启动一个程序后者服务,定时生成缓存。

适合场景:并发量大,允许一定延迟。如:首页、频道页等热门访问页面
优点:相对简单
缺点:不是很实时,但是有自己相应的应用场景。

1.4、 缓存被动RELOAD

缓存永远不过期或者有效期很长,依靠访问来刷新缓存。

当访问页面时,通过主流程获取数据并返回。同时异步(队列、线程等)去检测缓存是否过期,如果过期重新reload

适合场景:并发量一般,访问速度要求快,允许一定延迟。
优点:对于冷数据,无人访问的数据,不浪费资源去处理它。
缺点:容易在多次访问的时候,多次异步去reload缓存。

2、 事件驱动

在上面4种缓存机制中,我觉得1.21.31.4并没有什么难度。
1.1主动更新缓存才是重中之重,我们应该如何去设计它呢?

我暂时想到的比较好的方法,就是事件驱动

比如,订单状态的刷新。我们可以在订单状态改动的程序附件触发一个OrderUpdateEvent的事件,然后写一个ReloadOrderCacheListener的监听器挂载在上面。

这样做既解耦了业务流程代码和缓存代码,又可以实现缓存代码的重用。

但是,当事件变得越来越多,不仅有缓存的事件,也有业务逻辑的事件,久而久之也会发现难以管理。

那么我们应该如何去管理这些事件?

3、 服务化

我们可以将所以缓存相关的事件集中起来,做成一个服务。

它独立于其他系统服务,并且提供出相应的事件监听器,相关服务可以在启动时向缓存服务发送请求注册自己关注事件以及关联的监听器

业务中监听事件

服务化的好处,我们可以起一个有一个的服务,将代码彻底的解耦。然后无线水平扩展(当然是理论上的- -)。