讨论一下 cache 的用法

2015-03-31 01:48:08 +08:00
 Lamian

举个实际的例子。为了减少对数据库的读操作,我们决定对部分数据加一层 cache。比如判断某 object是否为空,相应数量等等。

我的实现方式是每次数据库commit之后更新cache以防止脏数据,而且不用担心expiration的问题。如果不能hit cache, 我们就去查数据库,同时更新 cache。

我同事对此表示不同意,他的意见是 cache 本来就是性能和数据正确性之间的妥协。所以他觉得我的实现方式其实就是代替数据库,他更倾向设置一个很短的 expiration 时间,并且不去实现 after commit 的 hook,他觉得这样才是正确的使用 cache 的方法。

请问大家对 cache 的用法有什么看法?

2762 次点击
所在节点    数据库
36 条回复
Andiry
2015-03-31 02:32:28 +08:00
两种都可以。你同事的做法实现上简单一些,看实际需求了。
Lamian
2015-03-31 02:36:03 +08:00
我其实已经实现了,他想让我改。捂脸
monkeylyf
2015-03-31 02:38:12 +08:00
对加了cache后的db operation下降有什么预期吗 数据量是多少 你的做法就是把数据库装进 cache(memory) 如果不expire的话会吃掉多少内存?
你们的use case对数据本身是什么要求? 如果是因为cache inconsistent data会有什么影响?我司有些服务是要求data 一定要consistent 宁可牺牲performance 有些是轻微inconsistent也无所谓 需要分开讨论
Lamian
2015-03-31 02:47:00 +08:00
都是单个string,int,boolean这样的数据,基本不吃内存。因为是面对企业的数据,所以我实现的时候把 consistent放在了第一位。具体的预期很难估计,因为这个是老系统,又刚给 server装上 new relic,统计不全面,只能边改边看
Lamian
2015-03-31 02:47:37 +08:00
monkeylyf
2015-03-31 03:08:46 +08:00
@Lamian 那就是你和你同事对这个service的consistency的理解不同 去和他/她聊聊吧. 不考虑expiration 的问题(不expire真的大丈夫吗?如果数据量小 cache的意义不大 如果数据量大 不expire感觉要一把汗啊 最好去测一下真实数据)你的做法没啥问题
ncisoft
2015-03-31 03:50:57 +08:00
如果Cache不可信,加cache干啥,过期时间再短也是自欺欺人,你那同事想多了。只是要注意程序以外的地方直接修改数据库,或直接修改cache,这样会造成数据不一致,都跟过期设置无关。可从审计角度考虑问题
Lamian
2015-03-31 04:51:16 +08:00
@monkeylyf 其实有 expiration 的,12个小时 - -
firstway
2015-03-31 05:35:31 +08:00
实在忍不住要回复了。。。。。。。
“cache 本来就是性能和数据正确性之间的妥协”,这个是错误的,他似乎认为用到cache就一定会引起inconsistency,参见CPU和OS kernel里的cache。
什么叫“其实就是代替数据库”,难道我加了一层封装,下层数据库就没了??
cache本身只是概念,怎么做其实是实现层面的东西。

我支持楼主的做法,其实可以考虑这样的,就是 commit 之后,将原cache里对应KV清空,而不是update。这个取决你们场景里,新数据马上被访问的概率多大。

楼主同事要么是调书袋理解不到位,要么是为了反对而反对。
puncsky
2015-03-31 06:21:35 +08:00
KV Cache的本质是为了 Reduce latency for accessing active data,把常用数据的数据库的O(logn)的读写和复杂的查询变成O(1)的读写,cache的设计有很多pattern,常见的有 read-through/write-through(or write-back) 和 cache aside.

在分布式系统中,这些 pattern 的组合都是 consistency, availability, partition tolerance 之间的 trade-off,要根据你的业务需求具体选择。

## read-through/write-through(or write-back)

- Read-through: clients 和 databases 之间加一层 cache layer,clients 不直接访问数据库,clients 通过 cache 间接访问数据库。读的时候 cache 里面没有东西则从database更新再返回,有则直接返回。

- Write-through: clients 先写数据到 cache,cache 更新 database,只有 database 最终更新了,操作才算完成。

- Write-around: clients 写的时候绕过 cache 直接写数据库。

- Write-back: clients 先写数据到 cache,先返回。回头将 cache 异步更新到 database.

一般来讲 write-back 是最快的

## cache aside pattern

Cache 不支持 Read through / write through 的时候用 Cache aside pattern https://msdn.microsoft.com/en-us/library/dn589799.aspx
Lamian
2015-03-31 06:50:15 +08:00
@firstway 组里另外一个工程师也要我把 after commit 的东西去掉。我已经默默回去重构了,顺便准备简历面试什么的。不过这帖子的意义其实也是想看看大家对如何使用 cache 的看法什么的
Andiry
2015-03-31 07:01:33 +08:00
@Lamian 都已经做出来了还有重构的道理?先跑了再说,有问题再改。他们觉得应该按他们的做法,那就拿出实际东西来做对比。
Lamian
2015-03-31 07:12:28 +08:00
@Andiry Review 阶段,不给我过啊,只能回去改了。这都是小事,主要是看看大家对 cache 的看法什么的
puncsky
2015-03-31 07:30:49 +08:00
Facebook TAO 把 cache 用得出神入化,也值得一读。
tabris17
2015-03-31 09:36:07 +08:00
还是一句话,看你的应用场景,如果数据一致性要求高,则采用前者,否则使用后者。

抛开应用场景谈缓存策略都是耍流氓
GuangXiN
2015-03-31 10:03:42 +08:00
@firstway 二楼真相
xinyewdz
2015-03-31 10:07:22 +08:00
其实这两种做法合起来是最好的实现,长时间不访问的数据会expiration,减少内存占用。只cache热点数据。
firstway
2015-03-31 10:35:32 +08:00
@xinyewdz 作者其实有expiration,只是时间比较长,他们争论之处在于commit 的 hook是否需要,也就是一致性需不需要保证。
mahone3297
2015-03-31 10:38:07 +08:00
@Lamian 找你们老大,再review下看看?做个中间人?
其实lz的做法,会更保障数据的准确,一致性。不过可能会降低性能。
我觉得,也要看你们的业务场景。。。
Lamian
2015-03-31 10:50:38 +08:00
不要歪楼啊各位...只想借这个机会讨论一下各种那个cache的策略而已- -

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

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

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

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

© 2021 V2EX