2

我在 ASP.NET 上问过这个问题...

http://forums.asp.net/t/1584731.aspx

...但也想在这里问。我确定这个问题之前已经解决了,所以我想为什么要重新发明轮子……</p>

简短的故事,我正在使用 memcached 作为数据库的缓存层构建具有社交功能的 Web 应用程序。为了简化问题,让我们假设一个基本设置,我们有一个persons 表和一个friendConnection 表,其中persons 包含个人信息,而friendConnection 有两个外键将一个人链接到另一个人,如果他们互相加为好友(我实际上不是使用表或 SQL,但问题类似)

我的缓存过期逻辑很简单:每当发生对表的放置时,都会使缓存中当前存在的与该表相关的所有选择语句过期。然而,这种逻辑在性能方面很糟糕,因为人们不断地相互交友,缓存永远不会持续超过几秒钟。

例如,一个更复杂的逻辑可能会使包含当前引用的朋友的所有选择语句过期,但这将需要获取与friendConnection 表相关的所有选择语句并检查它们的相关性,这也将成为性能负担。

首先,我的问题有意义吗?

其次,人们通常如何解决这个问题?

4

1 回答 1

1

不要将 memcached 条目与表关联,将条目与实体(即行)关联。

例如,为每个成员创建一个 memcached 条目,该条目存储该成员的朋友列表。

这是一个使用 PHP 的示例。我知道您使用的是 ASP.NET,所以将其视为伪代码。:-)

<?php
$m = new Memcached();
$m->append('Luke.Doolittle', '|Bill Karwin');
$m->append('Bill Karwin', '|Luke.Doolittle');

回复您的评论:

我看到的问题是当时没有将对象放置在 memcached 中的通用模式。

对。在关系数据库中,有一种用于建模数据的正式模式。 规范化是一种定义明确的数据建模方法,可减少冗余并防止异常。最优的规范化组织是由数据本身和数据之间的关系决定的。

在非关系数据库中,没有数据建模的形式化。组织非关系数据的最佳方式不是由数据决定的,而是由您需要针对该数据运行的查询决定的。这样,它类似于定义索引或对关系数据库应用非规范化的过程。

对于每种类型的对象,逻辑会有所不同。那有意义吗?

实际上,您需要针对该对象运行的每种查询类型的逻辑都会有所不同。这就是导致我们在非关系数据存储中冗余存储数据的原因。因为我们可能希望对相同的数据运行各种查询,这意味着我们需要以不同的方式访问数据以针对每种查询类型进行优化。

您如何使用这种技术执行删除?

从 memcached 中获取整个字符串,将值分解为一个数组,删除要删除的元素,内爆新数组,然后将其存储回 memcached。

我上面的例子很简单;它也不强制执行唯一性。

您可能有兴趣查看Redis,它的工作方式类似于 memcached,但也支持本地列表和集合。


我会使用 SQL 来存储数据,使用规范化规则。根据具体情况使用非关系方法来提高特定高优先级查询的性能——在您使用分析来衡量和证明您的瓶颈实际在哪里 之后(避免过早的优化)。

我将以下内容视为非关系解决方案:

  • 非规范化
  • 索引(你知道 SQL 标准根本没有提到索引吗?)
  • 缓存
  • NoSQL 数据存储

您的工具箱中拥有的工具越多,您在响应性能问题时就越灵活。

于 2010-08-01T19:23:41.853 回答