Почему упорядочить сообщения так сложно?

JavaScript Язык программирования

Многим предприятиям необходимо учитывать порядок доставки сообщений:

  • чат один на одинДоставка сообщения, чтобы убедиться, что порядок отправки отправителя соответствует порядку представления получателя.

  • Групповой чатДоставка сообщений, чтобы убедиться, что все получатели показывают один и тот же порядок

  • Сообщение о пополнении счета, чтобы запросы, инициированные одним и тем же пользователем, выполнялись в согласованной последовательности на стороне сервера.

Порядок сообщений — очень сложный вопрос при проектировании архитектуры распределенной системы.Каковы распространенные методы оптимизации?

Компромисс 1: время клиента или сервера имеет преимущественную силу

Независимо от того, какая ситуация, необходима линейка для измерения порядка последовательности, которая может быть основана на времени клиента или сервера в соответствии с бизнес-сценарием, например:

  • Порядок, в котором отображаются электронные письма, фактически зависит от времени отправки клиента.

Голос за кадром: пока отправитель настраивает время в почтовом протоколе на 1970 или 2970, получатель может оставаться «вверху» или «внизу» после получения электронной почты.

  • Оценка времени пиковой активности должна основываться на времени сервера.Клиент не может изменить локальное время, чтобы пик можно было отключить заранее.

Компромисс 2: сервер генерирует монотонно увеличивающийся идентификатор в качестве временной основы.

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

Голос за кадром: Эта единственная точка генерации идентификаторов может легко стать узким местом.

Компромисс 3: если бизнес может принять тенденцию увеличения id с небольшой ошибкой

Нет таких точных требований по времени для отправки сообщений, времени публикации и даже пикового времени:

  • Время сообщений в чате, опубликованных в течение 1 с, не соответствует порядку, это нормально

  • Порядок постов, публикуемых в одной и той же 1с, не правильный, ничего страшного

  • При инициации seckill в течение 1 с, из-за временной ошибки между несколькими серверами, seckill, который падает на сервер A, проходит успешно, но seckill, который падает на сервер B, еще не запущен, что допустимо в бизнесе (пользователи не могут это воспринять)

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

Таким образом, алгоритм генерации идентификаторов всегда можно распределить для генерации идентификаторов в качестве временной основы.

Компромисс 4: использование одноточечной сериализации может обеспечить одинаковое время для нескольких машин.

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

Возможна «одноточечная сериализация»:

  • Сначала сериализуйте операцию на одной машине

  • Затем распределите последовательность операций на все машины, чтобы убедиться, что последовательность операций на нескольких машинах непротиворечива, а окончательные данные непротиворечивы.

Типичный сценарий 1: синхронизация базы данных master-slave


В архитектуре базы данных «ведущий-ведомый» восходящий поток инициирует три операции, op1, op2 и op3 соответственно.Мастер главной библиотеки сериализует все операции записи SQL op3, op1 и op2, а затем отправляет ту же последовательность подчиненному подчиненная библиотека для выполнения, чтобы гарантировать, что непротиворечивость всех данных базы данных заключается в использовании идеи «сериализации из одной точки».

Типичный сценарий 2: Непротиворечивость файлов в GFS


GFS (файловая система Google) Чтобы обеспечить доступность файлов, файл должен храниться в нескольких копиях.При записи операций в один и тот же файл в нескольких восходящих потоках основной сервер фрагментов сначала сериализует операции записи, а затем сериализует операции записи.Последняя операция отправляется на другие серверы фрагментов для обеспечения согласованности данных избыточных файлов.

Чат один на один, как сделать так, чтобы порядок отправки соответствовал порядку получения?

Для нужд индивидуального чата отправитель A по очереди отправляет три сообщения: msg1, msg2 и msg3 получателю B. Могут ли эти три сообщения обеспечить согласованность времени отображения (порядок отправки и отображения)?

Конструктивные идеи схемы следующие:

(1) Если используется последовательность одноточечной сериализации сервера, может случиться так, что последовательность сообщений, полученных сервером, будет msg3, msg1 и msg2, что будет несовместимо с последовательностью отправки.

(2) В бизнесе нет необходимости в глобальной согласованности сообщений, нужно только согласовать время сообщений, отправляемых ta в B для одного и того же отправителя A. Обычная схема оптимизации заключается в том, что в сообщениях, отправляемых из A в B ,Добавьте абсолютную синхронизацию, локальную для отправителя A, чтобы представить синхронизацию представления получателя B.

msg1{sender:A, seq:10, receiver:B, msg:content1}

msg2{sender:A, seq:20, receiver:B, msg:content2}

msg3{sender:A, seq:30, receiver:B, msg:content3}


Может возникнуть проблема: если получатель B сначала получает msg3, то msg3 будет отображаться первым, а после получения msg1 и msg2 оно будет отображаться перед msg3.

Сообщения группового чата, как сделать так, чтобы каждый получатель получил один и тот же заказ?

Чтобы удовлетворить потребности в сообщениях группового чата, как N участников группы могут общаться в одной группе, как гарантировать, что сообщения, полученные всеми участниками группы, отображаются в одной и той же последовательности?

Конструктивные идеи схемы следующие:

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

(2) Следовательно, для сериализации можно использовать единую точку сервера.


Как показано на рисунке выше, процесс отправки группового чата выглядит следующим образом:

(1) sender1 отправляет msg1, sender2 отправляет msg2;

(2) msg1 и msg2 подключены к кластеру для обслуживания кластера;

(3) Сервисный уровень передает на нижний уровень уникальную последовательность для определения времени отображения приемника;

(4) последовательность msg2, полученная службой, равна 20, а последовательность msg1 равна 30;

(5) Отправляйте сообщения нескольким друзьям группы через службу доставки.Даже если друзья группы получают msg1 и msg2 в разное время, они могут отображаться в соответствии с последовательностью;

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

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

Есть ли какие-либо дополнительные методы оптимизации?

На самом деле, групповое сообщение не должно обеспечивать порядок глобальной последовательности сообщений, а только должно обеспечивать порядок сообщений в группе.В этом случае хорошей идеей становится «сериализация идентификаторов».


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

На данный момент использование локальных часов для генерации последовательности работает, не правда ли, это умно?

Суммировать

(1) Чтобы быть «упорядоченным», должна быть линейка для измерения «упорядоченности», которая может быть линейкой на стороне клиента или линейкой на стороне сервера;

(2) Большинство предприятий могут принять крупномасштабную тенденцию и упорядоченную, мелкомасштабную ошибку, абсолютно упорядоченный бизнес может полагаться на абсолютную способность синхронизации сервера;

(3) Одноточечная сериализация является распространенным методом для обеспечения единства синхронизации нескольких машин.Типичные сценарии включают согласованность db master-slave и согласованность нескольких файлов gfs;

(4) Индивидуальный чат, если время отправки соответствует времени получения, можно использовать последовательность клиента;

(5) Для группового чата необходимо только убедиться, что время всех сообщений получателя согласовано, и необходимо использовать последовательность сервера.Существует два метода: одноточечное абсолютное время, а другое - идентификатор сериализация;

Идея важнее, чем вывод, я надеюсь, что у каждого есть что-то получить.

Architect's Road — делитесь техническими статьями, которые можно реализовать