3

这个问题专门与 Couchbase 相关,但我相信它适用于任何使用 memcached api 的东西。

假设我正在创建一个客户端/服务器聊天应用程序,并且在我的服务器上,我将每个用户的聊天会话信息存储在数据桶中。聊天会话结束后,我将从数据桶中删除会话对象,但同时我还希望将其持久保存到永久 NoSQL 数据存储中,以用于报告和分析目的。我还希望会话对象在缓存驱逐、会话超时等时保持不变。

是否有某种“最佳实践”(甚至是我缺少的 Couchbase 功能)使我能够有效地做到这一点并保持内存缓存系统的最佳性能?

4

2 回答 2

2

使用 Couchbase Server 2.0,您可以设置两个存储桶(如果您想分离物理资源,则可以设置两个单独的集群)。在会话集群上,您将存储 JSON 文档(键/值对中的值),可能如下所示:

{ 
  "sessionId" : "some-guid",
  "users" : [ "user1", "user2" ],
  "chatData" : [ "message1", "message2"],
  "isActive" : true,
  "timestamp" : [2012, 8, 6, 11, 57, 00]
}

然后,您可以在会话数据库中编写一个 Map/Reduce 视图,为您提供所有过期项目的列表(注意下面带有 meta 参数的示例需要最近构建的 Couchbase Server 2.0 - 而不是 DP4。

function(doc, meta) {
  if (doc.sessionId && ! doc.isActive) {
    emit(meta.id, null);
  }
}

然后,使用您喜欢的 Couchbase 客户端库,您可以执行查询视图、获取项目并将它们移动到分析集群(或存储桶)中的任务。所以在 C# 中,这看起来像:

var view = sessionClient.GetView("sessions", "all_inactive");
foreach(var item in view) 
{
   var doc = sessionClient.Get(item.ItemId);
   analyticsClient.Store(StoreMode.Add, item.ItemId, doc);
   sessionClient.Remove(item.ItemId);
}

相反,如果您想使用明确的时间戳或过期时间,您的视图可以根据时间戳进行索引:

function(doc) {
   if (doc.sessionId && ! doc.isActive) {
      emit(timestamp, null);
   }
}

然后,您的任务可以通过包含一个 startkey 来查询视图,以返回 x 天内未触及的所有文档。

var view = sessionClient.GetView("sessions", "all_inactive").StartKey(new int[] { DateTime.Now.Year, DateTime.Now.Months, DateTime.Now.Days-1);

foreach(var item in view)
{
   var doc = sessionClient.Get(item.ItemId);
   analyticsClient.Store(StoreMode.Add, item.ItemId, doc);
   sessionClient.Remove(item.ItemId);
}

查看http://www.couchbase.com/couchbase-server/next以获取有关 Couchbase Server 2.0 的更多信息,如果您需要对此方法的任何说明,请在此线程上告诉我。

- 约翰

于 2012-08-06T16:17:18.037 回答
1

CouchDB 存储(最终)是持久的,并且没有内置的过期机制,因此您存储在其中的任何内容都将保持存储,直到您将其删除 - 它不像在 Memcached 中您可以为存储的数据设置超时。因此,如果您将会话存储在 CouchDB 中,您将不得不在它们过期时自行删除它们,因为它不是一种自动机制,但您自己做的事情没有理由不将数据保存在您想要的任何地方同时。

BTH 我认为使用 Persistent NoSQL 而非 SQL 进行会话存储(反之亦然)没有任何优势——两者的性能都将受到 IO 限制。仅内存密钥存储或混合解决方案是完全不同的故事。

至于您的问题:在您的应用程序会话到期/会话关闭机制中移动数据和/或运行定期检查会话存储中是否存在过期会话并移动数据的 cron 作业。

于 2012-07-30T20:07:59.117 回答