这个问题与Couchbase有关,但我相信它适用于memcached api。
让我们说我正在创建一个客户端/服务器聊天应用程序,在我的服务器上,我正在为数据桶中的每个用户存储聊天会话信息。聊天会话结束后,我将从数据桶中删除会话对象,但同时我也希望将其持久保存到永久性NoSQL数据存储区以进行报告和分析。我还希望会话对象在高速缓存逐出,会话超时等时保持持久性
是否存在某种“最佳实践”(甚至是我缺少的Couchbase功能),这使我能够有效地执行此操作并保持内存缓存系统的最佳性能?
答案 0 :(得分: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);
}
}
然后,您的任务可以通过包含一个启动键来查询视图,以返回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的更多信息,如果您需要有关此方法的任何说明,请在此主题上告知我们。
- 约翰
答案 1 :(得分:1)
CouchDB存储(最终)是持久的,没有内置的到期机制,因此无论你存储在它中的任何内容都将保留存储,直到你删除它 - 它不像在Memcached中,你可以设置存储数据的超时。 因此,如果你在CouchDB中存储会话,你必须在它们到期时自己删除它们,因为它不是一个自动机制,但是你自己做的事情没有理由你不在任何地方保存数据。同一时间。
BTH我认为使用Persistent NoSQL over SQL进行会话存储没有任何优势(反之亦然) - 两者的性能都是IO绑定的。仅内存密钥库或混合解决方案是一个完全不同的故事。
至于您的问题:在应用会话到期/会话关闭机制中移动数据和/或运行定期检查会话存储过期会话并移动数据的cron作业。