Страница 16 из 30
Фицпатрик: В основном Живым Журналом. Мы также пытались запустить фотохостинг, но Flickr нас уделал. Видимо, наш сервис был переусложнен — с прекрасными абстракциями и возможностью встраивания куда угодно. Создавая новый инфраструктурный компонент для Живого Журнала, мы спрашивали себя: «Как это будет работать с FotoBilder?», так что все начали делать абстрактным. Memcached был абстрактным, потому что не было смысла завязывать его с Живым Журналом. Потом мы создали файловую систему наподобие GFS[20] и очередь заданий. Мы создавали эти компоненты, чтобы они могли работать с любым из наших продуктов, но еще и потому, что чем меньше в системе запутанных взаимозависимостей, тем легче ее поддерживать. Даже если это требует больше работы, убрать часть зависимостей — уже большое дело. Поэтому мы начали создавать все эти обобщенные компоненты.
Сейбел: Интересно было бы услышать о развитии Живого Журнала, о том, как вы начинали и как в процессе усваивали необходимые уроки.
Фицпатрик: Все начиналось с одного компьютера с UNIX. На нем одновременно работали несколько пользователей, но постепенно Живой Журнал вытеснил их всех.
Сейбел: Выполнялся как набор CGI-скриптов?
Фицпатрик: Да. То был, кажется, CGI в самом буквальном смысле — пожертвуй всем и умри. Тот провайдер приставил ко мне одного парня. У меня были проблемы, потому что сервер все время сдыхал, и я сказал ему: «Я плачу десять долларов в месяц. Почему он не работает?» Парень ответил: «Ага, сделай-ка вот это». Вскоре я освоил UNIX и понял, что происходит на самом деле.
Затем я переделал все под FastGCI, настроил Apache и вырубил обратный поиск по DNS. После того как все эти этапы пройдены, упираешься в ограничения ввода/вывода или в ресурсы процессора. Потом я получил собственный выделенный сервер, но он был только один, и когда он умирал, у меня начинались проблемы с ресурсами. Я дал доступ на него своим друзьям и просто оставил страницу регистрации открытой. Потому друзья пригласили своих друзей, которые, в свою очередь, пригласили своих друзей, хотя сайт не задумывался как общедоступный. Страница регистрации осталась открытой случайно. Так что потом я поместил на страницу новостей Живого Журнала объявление: «Помогите. Нам нужно купить серверы».
Мы собрали, кажется, тысяч 6 или 7 долларов или около того, купили два больших Dell и поставили их у провайдера Speakeasy в деловом центре Сиэтла, Кто-то порекомендовал нам эти Dell, огромные шести-юнитовые громадины, килограммов под пятьдесят каждая. Логическое разделение было следующим: сервер базы данных и веб-сервер. Это единственное разделение, которое я знал, поскольку работал с двумя процессами — MySQL и Apache.
Какое-то время все работало как надо. Веб-серверы торчали напрямую во внешний мир, у них было по две сетевые карты и небольшой кабель к серверу базы данных. Потом веб-сервер перестал справляться с нагрузкой, но это не было проблемой, поскольку на тот момент у меня имелось несколько одноюнитовых серверов. Итак, у нас было три вебсервера и один сервер базы данных. Тогда я попробовал три-четыре программы балансировки нагрузки для протокола HTTP — mod_backhand, modproxy и Squid — и возненавидел их все. С тех пор не люблю балансировщики нагрузки.
Потому упала база данных. «Вот черт», — сказал я себе. Веб-серверы прекрасно масштабируются, ведь они не сохраняют состояния. Просто добавляешь новые серверы и распределяешь нагрузку. Это был долгий напряженный период. «Так, я могу слегка оптимизировать запросы», но это дает лишь неделю, а потом они опять перестают справляться с нагрузкой. В какой-то момент я задумался, что же нужно каждому конкретному запросу.
Тогда я решил — казалось, мне первому в мире пришла такая мысль, — разбить все это на разделы (partition). Я подготовил документ с рисунками, в котором говорилось, как наш код будет работать. «В главной базе данных будут храниться только метаданные каких-то глобальных вещей, которые дают небольшую нагрузку, а все данные, связанные с индивидуальными блогами и комментариями, для каждого пользователя будут выделены в кластер базы данных. Пользователям с такими-то идентификаторами предназначен определенный раздел базы данных». Задним числом я понимаю, что именно так все и поступают. Но тогда потребовалось много усилий, чтобы переделать код на работающей системе.
Сейбел: Был ли назначен день перевода со старой версии на новую?
Фицпатрик: Нет. У каждого пользователя был флаг, определяющий номер кластера: если он был равен нулю, значит данные находились в основной базе, если отличался от нуля, значит данные уже находились в каком-то разделе. Потом была версия «Ваша учетная запись заблокирована». Учетная запись блокировалась и выполнялась попытка переноса данных, программа пыталась переместить данные и снова сделать это, е£ли вы в это время вносили какие-то изменения. Примерно в таком духе: «Ждите, пока мы не переместим данные, и не вносите никаких изменений в данные в основном кластере, скоро мы переместим вас в ваш индивидуальный кластер».
Такой перевод в фоновом режиме длился несколько месяцев. Мы прикинули, что если бы мы просто выгрузили данные, написали что-то для разбивки SQL-файлов и залили данные назад, то это потребовало бы около недели. Неделя простоя или два месяца медленного переноса? Но в процессе переноса данных 10% пользователей работоспособность сайта снова становилась приемлемой для других пользователей, так что мы смогли увеличить темпы переноса данных с загруженных кластеров.
Сейбел: Это было еще до memcached и Perlbal.
Фицпатрик: До Perlbal — это точно. Memcached, пожалуй, тоже была позднее. По-моему, я создал memcached сразу после колледжа, когда переехал. Помню, как ко мне пришла эта идея. Сайт был на грани, я пошел в душ и вдруг понял, что у нас ведь есть вся эта свободная память повсюду! Я набросал прототип тем же вечером, написал на Perl сервер и клиент, но сервер упал, потому что для сервера на Perl было слишком много обращений к процессору. Поэтому мы начали переписывать его на Си.
Сейбел: И вам не понадобилось покупать новые серверы для базы данных.
Фицпатрик: Да, серверы были дорогими, а процесс перехода с одного на другой — очень медленным. Веб-серверы были дешевы, и добавление новых сразу давало эффект. А при покупке новой базы данных где-то неделя уходит только на запуск и проверку: нужно проверить диски, все установить и настроить.
Сейбел: Значит, все элементы созданной вами инфраструктуры, такие как memcached и Perlbal, были разработаны в ответ на реальные потребности, связанные с масштабированием Живого Журнала?
Фицпатрик: Да, конечно. Все, что мы создали, делалось только потому, что наш сайт падал, и мы ночь напролет выдумывали новые штуки. Однажды мы даже решили купить систему хранения данных NetApp. Это выглядело так. Мы спросили: «Сколько она стоит?», а они в ответ: «Расскажите нам о вашем бизнесе». — «У нас платные учетные записи». «Сколько у вас клиентов? Какая нагрузка?» — «Мы знаем только, что их число растет, вот и все». — «Тогда цена такая: весь доход, который вы можете заплатить, чтобы не развалиться». — «Да пошли вы». Но все же нам была нужна эта штука, и мы ее купили. Скорость ввода/вывода нас не слишком впечатлила, цена была слишком высока, и здесь по-прежнему оставалась единственная точка отказа. Они попытались продать нам конфигурацию с высокой скоростью доступа, но мы сказали: «Да пошли вы. Мы эту ерунду больше не купим».
Итак, мы начали работу над файловой системой. Я даже не уверен, что к этому моменту был опубликован документ по GFS, кажется, я просто услышал о ней от кого-то. В то время я всегда использовал хеш-значение ключа для указания на фрагмент памяти. Почему бы не сделать то же самое с файлами? Файлы постоянны, поэтому нам нужно записывать, где они хранятся, поскольку при добавлении новых узлов хранения меняется и конфигурация. И дело не только в вводе/выводе и отслеживании местонахождения файлов, но и в высокой доступности системы. Мы нашли решение, и я пришел к следующей схеме: «Нам нужно хранить все обращения к файлам, чтобы знать, где что лежит».
20
GFS (Google File System) — распределенная файловая система компании Google, кластерная система, оптимизированная для работы с большими блоками данных по 64 Мбайт и обладающая повышенной защитой от сбоев. — Прим. науч. ред.