Как мне реализовать шаблон «получить объекты изменен с» с MongoDB? - PullRequest
6 голосов
/ 23 апреля 2011

У меня есть коллекция объектов, скажем, они являются "сообщениями", и эти объекты могут быть изменены. Я хотел бы отобразить список на стороне клиента, который обновляется динамически. Таким образом, на стороне клиента, если делать это с помощью опроса, клиент будет вызывать API, например:

getPostsChangedSince(serial)

, где serial может быть монотонно увеличивающимся числом, возможно, отметкой времени. Клиент возвращает список сообщений, которые изменились с того времени, сохраняет новый последний серийный номер, и в следующий раз, когда клиент запрашивает изменения, запрошенные с этого последнего серийного номера.

Я думаю, что основная идея в этом вопросе та же (что касается ASP.NET): Как реализовать "получить последние измененные элементы" с помощью служб данных ADO.NET?

Я пытаюсь найти лучший способ реализовать это в MongoDB.

Мне нравится идея использовать время для сериала, так как оно автоматически работает, по крайней мере, в основном правильно, даже если есть несколько серверов приложений. Серийный номер будет храниться в каждом почтовом объекте и обновляться при каждом изменении объекта.

Последовательность на основе временной метки может быть реализована как:

  • a Дата (я думаю, она хранится как 64-битные миллисекунды с начала эпохи?)
  • метка времени http://www.mongodb.org/display/DOCS/Timestamp+Data+Type
  • что-то "от руки", например хранить миллисекунды как число

Некоторые полезные функции решения включают в себя:

  • гарантирует, что создание, а затем немедленное обновление объекта в разрешении таймера ОС будет по-прежнему увеличивать последовательное значение, несмотря на то, что оно является тем же временем
  • еще лучше было бы гарантировать монотонное увеличение в глобальном масштабе для всех объектов, а не просто гарантировать, что изменение данного объекта приведет к увеличению серийного номера на этом объекте (при этом вызовы getPostsChangedSince (), вероятно, нуждаются во временном запаздывании во времени, чтобы не пропустить изменения - по цене получения нескольких изменений дважды)
  • временные метки на стороне mongodb могут быть хорошими, потому что получение времени в приложении создает разрыв между тем, когда вы получаете время, и когда новый объект сохраняется и доступен в запросах
  • обновить, используя findAndModify () с запросом, включающим старый серийный номер, поэтому «конфликты» (два изменения одновременно) приведут к ошибке, позволяющей приложению повторить попытку

Я понимаю, что некоторые из угловых случаев здесь немного "академичны" и, вероятно, могут быть обмануты в реальной жизни.

Мой подход пока таков:

  • используйте тип даты для сериала
  • при изменении объекта получите текущее время и, если оно совпадает со старым серийным номером объекта, добавьте 1 миллисекунду (да, это прерывается, если вы быстро делаете две модификации без повторного извлечения из mongodb, но это выглядит нормально)
  • использовать findAndModify (), но на основе https://jira.mongodb.org/browse/JAVA-276 может не быть способа обнаружить, если в итоге ничего не найдется для изменения (т. Е. Второе изменение игнорируется в случае конфликта)

Вопросы:

  • Мне кажется, что вместо этого я должен использовать метку времени; правда? Есть минусы?
  • если бы у вас был кластер монго, может ли время в миллисекундах быть более уникальным и правильным, чем время в метках времени в секундах плюс число, в то время как у одного монгода отметка времени более уникальна?
  • есть ли способ определить, обновлял ли findAndModify () что-нибудь?
  • какие-либо общие советы / опыт с этой проблемой? как бы ты это сделал?

Ответы [ 2 ]

0 голосов
/ 08 января 2013

Вы можете продолжать использовать свою обычную коллекцию, как и сейчас, и после каждого обновления дополнительно вставлять идентификатор сообщения в специальную коллекцию TTL.См. http://docs.mongodb.org/manual/tutorial/expire-data/ для получения дополнительной информации об использовании такой коллекции.Mongo позаботится обо всех проблемах синхронизации, вам не нужно беспокоиться о серийных номерах, и вы сможете очень быстро получить доступ к спискам объектов на основе времени по их идентификаторам.

Предупреждение:

useформа блокировки findAndModify, чтобы гарантировать, что изменения действительно были обработаны:

Блокировка / Безопасная запись

Если вы не укажете параметр "new" как true, операция записи не будет блокироватьсяи не вернет ошибку (если она есть).Если вы хотите, чтобы «новый» документ был возвращен, то операция будет ожидать, пока не будет завершена запись, чтобы вернуть новый документ, или возникнет ошибка.

Для «безопасной» (блокирующей) операции записи вы должны вызвать getLastError(если не использовать «новый»).

0 голосов
/ 23 апреля 2011

Рассматривали ли вы "экстернализацию" генератора серийных номеров? Время с точностью MongoDB хорошее, но может стать трудным для синхронизации при использовании нескольких машин. Одним из вариантов является то, что вы можете использовать memcached или что-то подобное, основанное на памяти, очень быстрое и сериализуемое (memcached имеет операцию CAS).

Итак, вы должны сохранить «семя» в memcached с ключом, скажем, counter. Каждый раз, когда приложению необходимо выполнить вставку, оно получает следующий номер из memcached и увеличивает счетчик.

Если подумать, вы даже можете покончить с memcached и просто использовать одну коллекцию строк (извините, документ), у которой просто есть счетчик. Вы можете получить счетчик и увеличить его, что будет чрезвычайно быстрой операцией, имитируя memcached.

И, естественно, вы можете соответствующим образом индексировать данные. Тем не менее, мне интересно, что это приведет к тому, что индекс будет очень несбалансированным (с правой стороны). В зависимости от ситуации, возможно, стоит изучить использование ограниченного сбора. Поэтому, когда вы вставляете данные в основную коллекцию, вставляйте ее также в ограниченную коллекцию и считывайте данные из этой коллекции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...