Знакомьтесь, Олег Анастасьев — ведущий разработчик Одноклассников, спикер на конференциях по Java и Cassandra, эксперт в области распределенных и отказоустойчивых систем. С Олегом мы поговорили о следующем:
- Что не так с термином «архитектор»
- Зачем Одноклассникам 11 000 серверов
- Как выглядят учения по ликвидации аварий
- Что такое «Правило большого З»
- Как в Одноклассниках используют Cassandra
- В чём для современной компании сложности с размещением кода в Open Source
- Как в Одноклассниках работают с Big Data
Как всегда, под катом — полная текстовая расшифровка беседы.
Архитектура и архитекторы
— Олег, хотя по своей роли ты близок к архитектору, ты везде говоришь, что ты «ведущий программист». Я знаю, что к слову «архитектор» у тебя особенная нелюбовь. Расскажи, пожалуйста, почему.
— Сейчас в индустрии понятие «архитектор» означает некоего человека с огромной головой, который всё всегда знает наперёд, естественно, давно отошедшего от дел и уже не марающего руки кодом. Его задача — раздавать указания тем, кто ещё не дорос до архитектора, максимум — рисовать квадратики, соединять их стрелочками. Как строительный архитектор, который рисует, но ничего сам не делает.
Понятие «архитектор» уже сильно выхолощено. И поэтому я против этого термина, я больше за то, чем архитектор должен бы быть в нашей индустрии. Это лидер, ведущий разработчик, который сам пишет код, сам делает архитектурные решения, сам их реализует, проверяет, один или с помощью кого-то ещё, видит свои ошибки, чужие ошибки, переделывает это всё до того, как архитектура становится хорошей, выверенной, понятной, не содержащей ничего лишнего.
— То есть ты всё-таки занимаешься «архитектурой», но ещё и код пишешь? Мы тебя поймали, всё-таки архитектор!
— Всё-таки да, но здесь ещё важно, что нет одного человека с вот такой головой, который всё может предусмотреть. Архитектура — это командная игра. Архитектуру должны делать все те люди, которые делают проект. Есть один или несколько лидеров, которые принимают или не принимают какие-то решения, больше даже предлагают решения, а дальше уже команда в демократическом или консенсусном смысле должна эту архитектуру принять.
Поскольку у нас очень сложная техническая индустрия, один человек может очень легко ошибиться, не увидеть каких-то очевидных решений, сам себя загнать в какую-то ментальную ловушку. И тут очень важно, чтобы рядом был второй, третий, четвёртый человек, которые рассмотрят ту же самую проблему под немножко другими углами и предложат такие решения, про которые ты сам потом удивляешься «почему я до этого не додумался, это же очевидно, просто и понятно».
— Судя по тому, что я услышал, простота является для тебя важным инженерным принципом, ты сейчас два или три раза про это сказал. Я правильно тебя услышал?
— Да. Сложную архитектуру очень просто сделать. Как говорится, любая проблема может быть решена введением ещё одного уровня абстракции. А искусство и собственно сложность состоят в том, чтобы сделать сложную систему просто. Чтобы она содержала как можно меньше компонент. Потому что чем меньше в системе компонент, тем меньше число отказов. Получается более надёжная архитектура, более надёжная система, за ней надо меньше следить, она реже ломается, значит, она чаще приносит прибыль.
11 тысяч серверов
— Сейчас в Одноклассниках много тысяч серверов, я уже даже запутался, сколько. Называют цифры «9 500», «10 000», «11 000». Первый вопрос — сколько же их всё-таки, второй — зачем их так много, и третий — как это стыкуется с простотой?
— Сейчас (интервью записывалось в декабре 2016 — прим.авт.) их, наверное, ближе к 11 000. По большей части это связано с тем, что в Одноклассниках запускаются новые сервисы, и они требуют иметь под собой какие-то мощности — это раз. Во-вторых, нагрузка растёт и по старым сервисам. Допустим, по видео за последний год мы удвоили трафик, мы сейчас по просмотру видео вообще занимаем первое место в рунете. А видео — это очень ресурсоёмкий проект, он требует очень больших мощностей. Поэтому я думаю, что, скорее всего, где-то к 11 000, и, скорее всего, будем и дальше расти.
— А зачем так много машин, и как это стыкуется с простотой, которую ты декларируешь как принцип?
— Серверов много, потому что нагрузка большая. У нас в стране есть две социальные сети, ВКонтакте и Одноклассники. Сама по себе социальная сеть — это такая задача, где очень много связей между людьми, между системами. То есть её не получится шардировать по самой простой архитектуре shared nothing, когда у вас есть два сервера, и между ними ничего общего, они не знают друг о друге и работают индивидуально. С социальной сетью так не получится, потому что её предназначение — как раз связывать людей, соответственно, точно так же и сервера связываются внутри, чтобы гонять информацию туда-сюда. Поэтому, с одной стороны, эта задача не очень просто масштабируется, с другой стороны — это то количество серверов, которое для социальной сети нашего объёма, наверное, близко к необходимому минимуму. Допустим, у ВКонтакте серверов значительно больше, чем у нас.
— Ну, они у вас же, так понимаю, всё равно не на 100% загружены?
— Нет, не на 100.
— Как вы выбираете баланс между Throughput и Latency, между «загрузить машину по самые помидоры» и «оставить её разгруженной, чтобы она быстро отвечала на запросы»?
— Есть такое понятие, как «эффективное использование дата-центра». На текущий момент дата-центр у нас полностью «железный», то есть каждая задача работает на выделенном ей сервере или наборе серверов.
— В том плане, что нет виртуализации?
— Нет никакой виртуализации или чего-то такого. Соответственно, такой дата-центр, с одной стороны, недогружен, а с другой — способен наиболее быстро отвечать на запросы, и при этом наиболее предсказуем, потому что на машине, кроме одной задачи, ничего не работает. То есть ничто не может помешать этой задаче что-то сделать.
— Диагностика проще?
— Проще диагностика, поиск каких-то аномалий, поломок. Мы пошли по пути наименьшего сопротивления: нужно было решать и много других задач, не только эти, поэтому ставили всё больше железа.
— Место в дата-центрах вокруг Москвы — оно же не резиновое, да?
— Место не резиновое, мы, наверное, уже в 2017-м или в 2018-м выберем все мощности, которые есть сейчас в дата-центрах…
— Ох же весело вам будет.
— Весело будет, но мы уже сейчас готовимся как раз к тому, чтобы повысить утилизацию дата-центров.
— То есть запасы есть?
— Запасы есть, и сейчас у нас делаются технические решения, которые позволят достаточно безопасно запускать несколько задач на одной машине. То, что принято называть «облаком», что-то типа такого. Двигаемся в эту сторону.
Отказоустойчивость
— С внешним трафиком всё понятно: видео колоссально растёт, поэтому и общий колоссально растёт. А внутренний трафик? Когда есть такое количество машин, это же порождает какое-то дикое количество внутреннего трафика — не знаю, в десятки, в сотни или в тысячи раз больше, чем внешнего. Как вы вообще эту задачу решаете? Как вы управляете трафиком между дата-центрами — нужны же огромные мощности, чтобы туда-сюда гонять данные?
— Вот здесь ты вступаешь в ту область, к которой я последние лет, наверное, восемь не имел никакого отношения. Этим занимается отдельная команда, которая называется «сетевики», я достаточно далёк от них.
— Хорошо, давай попробую в таком ключе переформулировать свой вопрос. Дата-центров у вас три или четыре, даже не знаю...
— Три с половиной!
— Три с половиной. Как происходит разделение данных и нагрузок между этими дата-центрами, по каким принципам это было сделано?
— Дата-центра у нас три для того, чтобы мы выдерживали отказ любого из них. И наша цель в том, чтобы, во-первых, мы могли выдерживать такой отказ, и, во-вторых, пользователи бы при этом ничего не заметили. Многим кажется, что отказ дата-центра — это какая-то очень редкая вещь, бывает буквально раз в столетие. Так вот нет! Отказы дата-центров регулярны, по своему опыту могу сказать, что приблизительно раз в три месяца один из них отказывает. Прогнозировать, на сколько он лёг по времени — на 15 минут, на час, на два — мы не можем. А каждый этот час стоит нам очень много денег.
— А почему так часто отказывают, что это — какие-то ЧП, или?..
— Разные вещи. Бывают ЧП, бывает человеческий фактор. Допустим, совсем недавно в одном из наших дата-центров целиком вылетели два зала, это много-много-много машин. Из-за того, что оба луча питания отвалились. При этом все наши дата-центры — самой высшей категории, есть дизель-генераторы, UPS’ы и т.п. Но вот в программном обеспечении генераторов закралась ошибка, и при отключении дата-центра они тупо не завелись. Там были какие-то аномалии в электрической сети, они посмотрели на эти аномалии и решили, что не хотят заводиться. Аккумуляторы продержались 10 минут. А дальше всё.
— И как, собственно, на всё это отреагировал портал?
— Портал отреагировал отлично, никто ничего не заметил. Это было буквально месяц назад, но в новостях не было ничего вроде «Одноклассники лежат», «#окживи», всё прошло хорошо. Разобрались в течение двух часов, включили питание, запустились.
— Была ли какая-то деградация по функциональности, или обошлось без этого?
— Абсолютно незаметно прошло. Нам немножко повезло, если бы вылетели другие два зала, то тогда была бы деградация по функциональности. Но мы двигаемся в том направлении, чтобы вылет дата-центра вообще никак не влиял на пользователя.
— А какими путями достигается это повышение надёжности сервиса? Как мне сделать так, чтобы моя система из трёх машин, которые лежат по разным дата-центрам, работала стабильно и не деградировала?
— Основная идея здесь, естественно, в резервации. Понятно, что мощности должны быть выбраны так, чтобы вылет одной трети этой мощности позволил оставшимся двум серверам тянуть эту нагрузку. И опять же, дело не только в нагрузке, но и в доступности данных. Если у вас вылетел дата-центр, там лежали какие-то важные данные, и сейчас они недоступны, то в лучшем случае у вас происходит отказ в функциональности, потому что не можете достучаться до этих баз данных, а в худшем случае вообще ничего не работает.
У нас в каждом дата-центре имеется реплика данных, на Западе это называется термином «replication factor 3», то есть каждый из дата-центров имеет свою реплику. Когда мы меняем данные, записываем во все дата-центры, во все три реплики, и дожидаемся ответа от двух самых быстрых, потому что третья может не работать в данный момент. И мы считаем, что данные записаны, как только получили два подтверждения от двух самых быстрых.
По такому принципу сейчас построены все хранилища данных в Одноклассниках, кроме Cold Storage — это такое специальное хранилище, которое хранит большие блобы — для видео, для фоток, для музыки.
— А почему так? Это дорого?
— Да, replication factor 3 всё же подразумевает, что у нас три копии данных, а видео у нас очень быстро растёт, там уже петабайты-петабайты, и хранить их в трёх копиях — это достаточно дорогое удовольствие. Но, чтобы не терять надёжность, всё равно используется резервация, и у этой системы replication factor 2.1. Грубо говоря, это RAID 5, собранный не в рамках локальной машины, а в рамках распределённой системы. То есть, если в RAID 5 репликами служат локально установленные диски, то в данном случае эти диски распределены по разным дата-центрам.
— И если что-то из этого вылетает, то идёт распределённое восстановление?
— Да.
Во что играют админы
— Это же вообще известная проблема, что после замены вылетевших нод или восстановления дата-центра надо актуализировать данные, даём туда много трафика, все наши мощности по трафику съедаются, и так далее. В эту сторону что-то сделано, это процесс контролируемый?
— Здесь должно быть достаточно работы не только программиста, но и администратора системы. Поэтому, чтобы понимать, когда при восстановлении что может упасть, мы устраиваем учения и тестирование аварий. Это очень интересная игра, которой периодически занимается отдел администрирования.
— А как это выглядит?
— Какой-то человек назначается режиссёром этой аварии, и он придумывает сценарий: что происходит, какие симптомы. А остальные не знают заранее, что же будет происходить. И он начинает учения: говорит, что отключилось то-то, зажглись такие-то лампочки, мониторинг говорит то-то, на графиках это. А участники пишут, что они делают и как эту ситуацию будут исправлять.
Это теоретические учения, а есть ещё практические. Когда мы знаем, что cold storage должен выдерживать падение трети данных, мы выбираем какой-нибудь день (естественно, сначала такие тесты делаются обычно в моменты наименьшей нагрузки, например, ночью). Дата-центр или машины в нём полностью выключаются или партиционируются по сети, в зависимости от того, какой сценарий мы отрабатываем, потом включаются, и смотрим, что происходит.
— Это вообще довольно страшно — на боевом продакшене что-то отключать. Как вы преодолели этот страх? Я знаю несколько энтузиастов, которые говорят «вот сейчас мы на продакшене поэкспериментируем», а им говорят «нафиг, нафиг, не трогайте наш продакшен». Вам это тоже не сразу далось?
— Страх, что ты что-то сломаешь на продакшене, проходит приблизительно после десятого раза, когда ты что-либо сломал на продакшене. Система сама должна реагировать на то, что её сломали, правильно. То есть с минимальным количеством спецэффектов для пользователя.
— Расскажи об этом, пожалуйста. Что такое «правильно реагировать» и «неправильно реагировать»?
— Неправильно реагировать — например, давным-давно, если у нас вылетал один из SQL-серверов, то портал не работал. Показывал колесо «Извините, до свидания, заходите попозже». Это было в самом-самом начале Одноклассников, год 2007-2008. Серверов было 16, они не так часто вылетали, и их достаточно быстро заводили назад и всё было хорошо. Когда их стало 64, а потом 128, а потом 256, понятно, это стало происходить всё чаще, и такой уже вариант не работал. Он просто плохо влиял на бизнес.
Поэтому стали думать о failure tolerance системы, то есть об устойчивости к сбоям. Тогда в интернете об этом не было вообще никакой информации. Failure tolerance — это то, что мы сами внутри себя придумали и начали реализовывать. Идея была достаточно простая: если сервер не работает, то мы не можем оттуда прочитать данные. Если эти данные нужны нам для того, чтобы что-то по ним отобразить, то и фиг с ним, мы пропустим.
Пример. Возьмём граф друзей. В обычной ситуации у вас 32 друга. 16 партиций — по 2 друга на каждую. Одна партиция отказывает, двух друзей мы прочитать не можем. В этой ситуации мы покажем только 30 друзей и надпись: «Возможно, отображаются неполные данные». Потому что мы знаем, что с одного из шардов мы не смогли прочитать данные.
По большому счёту, пользователю может быть в конкретный момент наплевать на этих двух друзей, тем более, что из-за вылетевшей партиции они сейчас всё равно не могут работать. Но при этом юзер может продолжать работать с остальной информацией. Это то, что относится к рендерингу данных, к их отображению на экране. И наоборот, если мы хотим изменить данные, которые лежать на отказавшем в данный момент сервере, то такую транзакцию выполнять нельзя, она отваливается с сообщением «извините, сейчас не смогла, может быть, попозже».
Таким образом, из-за одного отказавшего сервера страдает очень маленькая часть функциональности, требующая изменения данных на этом сервере. А всё остальное работает. Вы не можете просмотреть всех своих друзей в соцсети (этих двух вы временно потеряли), вы не можете раздружиться с ними в данный момент, но зато вы можете делать в соцсети все остальное — читать ленту, постить фоточки, обсуждать что-то в комментариях, и так далее. Это называется «изоляция отказа». Мы изолировали отказ этого сервера ценой деградации полноты данных.
— А если весь кластер друзей отвалился: вирус или что-то такое?
— Не обязательно вирус. Весь кластер может отвалиться очень просто: люди могут положить, баги могут быть, кто-то неаккуратно захватил lock на всю таблицу, причин может быть очень много. Баги в самом софте баз данных, сеть отвалилась — кластер полностью недоступен, его вообще нет. В этом случае нам не остаётся ничего, кроме как деградировать уже функционально, то есть мы полностью убираем часть функций друзей.
— А что пользователь видит при этом?
— Пользователь видит заглушку: на соответствующем разделе будет показано, что сейчас функция недоступна, заходите попозже, но остальные разделы сайта будут работать, если они не затронуты этой аварией. Такой режим может включаться и автоматически, и вручную. Администратор тоже может отключить любую функцию сайта в любой момент.
Почему отказались от SQL-серверов
— Ты говорил про Microsoft SQL Server, которых у вас было 16, 32, 64 инстанса и так далее. Как оно вообще в таком количестве дружит друг с другом? До сих пор вопрос скалируемости баз данных, репликации, шардирования остаётся открытым. Люди говорят, что даже самые навороченные системы типа Oracle могут скалироваться до 10 машин, а дальше, как правило, начинается беда. Что сейчас в Одноклассниках с MS SQL-серверами?
— С MS SQL-серверами в Одноклассниках всё очень просто: они выводятся из эксплуатации. Мы по возможности отказываемся от них.
— А в пользу чего? Какие системы заменяют SQL-сервера? Что примерно на них было, и на что заменяется?
— На них были обычные бизнес-данные, которые требуют ACID-транзакций. Данные о пользователях, дружбах, деньгах, фотках (не блобы, а метаинформация), всякие классы, комментарии, сообщения — всё подряд. SQL-сервер — нормальная парадигма, она хорошо работает, на ней удобно быстро писать код. Мы так и делали — быстро писали код, пока в какой-то момент не стало ясно, что парадигма SQL-сервера архитектурно не укладывается в модель отказа дата-центра.
— Расскажи про это чуть подробнее.
— Есть SQL-сервер. И он сделан так, что это single-master, то есть одни данные изменяет только один конкретный инстанс сервера. Есть какие-то процедуры, которые переключают мастер, если первый отвалился — leader election, failover… Я уже начал подзабывать эти термины. Отказоустойчивый кластер можно построить несколькими способами. Классический энтерпрайзный вариант: у вас есть shared storage, два сервера смотрят в него по оптической связи, и если один отказывает, то другой берёт управление — вот и вся схема. Но во-первых, сами железки стоят очень дорого. Во-вторых, эти два сервера находятся рядом с shared storage, то есть в принципе не могут находиться в другом дата-центре. И если отказывает дата-центр, в котором эта железка стоит, то выходит, что кучу денег вы потратили просто так. Эта схема не дает никакой отказоустойчивости в такой ситуации.
Есть другая схема, когда master в одном дата-центре, slave в другом, и выполняется…
— Cross data center replication.
— Да-да. При коммите сначала делается запись в slave, и если slave закоммитил и всё хорошо, то только тогда мастер говорит системе, что закоммитил. В этой схеме тоже не всё хорошо. Когда у вас немножко притормаживает slave, master перестаёт подтверждать коммиты. Или если что-то случилось с сеткой. Такая транзакция работает со скоростью самого медленного сервера плюс latency по сетке.
Собственно, вот основные проблемы. Есть ещё мультимастер, но это отдельная песня, очень сложная и очень много конфликтов возникает. На наших нагрузках он вообще не работает, поэтому мы даже не рассматривали этот вариант.
Поэтому стало ясно, что такие классические ACID-базы данных не работают. Они не позволяют нам сделать такую отказоустойчивость, как мы хотим. Чтобы эту проблему решить, мы написали свою ACID-систему, которая распределяет данные по нескольким дата-центрам. Я про неё рассказывал года два назад на Joker — как она работает, основные её принципы. И сейчас мы с максимальной скоростью переносим все наши данные на эту систему.
— Мы добавим ссылку на тот доклад, но для тех, кто не сможет посмотреть его, ты можешь как-то базово описать, как вы решили в новой системе описанные проблемы?
— Во-первых, главное, что транзакция подтверждается, как только два самых быстрых из трёх реплик подтвердили, что они приняли транзакцию. Во-вторых, в качестве хранилища данных используется Cassandra. Она у нас уже давно используется и доказала, что это сейчас самое лучшее решение на рынке в плане отказоустойчивости, кросс дата-центровой репликации и так далее.
Далее, координаторы, которые управляют транзакциями, в нашей системе данными не владеют. Данными владеют только storage-ноды… То есть мы выделили отдельно transaction-координаторов и storage.
— Координаторы транзакций занимаются чем — логикой, отказами?..
— Логикой транзакций. На нём можно открыть транзакцию, составить её — ну, когда вы делаете insert несколько раз подряд, это составляет из себя транзакцию, он операции не запускает, а только складывает в память. И если вы, как клиент, который открыл транзакцию, что-то читаете из базы данных, то ваш запрос на чтение пройдёт через этот координатор. Координатор транзакций прочитает текущее состояние из Cassandra storage, наложит то измененное состояние, которое должно быть в рамках транзакции, которую клиент открывал, и отдаст её клиенту.
Таким образом, вы собственные изменения в транзакции видите, а соседние клиенты, или другие клиенты, или просто другие треды в пределах этого клиента идут напрямую в Cassandra storage, минуя transaction-координаторы, и видят состояние данных до начала транзакции. При коммите транзакшн-координатор вот так кворумно, в две головы из трёх, запишет эти данные и даст подтверждение о успешном коммите клиенту. И те клиенты, которые в транзакции не участвовали, начнут читать эти данные, как только транзакция была закоммичена. Таким образом мы и получили read committed. Поскольку координаторы транзакций не владеют данными, то переключения между ними получились очень простыми: если один вылетает, то другой начинает использоваться.
— В случае с базами данных бывают разные уровни изоляции транзакций. Почему read committed, везде ли read committed?
— В нашей системе поддерживается только read committed. В большинстве систем достаточно read committed на самом деле. Я видел мало систем, которые требовали serializable read, и очень мало людей, которые шли на read uncommitted по собственной инициативе. Мы во времена работы с Microsoft SQL Server использовали read uncommitted не потому что он такой хороший, а из-за производительности.
— Какие версии Cassandra у вас используются «в бою»?
— У нас сейчас используются три версии. Одна — старая-старая 0.6, она простая, как автомат Калашникова, там ничего лишнего нет. Она используется в качестве key-value хранилища, точнее, column family хранилища, скажем так. Если у вас ключ, а в значении у вас ordered map колонок со значениями. Это много где очень удобно. И работа с такими хранилищами происходит именно на низком уровне.
В более современных версиях Cassandra появилось такое понятие, как CQL: Cassandra Query Language, который как-то похож на SQL. На самом деле это, конечно, совсем не SQL, но нечто похожее, что облегчает людям порог входа в эту новую систему. Тут мы используем Cassandra 2.0. Почему мы выбрали 2.0 для перевозки SQL-баз на неё: грубо говоря, потому что там SELECT, и здесь SELECT. Для человека, который программирует прикладную логику, внешне очень мало что меняется. Он как там делал селекты, так и здесь делает.
В MS SQL мы не использовали join-ы: мы отказались от них, потому что на наших объемах они очень медленно работают. В Cassandra же join-ов просто нет.
— То есть данные сильно денормализованы?
— Естественно.
— Ты сказал про Cassandra версий 0.6 и 2.0, а третья версия какая?
— А третья 1.2. Была такая очень переходная версия, мы её взяли, попробовали в одной штуке, штука работает через пень-колоду, но как-то фурычит до сих пор.
Технический долг
— Итого, на продакшене у вас три разных версии Cassandra. Я знаю много людей, которые, когда будут смотреть или читать наше интервью, в этом месте поднимут палец и скажут: «так, у вас, ребята, технический долг, не хотите ли вы его как-то начать исправлять?» Соответственно, не является ли факт использования трех разных версий одного продукта техническим долгом? Если нет, то почему, а если является, то почему не исправляете?
— Для того, чтобы зайти на эту тему, я хочу рассказать тебе о замечательном «Правиле большого З», которое используется у нас в компании. «Большое З» означает «Зачем?». То есть любое техническое действие, в том числе перевод версии софтины X с 1.0 на 2.0, должно отвечать на этот вопрос. Какие задачи это решит? Решит ли это какие-то реальные проблемы? Реальные проблемы — это тоже отдельная интересная вещь. Мы считаем проблему реальной, если она упирается в деньги, во время или в людей. Любая реальная проблема упрётся в эти три кита IT-индустрии. Технический долг… Что такое технический долг?
— Наверное, так: это набор действий, которую нужно будет сделать в будущем для того, чтобы решить какие-то проблемы. То есть у нас намечаются какие-то проблемы, но мы говорим, что сейчас ими не будем заниматься, а будем решать их потом. И проблема с техническим долгом, как я понимаю, в том, что это «оно» когда-нибудь наступит.
В данном случае, если среди Java-программистов сейчас можно найти людей, которые что-то знают про Cassandra 2, то найти людей, которые что-то знают про Cassandra 0.6, довольно трудно. Если кто-то уйдёт в отпуск, кто-то будет в командировке, кто-то будет давать мне интервью, а с этой штукой что-то случится, то довольно трудно будет найти того, кто это сможет ее быстро починить.
— В данном случае вопрос с людьми решается совершенно другим способом. У нас каждую из ключевых технологий обычно знает несколько людей, нет какого-то одного человека. Более того, мы (в том числе и я) специально стимулируем других людей, даже прикладных программистов, наткнувшихся на баг, допустим, в той же Cassandra 0.6.
Как всё это происходит в плохой конторе? Все приходят к одному человеку, который отвечает за Cassandra 0.6, и говорят: вот я нашёл баг, вот я завёл тикет в JIRA, написал там steps to reproduce, пофиксите его, пожалуйста, мне срочно нужно. Я пока пойду позанимаюсь другими делами, а вы как-нибудь пофиксите и принесёте мне потом всё на блюдечке с голубой каёмочкой.
У нас так редко происходит, чаще всего происходит так, чтобы нашёдший это человек понял, в чём этот баг, пофиксил его, закоммитил, команда Cassandra 0.6 внутри компании посмотрела на этот код, сделала ему код ревью, если всё нормально, код идёт в мастер, человек убеждается, что в его конкретном кейсе он пофиксил баг, молодец.
— А что происходит с другими инстансами? Предположим, человека работает в команде подарочков, а эта Cassandra 0.6 используется ещё в других сервисах. Другие будут обновляться?
— Если это критичный баг, то команда Cassandra 0.6 доведёт до сведения всех пользователей, что такой баг есть и его желательно фиксить. Проблема в любом случае дойдёт до людей, которые занимаются Cassandra. Но поскольку его фиксят люди, которые на него наткнулись, во-первых, у них больше мотивации это сделать, а во-вторых, они за счет такой работы узнают потроха своего сервиса, как всё на самом деле у них работает. Программист пофиксит один баг, второй, третий, а на четвёртый мы ему не нужны, я не нужен — он уже во всём может разобраться самостоятельно.
— А не страшно было брать в продакшн что-то, имеющее версию 0.6, от чего в своё время, я так понимаю, отказался Facebook? Как вообще такое вам пришло в голову? Часто говорят, что энтерпрайзы не берут библиотеки до выхода версии 1.0.
— Эта мысль пришла в голову, исходя, опять же, из «Правила большого З». Была конкретная проблема: тогда в компании не было хранилища, которое бы, во-первых, было отказоустойчивым, во-вторых, выдерживало бы падение дата-центра, и было бы достаточно быстрым.
— Какой это был год?
— Примерно 2010-й. Мы тогда работали по большей части на Microsoft SQL Server и на самодельных NoSQL-штуках, построенных по master-slave принципу и носивших смешное название «Бармалей». Бармалеи очень часто отказывали, всё-таки как хранилище назовёшь, так оно и полетит ;-). Их всё время нужно было восстанавливать, у нас для этого среди администраторов был специально выделенный человек — специалист по подъёму Бармалеев. Он не спал каждую ночь и что-то с ними делал: то бэкапы, то дамп базы, то туда, то сюда. Это занимало у него очень много времени, он даже похудел немножко. На тот момент проблема была очень животрепещущей, и стало понятно, что дальше так невозможно.
— Что было на рынке на тот момент?
— Ничего. Тогда было два решения — Voldemort от компании LinkedIn, они недавно открыли его в опенсорс, и второе, собственно, Cassandra. По-моему, когда мы в первый раз пришли на неё смотреть, была версия 0.5, которую буквально только что выбросил Фейсбук. Мы попробовали одно и другое, и для нас больше подошла именно Cassandra. Дальше мы её взяли и начали доводить до ума, потому что естественно, что стоковая Кассандра, которая есть в опенсорсе, мягко говоря, не работает.
Дальше в течение нескольких месяцев мы делали разные тесты, по-разному пытались заставить её работать, что-то переписали, какие-то части выкинули. Там осталось очень мало от оригинальной Cassandra. Кстати, эта Cassandra 0.6 есть у нас на GitHub, мы просто её не афишируем, но я периодически даже коммичу туда что-то — именно на GitHub, хотя у нас по большей части разработка делается с внутренним репозиторием. Просмотреть на её имеет смысл тем, кому нужен «просто column-family storage» — это неплохой вариант.
— Cassandra была настолько сырая на тот момент, когда Фейсбук её выкинул?
— Да, она была очень сырой, там кое-где сильно текли концепции, с тех пор её, конечно, много доводили до ума. Тут, конечно, большое спасибо команде DataStax.
— А современные версии, 2.0 и выше, уже продакшен-quality, или там тоже всё печально?
— Мне сложно говорить о совсем последних версиях, 3.0-ветке. А про 2.0 могу сказать только то, что когда её выпустили, мы внутри себя доводили её до продакшена, чтобы она как-то работала и не падала, где-то около полугода.
— Это связано с тем, что она сырая, или у вас просто какие-то специфические задачи?
— На тот момент она была сильно инновационной, они переписали внутри много частей и недотестировали. Но с тех пор утекло очень много воды, я знаю, что тестирование у них сейчас гораздо лучше построено.
— А в апстрим вы им что-нибудь возвращали?
— Да, конечно.
— Много?
— Когда я в последний раз считал, у меня было около 20 тикетов, которые я в стрим возвращал… Очень много коммитили именно в 2.0.0, когда она вышла. Мы начали с ней возиться, когда она была ещё релиз-кандидатом или бетой, и в том состоянии она у нас под продакшен-нагрузкой продержалась приблизительно 5 секунд.
— А вы отправляли просто баги, или прямо с багфиксами, или по-разному?
— Только фиксы. Когда вы работаете с опенсорс-проектом, мне кажется плохим тоном репортить баги без фиксов. Вы этим людям не платите, пользуетесь этим кодом, а если пользуетесь, то верните им хотя бы часть стоимости своим трудом.
Open source
— Очень интересная тема — опенсорс. Мы о нем говорили в интервью с Барухом Садогурским, у нас там всплывала история с Одноклассниками, правда, не про Cassandra, а про патченный OpenJDK… Очень мало кто реально понимает, что опенсорс — это не только про «читайте код», не только про какую-то бесплатность (free software и open source часто идут бок о бок), а ещё и про то, что я могу сам отловить баг, пофиксить, и если хочу, то ещё и вернуть в upstream. Мне удивительно, что с этой позиции очень мало кто опенсорсом занимается.
Насколько активно используется опенсорс в Одноклассниках? Насколько часто происходят коммиты в Upstream чужих опенсорс-проектов или подобного типа взаимодействия?
— Сложно сказать, насколько много. Считать ли Guava опенсорс-решением, которое мы используем? Это больше библиотека. Но, допустим, да, Guava мы используем, Андрей как раз находил там прекрасные баги про класслоадеры, репортил их и предлагал решения. Но здесь сильно зависит от команды, которая является коммитером опенсорса. Некоторые команды в принципе не дают другим людям участвовать в разработке.
— Представим такую ситуацию. Вот есть у меня большой продакшен на 11 000 машин. Вдруг в моей Cassandra обнаруживается какой-то адский баг, и всё, отваливается каждые 3 минуты. И если у меня не опенсорс-решение, у меня нет шансов. Я иду в саппорт вендора, начинаю что-то выяснять с кем-то, заводить тикеты, но шансов, что оно быстро решится, практически нет, и на самом деле я в заднице. В случае, когда используется опенсорс-продукт, есть ли ощущение, что опенсорсность даёт возможность всё это фиксить, и часто ли это происходит? Часто ли обнаруживаются в опенсорсных тулах какие-то дыры, и что можно вообще сказать о состоянии современного?
— Я могу сказать, что у нас в компании, если мы выбираем какое-то решение для продакшена, оно обязано быть опенсорсным именно из тех соображений, что оно сломается — и мы знаем, что сломается, вопрос только во времени, когда это произойдет. И мы должны мочь это пофиксить. Быстро, сами, у нас должен быть человек, который может это пофиксить. Соответственно, из всех опенсорс-решений мы берём только те, которые можем пофиксить сами, то есть оно должно быть написано на языке или технологии, которые мы понимаем.
Если такое опенсорс-решение есть — замечательно, мы его берём, пытаемся использовать, фиксим баги по ходу, если какие-то фиксы могут помочь всем остальным, в апстрим закидываем, и так далее. Если такого решения нет, то мы пишем сами, тогда это будет чистый closed source, таких решений у нас тоже очень много. Часть из них сильно завязана на инфраструктуру, как, например, система статистики — это огромная система, в неё входит очень много компонентов, они должны как-то взаимодействовать, туда вложено очень много труда. Это closed source, открывать его не имеет смысла, потому что никто не сможет этого построить или потратит очень много времени.
Netflix выпускает в опенсорс какую-то часть своей статистики, например, у них есть Atlas, но надо понимать, что это, скорее всего, только очень маленькая часть. Я не могу знать полностью, но если сравнивать то, что есть внутри у нас и что открыл Netflix, у них должен быть какой-то аналог того, что есть у нас. Так что Netflix тоже открывает далеко не всё и только то, что обычные люди могут применить.
В этом году мы рассказывали про смарт-мониторинг, про систему, которая сама автоматически детектирует аномалии среди тысяч серверов, и было много вопросов «а давайте вы её в опенсорс выложите». Но это невозможное действие, просто потому что она завязана и на систему статистики, и на сбор статистики, и на процессы, которые у нас вокруг этой статистики налажены.
— Это хороший вопрос, потому что мы как-то разговаривали с Андреем Паньгиным про библиотеку one-nio, которой он занимается. И зашла речь о том, чтобы не просто выложить ее на GitHub, а построить вокруг этого что-то ещё. И выяснилось, что это огромная работа. Это создание wiki, туториалов, вычищение всех «однокласснико-зависимых» компонентов, написание тестов, описание разнообразных юзкейсов. Помимо этого, ещё должны люди ездить с докладами по конференциям, писать статьи и так далее.
То есть выяснилось, что объём работы совершенно колоссальный. И если четыре года назад, когда Андрей начинал рассказывать про one-nio, зацепиться за это и начать делать из этого OpenSource, наверное, имело бы смысл, то сейчас подобных решений на рынке появилось довольно много и, пожалуй, этот момент уже упущен.
И у меня возникло ощущение, что вся эта опенсорсность нынешняя, Netflix и всё такое — это для компании ни фига не бесплатно, это в реальности огромное вложение. Ты думал что-нибудь из своего кода когда-то опенсорсить? Ты рассказывал про свою версию Cassandra, но опять же упомянул, что это довольно сложно использовать. А были ли в компании мысли взять хороший крутой кусок кода, решающий интересные задачи, которые мало кто решает, попытаться это заопенсорсить и что-то вокруг этого сделать?
— Мысли всегда есть, тем более, что внутри много интересных кусков кода, некоторые идут совсем вразрез с тем, как принято программировать на Java, некоторые решают довольно интересные задачи весьма оригинальным способом. Весь вопрос упирается в «Зачем?», в деньги и в людей. Потому что туда нужно вложить достаточное количество денег, времени и людей, которые всё это будут делать. А ответ на вопрос «Зачем?» должен как-то это обосновывать, и мы не нашли для себя такого ответа. На самом деле это бы означало, что Андрей Паньгин вместо того, чтобы заниматься развитием one-nio remoting (у нас сейчас есть ещё одна проблема с remoting, мы подошли к очередной границе наших технологий, и нам нужно его развивать), пошёл бы заниматься маркетингом, туториалами и one-nio, и через год мы получили бы большие проблемы на production из-за отсутствия необходимого развития.
— Я как-то попытался ему помочь, сидел, всё анализировал, но это, конечно, год работы, чтобы это нормально сделать. Несколько месяцев точно, в это надо глубоко залезать. Всякие маркдауны сделать и сгенерить документацию — это фигня, а...
— Там есть работа чисто по оформлению, а есть работа по наработке тех же примеров использования.
— И вот в это я упёрся. Я посмотрел, как это используется в компании, как Андрей использует, какие-то конкретные примеры. Но чтобы это привести к состоянию, когда кто-то другой реально может брать и юзать — мне показалось, что я как инженер это не вытяну, или вытяну, но потрачу столько собственного времени и времени того же Андрея… Потому что это же банально high-performance вещи, и в них даже банальные рефакторинги могут стоить перфоманса. Это просто нерешаемая штука.
— Про перфоманс — да, мы тут недавно с Андреем на ревью где-то полдня над одним из кусков one-nio решали вопрос, что лучше в конкретном месте: Long.reverseBytes() или XOR. Делают они абсолютно одинаковые вещи, но…
— А теперь представь, что я прихожу туда и говорю «Андрей, тут надо зарефакторить». Андрей, естественно, тут же скажет, куда мне пойти, и будет совершенно прав, потому что понятно, что я в этом разбираюсь гораздо хуже него.
Как готовить Big Data
— Сейчас очень популярны истории вокруг Big Data, Smart Data, Data Science и всего вот этого. В каком виде это есть в Одноклассниках и как это выглядит?
— В компании есть команда Data Science, которая занимается анализом и построением математических моделей всего, что угодно. Началось это всё из задачи в музыке. Там была очень простая задача: есть куча пользователей, они грузят кучу треков, в этих треках в тегах внутри иногда что-то написано, иногда не написано, иногда один и тот же трек с разными тегами грузится. Из этого разнообразия файлов нужно было создать каталог: кто есть исполнители, какие есть альбомы, объединить в альбомы, какие-то треки включать в этот каталог, чтобы красивенько было, какие-то не включать. И сделать из набора данных красивую конфетку. С этого у нас началась вся система Data Science.
Потом она стала развиваться, в музыке появились система рекомендаций треков, пожанровое радио— это были первые шаги. Дальше мы эти рекомендации расширили, стали рекомендовать группы для пользователей.
Я вспомнил смешной случай. В те времена, когда мы это запускали, кажется, году в 2011-м, такого каталога не было на user-generated content. У ВКонтакте всё было просто списком, у Фейсбука вообще ничего не было и до сих пор нет, про Spotify никто не слышал, был разве что Last.fm. То есть этот каталог и персонализация музыки были мало изучены, мало у кого это было, и какой-то человек твитил: «Ха, я захожу на Одноклассники, смотрю популярные треки, а там всё больше “Голубые глазки”, Стас Михайлов, ха-ха-ха». Мы очень долго смеялись над этим человеком, так как ему показывали специально для него рекомендованные треки, исходя из того, что он слушает.
Возвращаясь к рекомендациям — сейчас уже много где эта система используется, в том числе «Умная лента» основана на этих технологиях. Фильтрация, ранжирование, большой кластер стримингового анализа и не только он. Используется совсем разный анализ.
— Это больше инженерная задача или научная?
— Такие штуки всегда на стыке: это и инженерная задача, и научная, и продуктовая. Мало показать нужный контент, нужно ещё этот контент привлечь, чтобы его потом показать. Здесь работает не только команда, которая занимается рекомендациями, но и инженеры, которые отвечают за latency технической реализации, и продуктовые менеджеры.
— Я много слышал, что людей, которые разбираются в Data Science, мало. В основном какие-то бородатые хипстеры бегают и машут руками вокруг этого. И, во-вторых, если есть люди, которые что-то реально в этом понимают, это довольно академические люди, а у таких людей бывают проблемы с продакшеном, когда это всё надо заводить в кластер и строить вокруг этого боевую систему. Что происходит в Одноклассниках с этим?
— Мы бы не запустили систему, если бы она не выдерживала нагрузки. Естественно, что люди, которые сейчас это запускают, понимают в нагрузках и продакшене.
— То есть это очень специальные люди?
— Здесь важно понимать, что один человек редко способен принимать все возможные технические решения. Это опять же архитектурный вопрос, а архитектура — это командная игра, в эту команду входят и учёные, и инженеры, и каждый со своей стороны привносит своё, предлагаемые технические решения. Таким образом всё это и работает. Ну и плюс, конечно, должен быть плавный запуск.
Как выкатывать фичи на десятки миллионов пользователей
— Что такое плавный запуск?
— Когда какая-то фича выкатывается в Одноклассниках, то, во-первых, она выкатывается в выключенном состоянии. Когда делается апдейт физических серверов, эта фича выключена. Она никак не должна поменять поведение сайта. Потом человек, который эту фичу программировал, начинает её постепенно включать, начиная с небольшого количества пользователей.
— Небольшое количество — это сколько процентов?
— Обычно это зависит от самоуверенности человека. Обычно это начинается либо с одной партиции (то есть 1/256 пользователей), либо с одного сервера, либо по географии берётся небольшая по числу пользователей страна. Если работает хорошо, то включается больше и проверяется на основании той же самой статистики.
— Это общепринятая в целом практика. Но система большая, если ты включил какую-то фичу на одну 256-ую, то получается, что на продакшене работает одновременно две версии (а может, и больше) одного и того же. Как оно вообще дружит друг с другом?
— По-разному. В зависимости от того, что за фича.
— Давай я тогда переформулирую вопрос. Приходится ли тратить дополнительные ресурсы, усилия на то, чтобы решать проблему «сожительства» разных версий фич на продакшене?
— Конечно. Но у нас нет другого выхода. Когда-то давно процедура апдейта выглядела как бой с конями в темноте. Выкладывали новую версию на сайт, вся свора людей заходила туда, в логах валились эксепшены, что-то не работало, активность просела, здесь упало, здесь повысилось, всё непонятно, а надо быстро фиксить. Это всё было в авральном режиме. В конечном итоге стало понятно, что так жить дальше нельзя, и придумали систему с постепенным вводом фичи.
— Это же целая инфрастуктура с включением, рубильниками, партициями, чёрт-те чем. Она требует каких-то специальных навыков от человека, который всё это пишет, или у него есть какие-то чёткие инструкции, что и как он должен делать?
— Обычно тем, что включает эксперименты, занимаются люди с допуском работы на продакшене. Допуск работы на продакшене означает, что человек прошёл некий инструктаж, как надо работать на продакшене и как не надо. Ему объясняют все эти вещи про эксперименты, про то, куда смотреть, как нужно плавно включать, что делать, если что-то пошло не так. А дальше он сам включает свою фичу, смотрит на всё это и разгребает результаты.
— То есть от и до, от написания до внедрения.
— Да. Это очень интересно, это мотивирует людей — видеть, как их код работает. Это быстро приводит людей к пониманию, как не надо делать. Каждый из ведущих программистов точно хоть раз, да ронял продакшен. Полностью. Но за одного битого дают двух небитых, и все ведущие программисты очень аккуратно включают свои эксперименты, потому что прекрасно понимают, что, как и где может сломаться и какие будут последствия.
Автор: JUG.ru Group