Сохранение кэшированных данных после удаления/вытеснения с помощью хранилища, совместимого с Memcache API.

Этот вопрос конкретно относится к Couchbase, но я считаю, что он применим ко всему, что имеет memcached api.

Допустим, я создаю клиент-серверное приложение для чата, и на моем сервере я храню информацию о сеансе чата для каждого пользователя в ведре данных. После завершения сеанса чата я удалю объект сеанса из корзины данных, но в то же время я также хочу сохранить его в постоянном хранилище данных NoSQL для целей отчетности и аналитики. Я также хочу, чтобы объекты сеанса сохранялись при вытеснении кеша, при тайм-ауте сеанса и т. д.

Есть ли какая-то «лучшая практика» (или даже функция Couchbase, которую мне не хватает), которая позволяет мне делать это эффективно и поддерживать максимально возможную производительность моей системы кэширования в памяти?


person EkoostikMartin    schedule 27.07.2012    source источник
comment
Если вы используете ведро Couchbase, оно будет постоянным. Есть ли причина, по которой вам нужно удалить сеанс?   -  person John Zablocki    schedule 28.07.2012
comment
@JohnZablocki - у меня сложилось впечатление, что данные, которые никогда не нужно будет возвращать в ОЗУ, следует удалить из корзины (соображения производительности, чтобы метаданные были меньше и т. д.). Разве это не так?   -  person EkoostikMartin    schedule 28.07.2012


Ответы (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 в базе данных сеанса, которое даст вам список всех элементов с истекшим сроком действия (обратите внимание, что приведенный ниже пример с мета-аргументом требует последней сборки 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, и если вам нужны какие-либо разъяснения по этому подходу, просто дайте мне знать в этой теме.

-- Джон

person John Zablocki    schedule 06.08.2012

Хранилище CouchDB является (в конечном итоге) постоянным и не имеет встроенного механизма истечения срока действия, поэтому все, что вы храните в нем, останется сохраненным до тех пор, пока вы его не удалите — это не похоже на Memcached, где вы можете установить время ожидания для сохраненных данных. Поэтому, если вы храните сеанс в CouchDB, вам придется удалить их самостоятельно по истечении срока их действия, и, поскольку это не автоматизированный механизм, а то, что вы делаете самостоятельно, у вас нет причин не сохранять данные там, где вы хотите. то же время.

BTH, я не вижу преимущества использования Persistent NoSQL по сравнению с SQL для хранения сеансов (и наоборот) — производительность обоих будет связана с вводом-выводом. Хранилище ключей только в памяти или гибридное решение — это совсем другая история.

Что касается вашей проблемы: переместите данные в механизм истечения/закрытия сеанса вашего приложения и/или запустите задание cron, которое периодически проверяет хранилище сеансов на наличие сеансов с истекшим сроком действия и перемещает данные.

person c2h5oh    schedule 30.07.2012
comment
Так что, по сути, вы просто говорите, что всякий раз, когда я удаляю запись из кеша, я одновременно сохраняю ее где-то еще? Нет лучшего способа сделать это? - person EkoostikMartin; 31.07.2012
comment
Не совсем. В Memcached отсутствует хук срока действия, который вы могли бы использовать для сохранения данных в другом хранилище, а в CouchDB даже нет механизма истечения срока действия. - person c2h5oh; 31.07.2012
comment
Пара замечаний... CouchDB и Couchbase — два очень разных зверя. Couchbase поддерживает полный бинарный протокол memcached, включая истечение срока действия данных. Хотя, учитывая вашу потребность в сохранении данных после сеанса, это, вероятно, бесполезно. Если вы храните документы JSON, вы можете включить поле истечения срока действия, а с помощью Couchbase 2.0 запросить представление по расписанию, чтобы удалить документы из сегмента сеанса и переместить его в сегмент долгосрочного хранения. Решения SQL не могут сравниться с Couchbase с точки зрения производительности, поэтому для сеанса используется решение NoSQL. - person John Zablocki; 06.08.2012
comment
@JohnZablocki - ваше предложение больше того, что я искал. Не возражаете ли вы включить это в качестве ответа (возможно, с более подробной информацией), и я могу отметить его как ответ. Спасибо за помощь. - person EkoostikMartin; 06.08.2012