需要缓存策略建议

时间:2012-06-14 14:23:17

标签: caching memcached

我们有一个幻想足球应用程序,它使用memcached和经典的memcached-object-read-with-sql-server-fallback。这很好用,但最近我一直在考虑所涉及的开销以及这是否是最好的方法。

例证 - 我们需要生成用户团队的下拉列表,因此我们遵循以下模式:

  1. 从memcached
  2. 获取用户团队列表
  3. 如果不可用,请从SQL服务器获取列表并存储在memcached中。
  4. 执行多项目以获取团队对象。
  5. 回退到从sql store加载对象。
  6. 这一切都非常好 - 每个缓存的数据都相对容易缓存和失效,但这有两个主要缺点:

    1)因为我们在对象上操作会产生相当大的开销 - 一个团队在memcached中占用了大约一百个字节,而我们真正需要的是团队名称和ID的列表 - 而不是所有其他的团队中的东西。

    2)由于加载单个对象的后退,在空缓存上或项目到期时生成的SQL查询数量可能很大:    1 x Memcached multiget(错过了,导致了什么)    1 x SELECT ... FROM Team WHERE Id IN(...)    20 x存储在memcached中 因此,仅针对此一个查询的21个网络请求,以及IN查询比特定连接慢。

    显然我们可以做一个简单的

    SELECT Id, Name FROM Teams WHERE UserId = XYZ
    

    并缓存该结果,但这意味着每当用户创建新团队时,此数据都需要专门无效。在这种情况下,它可能看起来相对简单,但我们有很多这类查询,其中许多都在不容易失效的轴上运行(比如朋友在特定的团队中创建的团队的ID和名称列表)游戏)。

    Sooo ..我的问题是 - 你们中是否有人有解决上述缺点的想法,或者我应该接受是否存在开销,而且缓存未命中是不好的,与它一起生活?

2 个答案:

答案 0 :(得分:0)

首先,缓存您需要的内容,可能是两个字段,而不是完整记录。

其次,再次缓存你需要的东西,将结果集分成记录并单独缓存它们

答案 1 :(得分:0)

关于缓存:

您通常使用缓存卸载较慢的基于磁盘的存储,在本例中为mysql。内存缓存相当容易扩展,mysql扩展不太容易。

鉴于此,即使您将缓存的cpu / netowork / memory使用量加倍并将其全部放在一起,它仍将卸载数据库。添加另一个nodejs实例或另一个memcached服务器很容易。

回到你的问题

  1. 你说它是一个用户的团队,你可以在用户登录时去取它,并在用户在整个会话期间更改它时将其更新到缓存中。

  2. 我认为团队成员的名字不会改变,如果是这样,你可以通过id加载所有团队成员,名称并将其存储在缓存中,甚至存储在nodejs上,使用与现在相同的后备策略。只剩下第1步,第2步和第4步。

  3. 个人我经常尝试将sql结果拆分成较小的现成件并缓存它们,并尽可能长时间地保持缓存更新,非常密切地尝试仅使用mysql作为存储而永远不会从中读取

    通常你会在mysql的返回行上运行一些逻辑,无需继续重复。