LINUX.ORG.RU
ФорумAdmin

Отказоустойчивость

 


1

4

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

Но в конечном счёте что бы мы не навернули в инфраструктуре, в DNS записи придётся указать один конкретный IP адрес. И сервер, чей это IP станет единой точкой отказа, хоть он проксирует трафик на 10 бекэндов, настроен проверять в фоне что они живы и исключать из round robin упавшие ноды.

Насчёт «один IP адрес» я, конечно, слукавил, но не сильно - несколько A/AAAA записей с одинаковым именем можно использовать только для балансировки нагрузки, но не для отказоустойчивости (клиенты выбирают случайный IP из списка, но не ретраят другой, если не фортанёт).

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

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

Пока на ум приходит только CDN типа CloudFlare, которые позволяют переключать IP адрес записи гораздо быстрее, чем позволяет DNS (так как DNS не обновляется, обновляются лишь настройки их сообственного реверс прокси и там уже время реакции секунды).

★★★★★
Ответ на: комментарий от maxcom

Anycast можно мгновенно переключить? Сервер упадёт а маршрут то от этого сам собой не исчезнет.

А у vrrp всё равно точка отказа будет.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

Выглядит как будто ты опрометчиво перекладываешь отказоустойчивость всего сервиса на бэкенд. Клиент тоже должен поучаствовать в ее обеспечении. curl(cli-команда), например, умеет реконнектиться к другому ip, если один недоступен.

cobold ★★★★★
()

Ты возможно не застал это великолепное время, когда здесь был Erzent. Он бы объяснил в чем ты не прав.

Ладно отвлекся.

Обычно под «отказоустойчивостью» (fault tolerance) приводят пример c внедорожником, который катается вдали от цивилизации. К примеру, пробил колесо, машина остановилась, вышли и заменили колесо и поехали дальше.

Простой есть, но сервис не упал в целом.

А под «высокой доступностью» (high availability) приводят пример с самолетом, где все важные системы многократно задублированы. Так как в полете самолет не может остановится и исправить проблему. Переключаются на резервную систему и летят в аэропорт, там после посадки механики разберутся в чем была проблема. Ну это очень и очень упрощенно.

В DNS есть прекрасный механизм SRV записей. Я рекомендую использовать этот механизм.

Этот же механизм по умолчанию применяется в Consul (Service Discovery).

Consul благодаря протоколу Gossip может за микросекунды обновлять таблицу и удалять умершие узлы, добавлять новые узлы. Даже есть примеры рабочие, например, nginx template, который обновляется и перегружается каждый раз при изменение состояния узлов кластера.

Это в случае, если сеть простая без BGP.

А в случае с BGP можно отказаться от NGINX как балансировщика и перевести все хозяйство на ECMP (Equal cost multi path).

Nurmukh ★★★★
()
Ответ на: комментарий от Nurmukh

Это всё хорошо внутри датацентра (или между несколькими датацентрами). А меня интересует вопрос «последней мили». Юзер написал адрес сайта в браузере и сайт должен ему открыться даже если любое меньшинство серверов упало (единственная нода лоад-балансера тоже «меньшинство»). Так что либо failover должен быть не на уровне протокола приложения, либо должен поддерживаться популярными браузерами.

Как я понимаю, у браузеров такого нет (можно натянуть Service Worker'ы, но если юзер пришёл на сайт первый раз, то он не поможет). А вот anycast и VRRP актуальны.

KivApple ★★★★★
() автор топика
Ответ на: комментарий от KivApple

Про vrrp все правильно посоветовали

Только ip ведет не на backend, а на reverse proxy. nginx/angie или haproxy. а тот уже сам проверят доступность backend’ов и балансирует нагрузку по живым

router ★★★★★
()
Ответ на: комментарий от KivApple

Ну тогда это не решение на уровне сетевого стека, а комплекс организационных мер по поддержанию ресурса в пределах указанных в SLA/SLO и так далее.

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

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

Ну и рожать документ, в котором за каждым расписано что отвечают.

Только так.

Nurmukh ★★★★
()
Ответ на: комментарий от BOOBLIK

вся вебня все ретраит другие IP А-записи, если с первым что3не получилось.

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

yandrey ★★
()
Ответ на: комментарий от yandrey

Браузеры очень долго решают что что то не получилось

Смотря что не получилось. Если у сайта админ любитель накрутить всевозможных таймаутов - пользователь будет страдать. А если условный таймаут на tcp handshake поставить где-нибудь в секунду (скромно считаю, что в закрытой связке lba+backend отсутствие хендшейка за секунду - инцидент) - браузер довольно лихо будет скакать по всем возможным тычкам.

l0stparadise ★★★★★
()
Ответ на: комментарий от firkax

Anycast можно мгновенно переключить? Сервер упадёт а маршрут то от этого сам собой не исчезнет.

Можно и нельзя. Сам по себе и правда не исчезнет. Но можно сделать в качестве пира условный exabgp, который анонсирует адрес и каждую секунду делает условный pidof nginx, и если вернулась пустота - анонс ложится. Я к подобной схеме даже автоскейлинг как-то приделывал, немного костыльный, но вполне рабочий.

l0stparadise ★★★★★
()

Это всё легко решается.

но не для отказоустойчивости (клиенты выбирают случайный IP из списка, но не ретраят другой, если не фортанёт).

При падении одного из IP просто поднимаешь его на другой машине алиасом.

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

Самая крутая штука которую я щупал - Remus из RTAI. Жалко что чуваки из DRBD оказались говнюками и не приняли в апстрим Protocol D, а RTAI не осилили свой форк DRBD тащить. В общем, там разные железки связвны жирным каналом, и имеют один внешний IP. При падении одной железки всё, что заметит пользователь - задержка в 200мс при ответе на запрос на котором сдохло железо. Всё. Никаких обрывов, никаких даже перезапросов ничего. Несколько разных железок выглядят как одна.

Однако, во всей этой хрени есть один огромный недостаток. Все всегда решают проблему как по незаметнее обеспечить продолжение работы при сдыхании одной ноды, но никто и никогда не пытался решить проблему - как точно так же незаметно и автоматически воткнуть в кластер новую/починенную ноду взамен сдохшей. Абсолютно все имеющиеся решения подразумевают как минимум тонну ручного пердолинга и почти всегда отановку кластера для синхронизации. Решения - «заслать монтажника в датацентр с новой железкой»/«поднять где-нибудь новую виртуалку» с установленной из готового образа ОС и потом одной командой подключить её и оно само всё сделает - не существует. Всегда пердолинг и пляски с бубном.

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

Stanson ★★★★★
()

Можно сделать что ты всего лишь прокси до нескольких aws lamda, где каждый сервис всего-лишь фунуция в lamda. Также можно и CF, где у тебя будет все работать в CF воркерах. Это далеко не панацея и зачастую избыточно, но неплохой вариант.

anonymous_sama ★★★★★
()
Последнее исправление: anonymous_sama (всего исправлений: 2)
Ответ на: комментарий от l0stparadise

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

Как админ сайта с несколькими A/AAAA/HTTPS-ipv4/6hint может повлиять на то сколько пользователь будет ждать ответа, перед тем как пробовать другой IP-адрес?

yandrey ★★
()
Ответ на: комментарий от BOOBLIK

Это если он их вообще увидит. А ведь они могут потеряться в днс кешах и браузеру дадут только один чтобы не «грузить» его лишней информацией.

firkax ★★★★★
()
Ответ на: комментарий от l0stparadise

Причём тут связка lba (это load balancer?) + backend? У тебя балансер и упал, надо чтобы браузер нашёл альтернативный айпишник (или альтернативный bgp маршрут к тому же айпишнику но на другую железку) где балансер не упал.

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

firkax ★★★★★
()
Ответ на: комментарий от BOOBLIK

Чето сомнительно. У меня как раз такое случилось на сервере, и некоторые http клиенты (не мои) висели по минуте до таймаута на старый ip. Закономерности не нашел, отложил на потом.

Может расскажешь свой опыт, будет интересно.

anonymous
()
Ответ на: комментарий от anonymous

Мой опыт – это 30 секунд задержки и дальше браузер кэширует IP который ему ответил успешно и далее работает с ним. Для моих бизнес-процессов это приемлимый таймаут, как и отвалившиеся 5-10% клиентов, не дождавшихся ответа. Они не стоят даже десятой доли тех денег, которые нужны для настоящего HA. Ну а после срабатывания мониторинга и понимания, что некий хост из A-записи будет лежать долго, можно и подправить DNS вручную, а TTL = 300 быстро раскидает измещения по сети.

BOOBLIK ★★★★
()
Последнее исправление: BOOBLIK (всего исправлений: 1)

Но в конечном счёте что бы мы не навернули в инфраструктуре, в DNS записи придётся указать один конкретный IP адрес. И сервер, чей это IP станет единой точкой отказа, хоть он проксирует трафик на 10 бекэндов, настроен проверять в фоне что они живы и исключать из round robin упавшие ноды.

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

Enthusiast ★★★
()
Ответ на: комментарий от BOOBLIK

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

Потом я посчитал тоже, что не так все плохо, но вот задумался о том как сделать нормально.

anonymous
()
Ответ на: комментарий от Enthusiast

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

А если ты не ограничиваешь клиента своим приложением то фейл.

anonymous
()
Ответ на: комментарий от firkax

Это для локалки только, географическое резервирование так не сделать.

Общий L2+L3 можно сделать через оверлей и растянуть между площадками — прозрачно для сервиса за счёт усложнения сети. Но это обычно вне компетенций лоровца.

И чтоб третий раз не вставать: любое обсуждение технических решений по отказоустойчивости без явного выбора приоритетов по C, A или P в CAP имеет мало смысла.

anonymous
()
Ответ на: комментарий от firkax

Это для локалки только, географическое резервирование так не сделать.

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

Stanson ★★★★★
()

Это уже на уровне сетевого железа реализуется. Когда есть несколько роутеров для одного IP адреса.

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

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

Куда интересней вопрос - как синхронизировать базы, разнесённые по разным регионам.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 3)
Ответ на: комментарий от vbr

Куда интересней вопрос - как синхронизировать базы, разнесённые по разным регионам.

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

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

Enthusiast ★★★
()
Ответ на: комментарий от vbr

Когда есть несколько роутеров для одного IP адреса.

А у тебя днс упал/украли/отдает не те записи.

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

Мы вам перезвоним :)

anonymous
()