我一直在研究缓存(主要是 redis 和 memcached),并且很难弄清楚当您的数据不断变化时在哪里使用缓存。
以 Twitter 为例(请阅读让 Twitter 速度提高 10000%)。当大部分数据库记录不断变化时,您(或他们)将如何缓存他们的数据?
假设 Twitter 有这些模型:User
, Tweet
, Follow
, Favorite
.
有人可能会发布一条一天被转发一次的推文,而另一条一天被转发一千次的推文。对于那 1000 次转推,由于24 * 60 == 1440
一天中大约有几分钟,这意味着推文几乎每分钟都会更新(比如说它也有 440 个收藏夹)。跟关注一个人一样,charlie sheen 甚至在 1 天内就吸引了 100 万 Twitter 关注者。在这些情况下缓存似乎不值得,但可能只是因为我还没有达到那个水平。
还要说,平均 Twitter 追随者每天至少发一次推文/关注/收藏。这意味着在幼稚的 intro-rails 模式案例中,用户表每天至少更新一次(tweet_count
等)。这种情况对于缓存用户配置文件很有意义。
但是对于上面的 1000x 推文和 100 万关注者的例子,在缓存数据方面有哪些推荐的做法?
具体来说(假设 memcached 或 redis,并使用纯 JSON API(无页面/片段缓存)):
- 您是否缓存单个推文/记录?
- 或者你是否通过分页缓存记录块(例如
20
每个的redis列表)? - 或者您是否将记录单独缓存在页面中(查看单个推文与 JSON 提要)?
- 或者你是否为每个不同的场景缓存推文列表:家庭时间线推文、用户推文、用户最喜欢的推文等?还是以上所有?
- 或者您是否将数据分解为“最易变(最新)”到“最近几天”到“旧”块,其中“旧”数据以更长的到期日期或离散的分页列表或其他方式缓存?而且最新的记录根本没有被缓存。(即,如果数据像推文一样是时间相关的,如果您的旧记录知道它不会有太大变化,您是否会以不同的方式对待它?)
我不明白的是数据更改的比例与是否应该缓存它(并处理缓存到期的复杂性)的比率。似乎 Twitter 可能正在缓存不同的用户推文提要和每个用户的主页推文,但是每次收藏/推文/转发时使缓存无效意味着更新所有这些缓存项(以及可能缓存的记录列表),在某些时候,这似乎意味着使缓存无效会适得其反。
对于像这样变化很大的数据缓存的推荐策略是什么?