关于是使用本进程缓存还是分布式缓存的一点疑惑

2018-06-11 17:40:49 +08:00
 ashin

刚才看 openresty 最佳实践的文档 在缓存这一节 https://moonbingbing.gitbooks.io/openresty-best-practices/ngx_lua/cache.html 说使用缓存时应该尽量使用本进程和本机的缓存解决。

网络开销变小和不用序列化操作这些可以理解,但是在分布式环境下也应该尽量使用本进程缓存吗,这个一致性很难去保证吧,而且一个服务十几个进程就得需要十几倍的内存感觉很浪费?我都是尽量使用分布式内存,在 redis 里面统一存一份。

2797 次点击
所在节点    程序员
8 条回复
jybox
2018-06-11 17:46:36 +08:00
并不是所有缓存都需要一致性呀,可以考虑放在进程内缓存的情况:不需要一致性、访问频率高、总数据集小、重建成本低(进程重启后缓存为空不会被压垮)。关于内存占用的话,其实还可以考虑在靠前的负载均衡上面做一致性散列。
Itoktsnhc
2018-06-11 18:00:17 +08:00
进程内缓存或本地缓存主要是为了高访问频率下的快速响应,分布式内存也是要走网络的,这个开销还是蛮大的。
如果觉得内存占用比较浪费,可以对本地缓存设置较短的过期时间,降低本地缓存导致的内存使用。
如果对一致性还是有些要求的 可以考虑使用消息队列的方式,订阅更新缓存的信息。
troycheng
2018-06-11 18:07:40 +08:00
主要看应用场景,比如数据不经常变动,但访问频次高,应用又耗时敏感,使用本地缓存就会好一些
sampeng
2018-06-11 21:33:06 +08:00
举例:v2 的帖子是不允许编辑的。。内容就完全可以在进程缓存。而不需要 redis
fengchang
2018-06-11 23:31:14 +08:00
我以前在设计缓存的时候踩过不少坑,使用本地缓存时要考虑的点很多:

1. 分布式服务如果缓存量比较大的话,要在 client side 做路由策略
2. 有路由策略就需要考虑重启服务期间和扩容缩容时路由变化请求打到其他机器上产生无法被覆盖的脏数据
3. 同理,数据被更新时,清理分布在本地缓存中的数据比较麻烦
4. 重启服务本地缓存会被清空,需要考虑预热
5. 使用 Java 时,大量数据的 GC 很麻烦
6. 为了避免 GC 使用 off-heap memory 的话,你会发现反序列化的时间比想象的占比要高很多

我的总结是,如果你在用 Java,不要对本地缓存解决性能问题报太大期望。
Raymon111111
2018-06-11 23:48:14 +08:00
本地缓存主要是考虑, 延迟低 /频次高.

如果可以用分布式搞定的, 就尽量用分布式.

本地缓存很明显在维护一致性上要花比较大的功夫, 确实是没办法才使用.

这里简单考虑:
1. 新增 /修改 /删除怎么同步所有机器(不同机器生效还可能有业务可感知的先后)
2. 机器重启怎么全量拉取最新的一份缓存(和 1 还可能有并发冲突)
ashin
2018-06-12 10:41:06 +08:00
@fengchang 有没有详细的文章分享你这里的设计方案和踩过的坑啊
fengchang
2018-06-12 11:51:51 +08:00
@ashin 缓存设计和数据的特点有关,和业务关系太紧,写的东西都只能放在内网了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/462225

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX