How a Seemingly Well-Planned Server Move Crashed, Burned, and Rose from the Ashes | Rob Walling
Роб Уоллинг рассказывает, как через три недели после покупки небольшого стартапа HitTail в конце августа ему пришлось срочно перенести всё приложение, включая базу данных на 250 ГБ (1,2 млрд строк), на новые серверы. План был тщательным: реплицировать данные, отправить диск курьером, на 2-3 часа уйти в офлайн и объединить два сервера в один. Но в назначенный четверг почти всё пошло не так: в 10 утра у старого сервера отказал жёсткий диск, репликация молча упала за 48 часов до этого, копирование гигабайтов данных провалилось на 10% от завершения, а объединение 75 млн строк шло в 20 раз медленнее из-за окна резервного копирования и общего SAN. Чтобы обработать данные, Роб за 4 часа ночью написал приложение на Windows Forms, скомпилировав JavaScript в .NET DLL и переписав Classic ASP (VBScript) на C#. В итоге к 6:45 утра пятницы миграция удалась: приложение снова открыли для пользователей, оставшиеся 75 млн строк копировались ещё 4 дня без единой жалобы, а новое железо оказалось в 2-3 раза отзывчивее старого.
How a Seemingly Well-Planned Server Move Crashed, Burned, and Rose from the Ashes
Как, казалось бы, хорошо спланированный перенос сервера рухнул, сгорел и восстал из пепла
About 8 months ago I acquired a small startup called HitTail. You can read more about the acquisition here.
Около 8 месяцев назад я приобрёл небольшой стартап под названием HitTail. Подробнее об этом приобретении можно прочитать здесь.
When the deal closed, the app was in bad shape. Within 3 weeks I had to move the entire operation, including a large database, to new servers. This required my first all-nighter in a while. Here is an excerpt of an email I sent to a friend the morning of September 16, 2011 at 6:47 am:
Когда сделка закрылась, приложение было в плачевном состоянии. В течение 3 недель мне пришлось перенести всю инфраструктуру, включая большую базу данных, на новые серверы. Это потребовало моей первой за долгое время бессонной ночи. Вот отрывок из письма, которое я отправил другу утром 16 сентября 2011 года в 6:47:
Subject: My First All Nighter in Years
Тема: Моя первая за годы бессонная ночь
Wow, am I tired. Worst part is my kids are going to be up in the next half hour. This is going to hurt 🙂
Ого, как же я устал. Хуже всего то, что мои дети проснутся в ближайшие полчаса. Будет больно 🙂
But HitTail is on a new server and it seems to be running really well. Feels great to have it within my control. There are still a couple pieces left on the old server, but they are less important and I’ll have them moved within a week.
Но HitTail теперь на новом сервере и, похоже, работает действительно хорошо. Здорово, что всё под моим контролем. На старом сервере ещё осталась пара компонентов, но они менее важны, и я перенесу их в течение недели.
I’ll write again in a few hours with the whole story. It’s insane how many things went wrong.
Напишу снова через несколько часов и расскажу всю историю целиком. Просто безумие, сколько всего пошло не так.
What follows is the tale of that long night...
А далее — рассказ о той долгой ночи...
The Setup
Подготовка
I acquired HitTail in late August and it was in bad shape. I had 3 priorities that I wanted to hit hard and fast, in the following order:
Я приобрёл HitTail в конце августа, и он был в плачевном состоянии. У меня было 3 приоритета, по которым я хотел ударить сильно и быстро, в следующем порядке:
Stability – Before I acquired it the site went down every few months, sometimes for several days on end. To stabilize it I needed to move it to new servers, fix a few major bugs, and move 250GB of data (1.2 billion rows).
Plug the Funnel – Conversion rates were terrible; I needed to look at each step of the process and figure out how to improve the percentage of people making it to the next step.
Spread the Word – Market it.
Стабильность — до того как я его приобрёл, сайт падал каждые несколько месяцев, иногда на несколько дней подряд. Чтобы стабилизировать его, мне нужно было перенести всё на новые серверы, исправить несколько серьёзных багов и перенести 250 ГБ данных (1,2 млрд строк).Заткнуть воронку — показатели конверсии были ужасными; мне нужно было рассмотреть каждый шаг процесса и понять, как повысить долю людей, доходящих до следующего шага.Рассказать о нём — заняться маркетингом.
The first order of business was to move to new servers, which involved overnighting 250GB of data on a USB drive to the new hosting facility, restoring from backup, setting up database replication until the databases were in synch, taking everything offline for 2-3 hours to merge two servers into one, test everything, and flip the switch.
Первоочередной задачей был переезд на новые серверы, что включало отправку курьером 250 ГБ данных на USB-накопителе в новый дата-центр, восстановление из резервной копии, настройку репликации базы данных до синхронизации баз, перевод всего в офлайн на 2-3 часа для объединения двух серверов в один, тестирование всего и переключение.
If only it were that simple.
Если бы только всё было так просто.
Thursday Morning, 10am: An Untimely Crash
Четверг, 10 утра: несвоевременный сбой
We had planned to take the old servers offline at 10pm pacific on Thursday, but around 10am one of them went down. The server itself was working, but the hard drive was failing and it wouldn’t server web requests.
Мы планировали отключить старые серверы в 22:00 по тихоокеанскому времени в четверг, но около 10 утра один из них упал. Сам сервер работал, но жёсткий диск отказывал, и он не мог обслуживать веб-запросы.
I received a few emails from customers asking why the server was down and I was able to explain that this should be the last downtime for many months. Everyone was appreciative and supportive. But I spent most of the day trying to get the server stay alive for 12 more hours, with no luck. Half of the users had no access to it for the final 12 hours on the old servers.
Я получил несколько писем от клиентов, спрашивавших, почему сервер недоступен, и смог объяснить, что это должен быть последний простой на многие месяцы. Все отнеслись с пониманием и поддержкой. Но я провёл почти весь день, пытаясь продержать сервер живым ещё 12 часов, — безуспешно. Половина пользователей не имела к нему доступа в последние 12 часов на старых серверах.
Thursday Afternoon, 2pm: Where’s the Data?
Четверг, 14:00: где данные?
We had meticulously planned to have all the data replicated between the old and new database to ensure they would be in synch when we went to perform the migration. But there was one problem...
Мы тщательно спланировали репликацию всех данных между старой и новой базой, чтобы гарантировать их синхронизацию к моменту миграции. Но была одна проблема...
Replication had silently failed about 48 hours beforehand, and neither myself or my DBA noticed. So at 2pm we realized we were literally gigs behind with the synchronization. With only 8 hours until the migration window began, we zipped up these gigs and started copying them from server to server. The dialog said it would take 5.5 hours – no problem! We had 2.5 hours of leeway.
Репликация молча упала примерно за 48 часов до этого, и ни я, ни мой администратор баз данных (DBA) этого не заметили. Так что в 14:00 мы осознали, что буквально на гигабайты отстаём в синхронизации. Имея всего 8 часов до начала окна миграции, мы заархивировали эти гигабайты и начали копировать их с сервера на сервер. Диалог сообщил, что это займёт 5,5 часов — не проблема! У нас был запас в 2,5 часа.
Thursday Night, 8pm: Copy and Paste
Четверг, ночь, 20:00: копировать и вставить
My DBA checked on the copying a few times in the middle of his night (he’s in the UK), and it eventually failed with 10% remaining. At that point we knew that even if we got everything done according to plan we wouldn’t have data for the most recent 48 hours. Grrr.
Мой DBA несколько раз проверял копирование посреди своей ночи (он в Великобритании), и в итоге оно упало с оставшимися 10%. В этот момент мы поняли, что даже если всё пройдёт по плану, у нас не будет данных за последние 48 часов. Эх.
In a last ditch effort to get the data across the wire we selected the info from a single table that changes the most and copied it to the new server, which took only around 5 minutes. The problem was that this data should have been processed by our fancy keyword suggestion algorithm and it hadn’t been.
В отчаянной попытке протащить данные по сети мы выбрали информацию из одной таблицы, которая меняется чаще всего, и скопировали её на новый сервер, что заняло всего около 5 минут. Проблема была в том, что эти данные должны были быть обработаны нашим хитрым алгоритмом подсказки ключевых слов, а этого не произошло.
Friday Morning, 1am: Panic Sets In
Пятница, 1 час ночи: начинается паника
It was about this time I began to panic. Trying to process the data using existing code was not going to happen – the algorithm is written in a mix of JavaScript and Classic ASP, which couldn’t be executed in the same fashion that it is when the app runs under normal conditions. And it wouldn’t run fast enough to process the millions of rows that needed it in any realistic amount of time.
Примерно в это время я начал паниковать. Обработать данные имеющимся кодом было невозможно — алгоритм написан на смеси JavaScript и Classic ASP, которые нельзя было выполнить так же, как они выполняются, когда приложение работает в обычных условиях. И он не отработал бы достаточно быстро, чтобы обработать миллионы строк, которым это требовалось, в сколько-нибудь реалистичные сроки.
So I did one of the craziest things I’ve done in a while. I spent 4 hours, from approximately 11pm until 3am, writing a Windows Forms app that combined the JavaScript and Classic ASP into a single assembly – with the JavaScript being compiled directly into a .NET DLL that I referenced from C# code. Then I translated the Classic ASP (VBScript) into C# and prayed it would work.
Поэтому я сделал одну из самых безумных вещей за долгое время. Я потратил 4 часа, примерно с 23:00 до 3:00, на написание приложения Windows Forms, которое объединяло JavaScript и Classic ASP в одну сборку — причём JavaScript компилировался напрямую в .NET DLL, на которую я ссылался из кода на C#. Затем я перевёл Classic ASP (VBScript) на C# и молился, чтобы это сработало.
And after 2 hours of coding and 2 hours of execution, it worked.
И после 2 часов кодирования и 2 часов выполнения это сработало.
Friday Morning, 3am: It Gets Worse...
Пятница, 3 часа ночи: становится хуже...
During this time the DBA was trying to merge two databases – copying 75 million rows of data from one DB to another. This was supposed to take 3-5 hour based on tests the DBA had run.
В это время DBA пытался объединить две базы данных — копируя 75 миллионов строк данных из одной БД в другую. Это должно было занять 3-5 часов, судя по тестам, которые провёл DBA.
But it was taking 20x longer. The disks were insanely slow because we were running during their backup window and some of the data was on a shared SAN. By 3am, when we should have been wrapping up the entire process, we were 10% done with the 75 million rows.
Но это занимало в 20 раз дольше. Диски были безумно медленными, потому что мы работали во время их окна резервного копирования, а часть данных была на общем SAN. К 3 часам ночи, когда мы должны были уже завершать весь процесс, мы были готовы лишь на 10% из 75 миллионов строк.
By 6am we had to make a call. It was already 9am on the East Coast and customers would surely be logging in soon if they hadn’t already. I was exhausted and at my wits end with the number of unexpected failures, and I asked my DBA what our options were.
К 6 утра нам нужно было принять решение. На Восточном побережье было уже 9 утра, и клиенты наверняка вот-вот залогинятся, если ещё не сделали этого. Я был измотан и на пределе из-за количества непредвиденных сбоев, и спросил своего DBA, какие у нас варианты.
After some discussion we decided to re-enable the application so users could access it, but continue copying the 75 million rows, but with a forced sleep so the app could run with surprisingly little performance impact. It took 4 days for all of the data to copy, but we didn’t receive a single complaint in the meantime.
После некоторого обсуждения мы решили снова включить приложение, чтобы пользователи могли получить к нему доступ, но продолжить копирование 75 миллионов строк — но с принудительной паузой, чтобы приложение работало с удивительно малым влиянием на производительность. На копирование всех данных ушло 4 дня, но за это время мы не получили ни единой жалобы.
Lucky for us, no one noticed. And the app running on the new hardware was 2-3x times more responsive than on the old setup.
К счастью для нас, никто ничего не заметил. А приложение, работающее на новом железе, было в 2-3 раза отзывчивее, чем на старой конфигурации.
Friday Morning, 6:45am: Victory
Пятница, 6:45 утра: победа
After some final testing I logged off at 6:45am Friday morning with a huge sigh of relief. I dashed off the email you read in the intro, then headed to bed to be awoken by my kids an hour later. Needless to say had a big glass of wine the following night.
После финального тестирования я вышел из системы в 6:45 утра в пятницу с огромным вздохом облегчения. Я быстро набросал письмо, которое вы прочитали во вступлении, а затем отправился спать, чтобы час спустя меня разбудили дети. Излишне говорить, что следующим вечером я выпил большой бокал вина.
Building a startup isn’t all the fun you read about on Hacker News and TechCrunch...sometimes it’s even better.
Создание стартапа — это не только то веселье, о котором вы читаете на Hacker News и TechCrunch... иногда оно даже лучше.