我在 ASP.NET 上问过这个问题...
http://forums.asp.net/t/1584731.aspx
...但也想在这里问。我确信这个问题之前已经解决了,所以我想为什么要重新发明轮子……
简短的故事,我正在使用 memcached 作为数据库的缓存层构建一个具有社交功能的 Web 应用程序。为了简化问题,让我们假设一个基本设置,我们有一个persons 表和一个friendConnection 表,其中persons 包含个人信息,friendConnection 有两个外键将一个人链接到另一个人,如果他们互相加为好友(我实际上不是使用表或 SQL,但问题类似)
我的缓存过期逻辑很简单:每当发生对表的放置时,都会使缓存中当前存在的与该表相关的所有选择语句过期。然而,这种逻辑在性能方面很糟糕,因为人们不断地相互交友,缓存永远不会持续超过几秒钟。
例如,更复杂的逻辑可能会使包含当前引用的 friend 的所有选择语句过期,但这将需要获取与friendConnection 表相关的所有选择语句并检查它们的相关性,这也将成为性能负担。
首先,我的问题有意义吗?
其次,人们通常如何解决这个问题?
最佳答案
不要将 memcached 条目与表关联,将条目与实体(即行)关联。
例如,为每个成员创建一个 memcached 条目,该条目存储该成员的 friend 列表。
这是一个使用 PHP 的示例。我知道您使用的是 ASP.NET,所以将其视为伪代码。 :-)
<?php
$m = new Memcached();
$m->append('Luke.Doolittle', '|Bill Karwin');
$m->append('Bill Karwin', '|Luke.Doolittle');
回复您的评论:
The problem that I see is that there is no generalized pattern for placing objects in memcached then.
对。在关系数据库中,有一种用于建模数据的正式模式。 Normalization是一种定义明确的数据建模方法,可减少冗余并防止异常。最优归一化组织是由数据本身决定,以及数据之间的关系。
在非关系数据库中,没有数据建模的形式化。组织非关系数据的最佳方式不是由数据决定的,它是由您的查询确定 您需要针对该数据运行。这样,它类似于定义索引或对关系数据库应用非规范化的过程。
The logic would be different for each type of object. Does that make sense?
实际上,您需要针对该对象运行的每种查询类型的逻辑都会有所不同。这就是导致我们在非关系数据存储中冗余存储数据的原因。因为我们可能希望对相同的数据运行各种查询,这意味着我们需要以不同的方式访问数据以针对每种查询类型进行优化。
How do you perform removes using this technique?
从 memcached 中获取整个字符串,将值分解为一个数组,删除要删除的元素,分解新数组,然后将其存储回 memcached。
我上面的例子很简单;它也不强制执行唯一性。
您可能有兴趣查看 Redis ,它像 memcached 一样工作,但也支持本地列表和集合。
我会使用 SQL 来存储数据,使用规范化规则。根据具体情况使用非关系方法来提高特定高优先级查询的性能——在你使用分析来衡量和证明你的瓶颈实际在哪里之后(避免过早的优化)。
我将以下内容视为非关系解决方案:
您的工具箱中拥有的工具越多,您在响应性能问题时就越灵活。
关于database - 用于社交网络应用程序的 Memcached,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3383322/