Архив за месяц: Октябрь 2021

Логические часы Лэмпорта

Нельзя полагаться на часы в распределенных системах, потому что, даже при условии синхронизации их по NTP, они не будут полностью синхронны и разница будет расти со временем. Тем не менее, если такая система обменивается сообщениями, то встает вопрос в необходимости определения последовательности событий между хостами. Предположим, что хост генерирует события и некоторые из них (или все) отправляет по сети в виде сообщений, принимающая сторона фиксирует (обрабатывает) у себя эти сообщения аналогично тем, что уже обработала сама ранее (внутренние или внешние). Если мы станем рассматривать эти сообщения в порядке их появления, то мы отсортируем их по времени, но время у каждого хоста свое. Попробуйте запросить выборку событий в период времени у каждого хоста и вы удивитесь результатам, так как некоторые хосты будут считать что событие А уже наступило в этот период времени, а другой хост будет считать иначе. Таким образом, если мы сделаем выборку событий за период времени с каждого хоста, то из-за различий во времени, мы получим неоднозначность, например, события-источники могут иметь отметку времени более позднюю чем события-приемники. Я пытался найти для себя удачный пример, нашел его в лекции ИТМО “Введение в распределенные вычисления”, они предлагают нам представить банковские филиалы которые обмениваются денежными переводами. Каждый филиал в случайные промежутки времени производит транзакцию перевода денежных средств в другой филиал (дебит), внутри себя или принимает внешний перевод (кредит). Требуется посчитать сумму средств во всех филиалах за период времени. В условиях рассинхрона времени может оказаться что средства отправленные из филиала A будут отмечены временем T1, при этом филиал-приемник B зарегистрирует транзакцию во время T2, но если время в филиале B отставало от времени в филиале A, то окажется, что транзакция пришла раньше чем ушла (по мнению B), что само по себе абсурдно и может вообще не попасть во временные рамки периода. Это означает, что сумма денежных средств в банках не будет равна ожидаемой, первоначальной сумме. Часы Лемпорта могут нам в решении этой задачи, суть состоит в том, что событие имеет ID, оно отправляется в FIFO канал другого хоста, тот принимает его и обрабатываем следующим образом:

  • если его внутренний счетчик меньше чем тот, что стоит в сообщении, то хост регистрируя транзакцию теперь использует внешний счетчик, увеличив его на 1
  • если его внутренний счетчик больше — он увеличивает его на 1 и регистрирует транзакцию используя его
  • предполагается, что принимающий хост отправляет ответ с новым счетчиком, который обновит состояние отправителя

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