2015-06-17 2 views
0

Я столкнулся с такой ситуацией:Синхронизация текущего идентификатор сообщения в разговоре между Алисой и Бобом

Diagram

Хост и B обмениваются сообщениями в разговоре через брокера.

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

В любой момент или B может находиться в автономном режиме, и брокер будет держаться сообщений, пока они не придут в Интернете, а затем доставить их.

Каждого хост сохраняет свои собственные и другие хосты сообщений в базе данных таблицы:

ID | From | To | Msg | Type | Uid 

Я понял, используя первичный ключ идентификатора наивной таблицы был бы плохим выбором для идентификации сообщений (как это зависит в порядок вставки), поэтому я определил пользовательское уникальное поле id (uid).

Мой вопрос:

Как я могу убедиться, что текущий идентификатор сообщения синхронизируется между хостом A и B так, что только одно сообщение имеет этот идентификатор? Чтобы я мог использовать идентификатор токена доставки, чтобы определить, какое сообщение было получено, и было бы невозможно, если бы у меня было более одного сообщения с тем же идентификатором.

Если я делаю это по наивности приращения это каждый раз, когда мы отправить/получить сообщение сначала выглядит нормально:

Host A sends message with ID 1 and increases it's current ID to 2 
Host B receives a message and increases it's current ID to 2 
Host B sends message with ID 2 and increases it's current ID to 3 
Host A receives message and increases it's current ID to 3 
... 

Но это может очень легко ломается:

Host A sends message with ID 1 and increases it's current ID to 2 
Host B sends a message (before receiving the previous one) with ID 1 
clash.. two messages with ID 1 received by both hosts 

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

К сожалению, любое решение, касающееся брокера, нецелесообразно, поскольку я не могу коснуться кода брокера.

+0

Вы можете добавить идентификатор хоста как sufix в ID. – iz25

ответ

1

Это типичная проблема распределенных систем (упражнение класса?). Я полагаю, вы пытаетесь сохранить один и тот же идентификатор, чтобы определить абсолютный порядок среди всех сообщений, которыми обмениваются Алиса и Боб. Если это не так, то решение, предоставленное в комментарии john1020, должно быть достаточно. Другая возможность заключается в том, чтобы идентификатор хранился в одном узле, к которому можно получить доступ как A, так и B, а механизм распределенных блокировок синхронизирует доступ. Таким образом, вы всегда определяете порядок даже при столкновении. Но это не всегда возможно, а иногда и не эффективно.

К сожалению, не существует способа поддерживать абсолютный порядок (кроме наличия уникального счетчика с распределенными замками). Если у вас есть один идентификатор, который может быть изменен как A, так и B, у вас возникнет проблема возможной согласованности и риска столкновений.Столкновение - это в основном проблема, которую вы описали.

Теперь представьте, что оба Боба и Алиса отправят сообщение одновременно, оба установлены в 2. В каком порядке вы будете хранить сообщения? На самом деле это не имеет значения, это похоже на ситуацию, когда два человека разговаривали по телефону одновременно. Столкновение.

Однако интересно узнать, какие сообщения действительно имеют последовательность или причинный эффект: чтобы вы могли поддерживать порядок между сообщениями, вызванными другими сообщениями: Боб приглашает Алису танцевать, а Алиса говорит «да», два сообщения с заказом.

Для сохранения такого заказа вы можете применить некоторые методы, такие как векторные часы (на основе векторного алгоритма временных меток Лесли Лампорта): https://en.wikipedia.org/wiki/Vector_clock. Вы также можете прочитать о AWS DynamoDB: http://the-paper-trail.org/blog/consistency-and-availability-in-amazons-dynamo/

Также вы можете использовать тот же механизм, что и Cassandra для распределенных счетчиков. Это приятное описание: http://www.datastax.com/wp-content/uploads/2011/07/cassandra_sf_counters.pdf

Смежные вопросы