我们有一个 Fantasy Football 应用程序,它使用 memcached 和经典的 memcached-object-read-with-sql-server-fallback。这种方法效果相当好,但最近我一直在考虑所涉及的开销以及这是否是最好的方法。
举个例子 - 我们需要生成用户团队的下拉列表,因此我们遵循以下模式:
- 从 memcached 获取用户团队列表
- 如果不可用,请从 SQL Server 获取列表并将其存储在 memcached 中。
- 执行多重获取来获取团队对象。
- 后退到从 SQL 存储中加载对象。
这一切都很好 - 每个缓存的数据都相对容易缓存和失效,但这样做有两个主要缺点:
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
并缓存该结果,但这意味着每当用户创建新团队时,都需要专门使该数据失效。在这种情况下,它可能看起来相对简单,但是我们有许多此类查询,并且其中许多在不容易失效的轴上操作(例如您的 friend 在特定的环境中创建的团队的 id 和名称列表)游戏)。
所以..我的问题是 - 你们中有人有解决上述缺点的想法吗?还是我应该接受存在开销并且缓存未命中很糟糕,接受它?
最佳答案
首先,缓存您需要的内容,可能是两个字段,而不是完整的记录。
第二,再次缓存需要的内容,将结果集拆成记录,单独缓存
关于需要缓存策略建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11035172/