我们有一个幻想足球应用程序,它使用memcached和经典的memcached-object-read-with-sql-server-fallback。这很好用,但最近我一直在考虑所涉及的开销以及这是否是最好的方法。
例证 - 我们需要生成用户团队的下拉列表,因此我们遵循以下模式:
这一切都非常好 - 每个缓存的数据都相对容易缓存和失效,但这有两个主要缺点:
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 ..我的问题是 - 你们中是否有人有解决上述缺点的想法,或者我应该接受是否存在开销,而且缓存未命中是不好的,与它一起生活?
答案 0 :(得分:0)
首先,缓存您需要的内容,可能是两个字段,而不是完整记录。
其次,再次缓存你需要的东西,将结果集分成记录并单独缓存它们
答案 1 :(得分:0)
您通常使用缓存卸载较慢的基于磁盘的存储,在本例中为mysql。内存缓存相当容易扩展,mysql扩展不太容易。
鉴于此,即使您将缓存的cpu / netowork / memory使用量加倍并将其全部放在一起,它仍将卸载数据库。添加另一个nodejs实例或另一个memcached服务器很容易。
你说它是一个用户的团队,你可以在用户登录时去取它,并在用户在整个会话期间更改它时将其更新到缓存中。
我认为团队成员的名字不会改变,如果是这样,你可以通过id加载所有团队成员,名称并将其存储在缓存中,甚至存储在nodejs上,使用与现在相同的后备策略。只剩下第1步,第2步和第4步。
通常你会在mysql的返回行上运行一些逻辑,无需继续重复。