Статьи

Синхронизация часов в кластере Кассандра, Pt. 1: проблема

Эта статья была изначально написана Вильямом Голубом

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

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

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

О часах в кластерах Кассандры

Cassandra сериализует операции записи по меткам времени, которые вы отправляете с запросом.  Отметки времени решают важную проблему сериализации с узлами, которые по своей сути слабо связаны в больших кластерах. В то же время, однако, отметка времени является его ахиллесовой пятой. Если системные часы расходятся друг с другом, то же самое происходит и с метками времени операций записи, и вы можете столкнуться с необъяснимыми несоответствиями данных. Кассандре очень важно иметь правильные часы.

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

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

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

К сожалению, есть отличное готовое решение. Почему к сожалению?

Сетевой протокол времени

Сетевой протокол времени (NTP) получает время от внешнего источника времени в сети и распространяет его дальше по сети. NTP использует иерархическую древовидную топологию, где каждый слой называется «стратами часов», начиная со слоя 0 в качестве авторитетного источника времени и продолжая со стратами 1, 2 и т. Д. Узлы, которые синхронизируют часы с узлами на страте n, становятся вершины на Стратуне n + 1. Демон NTP периодически отправляет запросы времени указанным серверам, устанавливает значение задержки сети, связанной с передачей сообщений, и заново настраивает локальные часы на рассчитанное время. Запуск демона NTP поможет избежать смещения часов, особенно на загруженных машинах.

Чтобы заставить работать NTP, вам нужно указать набор серверов, с которых будет извлекаться текущее время. Серверы NTP могут быть предоставлены вашим сетевым поставщиком, или вы можете использовать общедоступные серверы NTP. Лучший список доступных общедоступных серверов NTP — это проект NTP pool, в котором вы также можете найти лучшие варианты для своего географического региона. Это хорошая вещь, чтобы использовать этот бассейн. Вы не должны использовать NTP-серверы без согласия провайдера.

Logentries_Try_It_Free_Promo_W

Как установить демон NTP

Установить демон NTP так же просто, как:

aptitude install ntpd

и это работает сразу. Это потому, что он предварительно настроен на использование стандартного пула NTP-серверов. Если вы посмотрите на них, /etc/ntp.confвы увидите серверы, определенные с помощью параметра server, например:

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst

Это по умолчанию для систем Debian, вы можете увидеть немного другой список в вашем дистрибутиве. iburstПараметр существует для оптимизации. Если вы хотите , чтобы проверить , как NTP демон работает, выполните следующую команду: ntpq -p. Вы получите список, похожий на этот:

remote  refid  st t when poll reach  delay  offset  jitter
==============================================================================
*dns1.dns.imagin 213.130.44.252  3 u  17  64  7  1.979  0.035  0.235
-eu-m01.nthweb.c 193.1.219.116  2 u  19  64  7  1.064  9.067  0.094
+tshirt.heanet.i .PPS.  1 u  15  64  7  3.276  -0.193  0.066
+ns0.fredprod.co 193.190.230.65  2 u  15  64  7  0.818  -0.699  8.112

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

NTP использует алгоритм оптимизации, который выбирает лучший источник текущих часов, а также рабочий набор серверов, которые он принимает во внимание. Узел, помеченный «*», является источником текущего времени. Узлы, отмеченные знаком «+», используются в окончательном наборе. Узлы, отмеченные «-», отбрасываются алгоритмом.

Вы можете перезапустить демон NTP с помощью

service ntpd restart

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

Почему бы просто не установить демон NTP на каждом узле

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

Что касается Кассандры, важна относительная разница между часами , а не их абсолютная точность. По умолчанию NTP будет синхронизироваться с набором случайных NTP-серверов в Интернете, что приведет к синхронизации абсолютных часов. Поэтому относительная разница часов в кластере C * будет зависеть от того, как часы синхронизируются с абсолютными значениями нескольких случайно выбранных общедоступных серверов.

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

Насколько точны в абсолютных значениях общедоступные NTP-серверы? Мы провели быструю проверку 560 случайно выбранных общедоступных серверов NTP из общего пула. Статистика:

  • 11% дрейфа ниже 0,5 мс
  • 15% дрейфа ниже 1 мс
  • 62% меньше 10 мс дрейфа
  • 11% дрейфа ниже 100 мс

Есть также выбросы, один из которых отключен на несколько часов.

Предполагая: (1) наши проверки являются репрезентативными, (2) каждый демон NTP выбирает 4 случайных NTP-сервера и (3) синхронизируется со вторым лучшим вариантом (это оптимистично), это вероятности отключения наших кластерных часов:

Nodes  5  10  25  100
95%  2.489  5.180  9.349  19.723
50%  7.122  10.892  18.872  44.394
25%  10.917  16.969  30.855  54.197
10%  18.584  30.291  45.311  66.942

Как это прочитать: предположим, кластер из 25 узлов, то с вероятностью 50% будет два узла с разностью тактовых импульсов более 18,8 мс.

Результаты могут быть удивительными — даже в небольшом кластере из 10 узлов они будут отключены более чем на 10,9 мс в половину времени, а с вероятностью 10% будут отключены более чем на 30 мс.