Хабрахабр

Failover: нас губит перфекционизм и… лень

Летом традиционно снижается и покупательская активность, и интенсивность изменения инфраструктуры веб-проектов, говорит нам Капитан Очевидность. Просто потому что даже айтишники, случается, ходят в отпуск. И CТО тоже. Тем тяжелее тем, кто остаётся на посту, но сейчас не об этом: возможно, именно поэтому лето — лучший период для того, чтобы не торопясь обдумать существующую схему резервирования и составить план по её улучшению. И в этом вам будет полезен опыт Егора Андреева из AdminDivision, о котором он рассказал на конференции Uptime day.

А попадаться в них совершенно нельзя. При строительстве резервных площадок, при резервировании есть несколько ловушек, в которые можно попасть. Мы пытаемся сделать всё-всё-всё идеально, а идеально делать не нужно! И губит нас во всем этом, как и во многом другом, перфекционизм и… лень. Нужно делать только определённые вещи, но сделать их правильно, довести до конца, чтоб они нормально работали.

И во всех методах резервирования я предлагаю думать в следующем контексте: где деньги? Failover — это не какая-то такая весёлая фановая штука «чтоб было»; это вещь, которая должна сделать ровно одно — уменьшить время простоя, чтобы сервис, компания, теряла меньше денег.

Это страшное заблуждение.
Первая ловушка: когда мы строим большие надёжные системы и занимаемся резервированием — мы уменьшаем число аварий. И если мы сделаем всё правильно, то совокупно мы время простоя уменьшим. Когда мы занимаемся резервированием, число аварий мы, скорее всего, повышаем. Ведь что такое резервирование? Аварий будет больше, но они будут происходить с меньшими издержками. Любое усложнение — это плохо: у нас появляется больше винтиков, больше шестерёнок, словом, больше элементов — и, следовательно, выше шанс на поломку. — это усложнение системы. И будут ломаться чаще. И они действительно разломаются. И его срочно нужно зарезервировать.
Штош (с) Берём вторую площадку, строим идентичную систему… Сложность становится в два раза больше — у нас две сущности. Простой пример: скажем, у нас есть некий сайт, с PHP, MySQL. Так вот, логика репликации — она обычно очень сложная, и стало быть, совокупная сложность системы может быть не в 2, а 3, 5, 10 раз больше. А ещё мы сверху накатываем определённую логику переноса данных с одной площадки на другую — то есть репликация данных, копирование статики и так далее.

Вуаля: мы хотим получить супернадёжную систему, которая работает вообще без простоя, переключается за полсекунды (а лучше вообще мгновенно), и начинаем воплощать мечты в реальность. Вторая ловушка: когда мы строим по-настоящему большие сложные системы, мы фантазируем, что же хотим получить в итоге. Чем сложнее нам придётся делать эту логику, тем чаще система будет ломаться. Но здесь тоже есть нюанс: чем меньше желаемое время переключения, тем более сложной получается логика системы. Тут зачастую ловишь себя на мысли: вот… лучше б не резервировали. И можно попасть в очень неприятную ситуацию: мы всеми силами пытаемся время простоя уменьшить, а на самом деле мы всё усложняем, и когда что-то идёт не так, время простоя в итоге будет больше. Лучше б оно одно работало и с понятным временем простоя.

Надо перестать себе врать, перестать себе льстить, что мы тут сейчас будем строить космолёт, но адекватно понимать, сколько проект может полежать. Как можно с этим бороться? И под это максимальное время мы будем выбирать, какими, собственно, методами будем повышать надёжность нашей системы.

Самое время для «историй из ж»… из жизни, конечно же.

Пример номер один

Представьте сайт-визитку трубопрокатного завода №1 города N. На ней написано огромными буквами — ТРУБОПРОКАТНЫЙ ЗАВОД №1. Чуть ниже — слоган: «Наши трубы — самые круглые трубы в N». И снизу номер телефона генерального директора и его имя. Понимаем, что нужно резервировать — это ж очень важная штука! Начинаем разбираться, из чего состоит. Html-статика — то есть пара картиночек, где генеральный, собственно, за столом в бане со своим партнером обсуждают какую-то очередную сделку. Начинаем думать про время простоя. В голову приходит: лежать там нужно пять минут, не больше. И тут вопрос: а сколько с этого нашего сайта было продаж вообще? Сколько-сколько? Что значит «ноль»? А то и значит: потому что все четыре сделки за прошлый год генеральный сделал за тем же столом, с теми же людьми, с которыми они ходят в баню сидят за столом. И понимаем, что даже если день полежит сайт — страшного не будет ничего.
Исходя из вводных, есть день на поднятие этой истории. Начинаем думать про схему резервирования. И выбираем самую идеальную схему для резервирования для данного примера: мы резервирование не используем. Вот эта вся штука поднимается любым админом за полчаса с перекурами. Поставить веб-сервер, положить файлы — всё. Оно заработает. Ни за чем не нужно следить, ничему не нужно уделять особого внимания. То есть вывод из примера номер один довольно очевидный: сервисы, которые резервировать не нужно — резервировать не нужно.

Пример номер два

Блог компании: специально обученные пишут туда новости, вот мы поучаствовали в такой-то выставке, а вот мы выпустили еще новый продукт и так далее. Допустим, это стандартный PHP с WordPress, небольшая база данных и чуть-чуть статики. В голову, конечно, опять приходит, что лежать ни в коем случае нельзя — «не больше пяти минут!», вот это всё. Но давайте подумаем дальше. Что этот блог делает? Туда приходят из Яндекса, из Гугла по каким-то запросам, по органике. Здорово. А продажи как-то вообще с ним связаны? Прозрение: не особо. Рекламный трафик идёт на основной сайт, который на другой машине. Начинаем думать про схему резервирования бложека. По-хорошему, за пару часов его нужно поднять, и к этому было бы неплохо подготовиться. Разумным будет взять в другом дата-центре машину, на нее вкатить окружение, то есть веб-сервер, PHP, WordPress, MySQL, и оставить это лежать притушенным. В момент, когда мы понимаем, что всё сломалось, нужно сделать две вещи — раскатать дамп mysql на 50 метров, он пролетит там за минуту, и раскатать там какое-то количество картинок из бэкапа. Это тоже там не бог весть сколько. Таким образом, за полчаса вся эта штука поднимается. Никаких репликаций, или прости господи, автоматического failover'a. Вывод: то, что мы можем быстро раскатать из бэкапа — резервировать не нужно.

Пример номер три, посложнее

Интернет-магазин. PhP с open heart немножко подпиленный, mysql с солидной базой. Довольно много статики (ведь в интернет-магазине есть красивые HD-картиночки и всё такое прочее), Redis для сессии и Elasticsearch для поиска. Начинаем думать про время простоя. И тут, конечно, очевидно, что день безболезненно интернет-магазин валяться не может. Ведь чем дольше он лежит, тем больше денег мы теряем. Стоит ускориться. А насколько? Полагаю, если мы час полежим, то никто с ума не сойдет. Да, мы что-то потеряем, но начнём усердствовать — будет только хуже. Определяем схему простоя, допустимого в час.
Как это все можно зарезервировать? Машина нужна в любом случае: час времени — это довольно мало. Mysql: тут уже нужна репликация, живая репликация, потому что за час 100 гб в дамп, скорее всего, не вольётся. Статика, картиночки: опять же, за час 500 гб может не успеть влиться. Стало быть, лучше сразу картиночки копировать. Redis: вот тут интереснее. В Redis сессии лежат — просто взять и похоронить мы его не можем. Потому что это будет не очень хорошо: все пользователи окажутся разлогиненными, корзины очищенными и так далее. Люди будут вынуждены заново вводить свой логин и пароль, и много народу может отколоться и покупку не завершить. Опять же, конверсия упадет. С другой стороны, Redis прям один в один актуальный, с последними залогинившимися пользователями, наверное, тоже не нужен. И хороший компромисс — взять Redis и восстановить его из бэкапа, вчерашнего, либо, если он у вас каждый час делается, — часовой давности. Благо восстановление его из бэкапа — это копирование одного файла. А самая интересная история — это Elasticsearch. Кто когда-либо поднимал репликацию MySQL? Кто когда-нибудь поднимал репликацию Elasticsearch? И у кого она после работала нормально? Я к чему: видим в нашей системе некую сущность. Она вроде как полезная — но она сложная. Сложная в том смысле, что у наших коллег-инженеров нет опыта работы с ней. Либо есть негативный опыт. Либо мы понимаем, что пока это довольно новая технология с нюансами или сыростью. Думаем… Блин, elastic тоже здоровый, его из бэкапа тоже долго восстанавливать, что делать? Понимаем, что elastic в нашем этом случае используется для поиска. А как продаёт наш интернет-магазин? Идём к маркетологам, спрашиваем, вообще откуда люди приходят. Они отвечают: «90% из Яндекс-маркета приходят прямо в карточку товара». И либо покупают, либо нет. Следовательно, поиск нужен 10% пользователей. А держать репликацию elastic'a, особенно между разными дата-центрами в разных зонах, — там, действительно, много нюансов. Какой выход? Мы берем elastic на резервированной площадке и ничего с ним не делаем. Если дело затянется, то мы его когда-нибудь потом, возможно, поднимем, но это не точно. Собственно, вывод плюс-минус прежний: сервисы, которые на деньги не влияют, мы, опять же, не резервируем. Чтобы схема оставалась проще.

Пример номер четыре, ещё сложнее

Интегратор: продажи цветов, вызова такси, продажи товаров, в общем, чего угодно. Серьёзная штука, которая работает 24/7 на большое число пользователей. С полноценным интересным стеком, где есть интересные базы, решения, высокая нагрузка, и самое главное, лежать ему больше 5 минут больно. Не только и не столько потому, что люди не купят, а потому что люди увидят, что эта штука не работает, расстроятся и могут вообще второй раз не прийти.
Окей. Пять минут. Что с этим будем делать? В этом случае мы по-взрослому, на все деньги строим настоящую резервную площадку, с репликацией всего и вся, и возможно, даже автоматизируем по максимуму переключение на эту площадку. И в дополнение к этому нужно не забыть сделать одну важную вещь: собственно, написать регламент переключения. Регламент, даже если у вас автоматизировано всё и вся, может быть очень простой. Из серии «запустить вот такой-то сценарий ansible», «в route 53 нажать такую-то галку» и так далее — но это должен быть какой-то точный список из действий.
И вроде все понятно. Репликацию переключить — тривиальная задача, либо она сама переключится. Переписать доменное имя в dns — из той же серии. Беда в том, что когда падает подобный проект, начинается паника, и даже самые сильные, бородатые админы могут быть ей подвержены. Без чёткой инструкции «открой терминал, зайди сюда, адрес у нашего сервера по-прежнему вот такой» срок в 5 минут, отведённых на реанимацию, выдержать сложно. Ну и плюс, когда мы этим регламентом пользуемся, легко отфиксировать какие-то изменения в инфраструктуре, например, — и соответствующим образом изменить регламент.
Ну, а если если система резервирования очень сложная и в какой-то момент мы допустили ошибку, то мы можем уложить и нашу резервную площадку, а вдобавок данные превратить в тыкву на обеих площадках — это будет совсем грустно.

Пример номер пять, полный хардкор

Международный сервис с сотней миллионов пользователей по всему миру. Все таймзоны, какие только есть, highload на максималках, лежать вообще никак нельзя. Минута — и будет грустно. Что делать? Резервировать, опять же, по полной программе. Сделали всё, о чём говорил в предыдущем примере, и ещё чуточку больше. Идеальный мир, и наша инфраструктура — она по всем понятиям девопса IaaC. То есть всё вообще в git, и только кнопку нажимай.
Чего не хватает? Одного — учений. Без них нельзя. Кажется, у нас все идеально, у нас вообще все под контролем. Кнопку нажимаем, всё происходит. Даже если это так — а мы понимаем, что так оно не бывает — наша система взаимодействует с какими-то другими системами. К примеру, это dns от route 53, s3-хранилища, интеграция с какими-то api. Всё предусмотреть в этом умозрительном эксперименте мы не сможем. И пока мы реально не дёрнем рубильник — не узнаем, заработает оно или нет.

Не ленитесь и не переусердствуйте. На этом, наверное, всё. И да пребудет с вами uptime!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть