中央缓存结合本地缓存:本地缓存数据刷新方案

互联网应用通常都需要应付大并发量,为了提高QPS,通常会使用中央缓存(例如memcache)和本地缓存的方式。请求先经过本地缓存,如果不命中,则请求穿透到中央缓存,如果还是不命中,则会直接查询数据库,并把查询到的数据刷新到中央缓存中。如果采用这种方式的话,必须要解决一个问题,如何刷新本地缓存的数据。

每个应用中都提供一个刷新接口


之前参与过的一个项目,应用的部署图大概如下:
这里写图片描述

当时的解决方案如下:
服务器a、b和c中的应用application-a基于oscache构建了本地缓存,为了能刷新服务器中这些应用中的oscache,可以在application-a这个应用中提供一个刷新oscache的http接口,叫refresh(),每次服务器d 中的后台应用修改了数据后,先刷新中央缓存,然后直接获取服务器a、b、c的ip地址,然后for循环,挨个的调用refresh()接口。

这种做法有很多缺点:
1. 必须维护application-a应用的所有ip地址,如果新增了一个机器部署了application-a,则必须在后台管理系统中对应的新增一个ip地址,以便数据更新后,可以通知到新应用中的oscache缓存数据;
2. 使用for循环,是串行的通知,没有做到并行的通知,如果服务器多的话,有一定的延迟;
3. 假设更新其中一台服务器的缓存数据失败了,没有重试机制。

订阅机制


另一种做法是,是MQ的订阅机制,生产者把消息写到一个队列中,然后通知订阅该队列的所有消费者。

设置本地缓存数据的失效时间


设置本地缓存数据的失效时间,例如10分钟,时间一到,则数据自动失效,让请求穿透过去,应用再次将新数据加载到本地缓存中,再次设置10分钟的失效时间。

这种做法非常的简单简洁,但是注意考虑业务场景。

使用时间戳版本号


当请求过来的时候,根据key先从中央缓存中获取对应这个key的一个时间戳,然后再根据这个key去本地缓存中获取时间戳,比较两个时间戳,如果本地缓存未失效,则从本地缓存获取。

这种做法也有个缺点,就是无论如何都必须先去中央缓存读取一次。多了一次开销,不过时间戳的大小也非常小,影响不是很大。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

1 1 收藏 评论

关于作者:Sam哥哥

互联网技术爱好者,目前就职于广州唯品会担任JAVA高级开发。个人的csdn技术博客如下:http://blog.csdn.net/linsongbin1本人伯乐在线的文章,都出自这个csdn博客 个人主页 · 我的文章 · 15

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部