Неисправности и частичные отказы

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

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

Ненадежные сети

Распределенные системы - это системы без совместного использования. Они общаются только через асинхронное сообщение, проходящее через сеть. Но сеть ненадежная.

Если запрос отправлен, многое может пойти не так

  • Запрос мог быть потерян (сетевой кабель отключен)
  • Запрос мог быть поставлен в очередь
  • Удаленный узел вышел из строя и недоступен.
  • Удаленный узел временно приостановлен (для сборки мусора)
  • Удаленный узел обработал запрос, но ответ потерялся в сети.
  • Ответ задерживается, потому что наша сеть перегружена.

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

Когда часть сети отключена от другой из-за сбоя сети, это называется разделом сети.

Тайм-аут - это единственный способ обнаружить неисправность, но есть компромиссы

Если тайм-аут слишком велик, то в это время система недоступна, и пользователи могут видеть сообщения об ошибках.

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

Большая часть сетевых задержек связана с очередями. Поскольку все запросы совместно используют один и тот же канал, при большом трафике будет некоторое формирование очереди. Разные места, где возможны очереди

  • Если несколько узлов отправляют данные в одно и то же место назначения, сетевой коммутатор должен поставить их в очередь и передать их в сетевое соединение назначения один за другим. В загруженном сетевом канале данные должны ждать в очереди, пока не получат слот. Если очередь коммутатора переполняется, некоторые пакеты могут быть отброшены.
  • Когда данные достигают целевой машины, если все процессоры в настоящее время заняты, тогда ОС ставит запрос в очередь до тех пор, пока приложение не будет готово обработать его. Здесь также время ожидания не ограничено.
  • В виртуализированных средах работающая ОС приостанавливается на 10 микросекунд, когда виртуальная машина хочет использовать код ЦП. В этом случае виртуальная машина не может потреблять какие-либо данные из сети, поэтому входящие данные ставятся в очередь монитором виртуальной машины, что увеличивает вариативность сетевых задержек.
  • TCP выполняет обратное давление, при котором узел ограничивает собственную скорость отправки, чтобы избежать перегрузки сетевых ссылок или узла назначения.
  • Если некоторые пакеты потеряны, TCP будет повторно передавать их, что увеличивает задержку.
  • В облачных средах машины являются общими. Таким образом, в зависимости от загруженности соседей задержки в сети могут быть разными.

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

Ненадежные часы

В распределенных системах обработка времени затруднена из-за переменных задержек связи в сети.

Каждая машина имеет свои собственные аппаратные часы, которые имеют незначительные различия в калибровке по сравнению с другими машинами и могут быть немного быстрее или медленнее по сравнению с другими машинами. Часы можно синхронизировать с помощью NTP (Network Time Protocol), который позволяет регулировать время в соответствии со временем, сообщаемым группой серверов. Эти серверы, в свою очередь, получают свое время от более точного источника, такого как приемники GPS.

У компьютеров есть два типа часов

Часы времени - возвращает текущее время на настенных часах. Эти часы настраиваются с помощью NTP. Таким образом, в идеале они должны быть одинаковыми на всех машинах, но если локальные часы машины слишком быстрые, время может быть сброшено, поэтому время может показаться обратным, поэтому их нельзя использовать для расчета продолжительности.

System.currentTimeMillis () или clock_getTime (CLOCK_REALTIME) (Linux) возвращает время настенных часов.

Монотонные часы - у этих часов есть время, которое всегда увеличивается или увеличивается. Таким образом, их можно использовать для расчета продолжительности. System.nanoTime в Java или clock_getTime (CLOCK_MONOTONIC) в Linux делает это.

  • Наличие нескольких процессоров на машине означает, что она может использовать несколько таймеров, но система показывает однородное монотонное время.
  • Когда NTP необходимо сбросить время, он ускоряет или замедляет таймер в зависимости от того, насколько он быстрее, но никогда не заставит время идти назад.

Проблемы с синхронизацией NTP

  • Кварц локального компьютера может дрейфовать
  • Если местное время сильно отличается от NTP, то система может отказаться от синхронизации или может быть принудительно сброшена, что приведет к обратному отсчету времени.
  • Если узел защищен брандмауэром из Интернета, то трудно определить, что часы не синхронизированы.
  • Если есть большая сетевая задержка, то синхронизация может работать некорректно.
  • Службы NTP могут сообщать неправильное время
  • Дополнительные секунды (59 или 61 секунда в минуту) могут вызвать проблемы с системами, которые не рассчитаны на дополнительные секунды.
  • В виртуальных машинах часы виртуализированы. Если виртуальная машина приостановлена ​​на какое-то время, приложение видит, что часы перескакивают вперед на эти секунды или минуты.
  • Если устройство не управляется приложением, то время сложно рассчитать. Пользователь может изменить время на устройстве.

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

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

У часов может быть доверительный интервал, основанный на точных часах, и транзакции могут ждать некоторое время, чтобы убедиться, что транзакции линеаризуемы. API Google Spanners True Time использует доверительные интервалы. Чтобы гарантировать, что временные метки транзакции отражают причинно-следственную связь, Spanner намеренно ожидает длины доверительного интервала перед тем, как зафиксировать транзакцию чтения-записи. Тем самым он гарантирует, что любая транзакция, которая может считывать данные, происходит в достаточно позднее время, поэтому их доверительные интервалы не перекрываются. Для того, чтобы время ожидания было как можно короче, Spanner должен поддерживать как можно меньшую погрешность часов; для этой цели Google развертывает приемник GPS или атомные часы в каждом центре обработки данных, что позволяет синхронизировать часы с точностью до 7 мс.

Обработка паузы

Даже если все правильно синхронизировано, на время сложно рассчитывать из-за произвольных пауз.

  • Это могло быть остановить мировой сборщик мусора
  • Это может быть неожиданный ввод-вывод, например, JVM будет лениво загружать файл класса при первом использовании
  • Виртуальная машина может быть приостановлена ​​и возобновлена
  • Пользователь может закрыть ноутбук и открыть его
  • CPU переключается на другой поток
  • свопинг на диск из-за подкачки
  • Процесс Unix SIGSTOP запущен и возобновлен позже с помощью SIGCONT

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

Идеи для преодоления пауз в процессе

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

Знание, правда и ложь

Истина определяется большинством

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

Итак, решение принимается большинством (половина или более узлов)

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

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

Как бороться со слабыми формами лжи

Если есть поврежденные пакеты, то такие протоколы, как TCP и UDP, используют контрольные суммы, чтобы определить и исправить или повторить попытку.

Очистить ввод от пользователей

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

Модели системы

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

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

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

Асинхронный: здесь нет временных предположений. Некоторые алгоритмы могут работать с асинхронным дизайном, но это очень ограничительно.

Модели отказа узлов

Остановка при сбое - в этой модели узел может выйти из строя из-за сбоя и никогда не вернется.

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

Произвольные сбои - узлы могут делать абсолютно все, включая обман других узлов.

Для моделирования распределенных систем наилучшей моделью является частично синхронная система с аварийным восстановлением.

Модели корректности

Свойства распределенной системы, которые укажут на ее корректность для алгоритма ограждения токенов.

Уникальность - нет двух одинаковых токенов

Монотонная последовательность - если запрос x был возвращен в tx, а y был возвращен в ty, а x завершился до y, то tx ‹ty

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

Безопасность и живучесть

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

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

Источник: https://books.google.com/books/about/Designing_Data_Intensive_Applications.html?id=zFheDgAAQBAJ