Highload-2012: Отчёт Виталия Филиппова — различия между версиями
(Новая страница: «Highload — «конференция разработчиков высоконагруженных систем» — пожалуй, самая распиаре...») |
(нет различий)
|
Версия 20:57, 31 октября 2012
Highload — «конференция разработчиков высоконагруженных систем» — пожалуй, самая распиаренная из Бунинских конференция. Проходила 22-23 октября 2012 (понедельник и вторник) в конференц-центре гостиницы Radisson Славянская (м. Киевская).
Общие замечания:
- Конференция полностью разработческая, число менеджерских тем стремится к нулю.
- Что приятно, число виндузятников на конференции также стремится к нулю — на ноутах у всех либо мак, либо линукс, причём соотношение где-то 50 на 50.
- Было некоторое количество иностранцев с докладами, но они в основном как-то растекались мыслью по древу. Говорят, Bruce Momjian очень хорошо вещал, но я его, к сожалению, пропустил.
- Уровень как докладчиков, так и презентаций, вполне приличный, пусть и не идеальный.
- В раздатке дали книжку с частью содержимого хайлоадов за 2010 и 2011 года. Я как раз пропустил то ли обе, то ли только 2011 :) пусть там не всё и вообще непонятно, по какому принципу выбирались доклады, тем не менее — наконец-то что-то полезное в раздатке :)
- Кормили неплохо. Жалко, бутербродиков в кофе-брейках не было :)
- Билет стоил (!!!) 21000 рублей. Что и говорит о степени распиаренности конференции.
- В этом году нагнали совершенно дикое количество народа — например, в первый день в первом зале было совсем всё печально. Сидели разве что не у друга на головах, плюс ещё стояли в проходах, выглядывая друг у друга из-за плеча. Я сидел на полу. Это при том, что первый зал был сам по себе огромный, размером примерно как 2-3 стандартных потоковых аудитории.
- В конце Бунин продал с аукциона красные пенопластовые буквы «HL++», стоявшие в виде декораций на полу. За 16500 O_o. Да, поистине чудесное аукцион творит.
Содержание
- 1 День первый
- 1.1 Building and Packaging Highly Scalable Services for Maximum Market Penetration / Michael Toutonghi (Parallels)
- 1.2 Что делать со своим первым миллиардом? / Евгений Поляков, Антон Кортунов (Яндекс)
- 1.3 MySQL в Google / Ievgen Varavva (Google)
- 1.4 Цикл разработки, визуальный деплой, автоматизация и интернационализация / Михаил Буйлов (Mamba)
- 1.5 SPDY: быстрее на 146 % / Валентин Бартенев (NGINX)
- 1.6 Полнотекстовый поиск в PostgreSQL за миллисекунды / Олег Бартунов, Александр Коротков
- 1.7 Tricky SQL. Особые возможности SQL-диалекта PostgreSQL / Иван Фролков
- 1.8 Крадущийся сервер, затаившийся диод / Андрей Аксенов (Sphinx)
- 1.9 Использование очередей асинхронных сообщений с PostgreSQL / Илья Космодемьянский (PostgreSQL-Consulting.com)
- 1.10 Суперкомпьютеры сегодня и завтра: архитектура, проблемы, перспективы / Андрей Слепухин (Т-Платформы)
- 2 День второй
- 2.1 One Billion Notes as 'Small Data': Scaling Evernote through Horizontal Partitioning / Dave Engberg (Evernote)
- 2.2 Percona XtraBackup: экспертные возможности / Алексей Копытов (Percona)
- 2.3 MySQL Plugins — why should I bother? / Sergei Golubchik (MariaDB)
- 2.4 Proactive Web Performance Optimization / Marcel Duran (Twitter)
- 2.5 Adventures in Bug Hunting / Joseph Damato (Boundary)
- 2.6 Cервис рекомендаций на виртуальном Hadoop кластере / Роман Зыков (Wikimart)
- 2.7 Спасение 6 млн файлов в условиях полного Хецнера / Даниил Подольский, Дмитрий Симонов (Setup.ru)
- 2.8 Выжимаем из сервера максимум! Приёмы кеширования и передачи данных на Java / Андрей Паньгин (Одноклассники)
- 2.9 AddressSanitizer, или как сделать программы на C/С++ надежнее и безопаснее / Константин Серебряный (Google)
День первый
Building and Packaging Highly Scalable Services for Maximum Market Penetration / Michael Toutonghi (Parallels)
Мишель Тутонги — раньше работал сначала 10 лет в стартапах, потом 10 лет в мелкософте — писал ядро Windows 95. Ух ты! У Windows 95 было ядро! Он его писал и до сих пор жив! — прим.вред.
А теперь работает в Parallels и осуществляет там глубокий penetration рынка (судя по названию доклада) :) Однако, полезного содержимого в докладе было мало — что-то рассказывал про OEM/партнёров/прямые продажи, что-то про Parallels’овский стандарт APS… В общем, в моей голове как-то ничего не осело.
Что делать со своим первым миллиардом? / Евгений Поляков, Антон Кортунов (Яндекс)
Так хитро на самом деле был назван доклад Яндекса про Кокаиновое облако — платформу для облачных приложений (типа App Engine), которую они там у себя запилили и используют, и выложили в OpenSource на гитхаб под лицензией LGPL 3. Что очень кошерно =)
А под «миллиардом» на самом деле понимался миллиард не денег, а объектов данных.
«Сиськи и кокаин» (они были в докладе с пометкой «размер не имеет значение»).
Итак, составляющие кокаина:
- Elliptics — распределённое хранилище. Использует DHT, коммуникации каждый-с-каждым и различные движки для хранения. Пробовали:
- BerkeleyDB — была совсем беда-беда — всё билось и восстанавливалось очень подолгу, а то и не восстанавливалось вообще
- Tokyocabinet/kyotocabinet — получше, но тоже билось
- Потом написали один свой движок — EBLOB
- Потом ещё один и ещё лучше, на основе принципов HBase’а (который хорош) — Smack. Называли цифры 10000 на запись и 3000 на чтение, хз к чему они относились.
- Вспомнили POHMELFS, про который, когда его пытались запихнуть в стандартную поставку ядра, Торвальдс сказал «когда вы мне покажете, что это использует ещё кто-то, кроме яндекса, я это сразу закоммичу»
- Собственно Cocaine Cloud — облачная платформа, к которой можно подключать плагинами различные языки программирования. Сейчас есть C++, Python, Perl и в разработке JS. Также плагинами подключаются событийные движки (где-то десяток уже подключён).
- libcocainedealer :) — библиотека-балансировщик для подключения к облаку
- Grape — библиотека для реалтаймовой обработки данных в облаке. Не MapReduce, потому что долго — смысла нет перевычислять всё, когда можно не перевычислять всё.
- Wookie — кокаиновое демо-приложение — простой поиск
MySQL в Google / Ievgen Varavva (Google)
Евгений Варавва рассказывал про то, как в Гугле готовят MySQL, чтобы он был быстр и отказоустойчив.
Почему MySQL? Ответ: он быстрый и надежный, особенно с гугловскими патчами. Плюс ОЧЕНЬ распространённый, так что проблемы всегда можно погуглить :) Евгений так и сказал, зал очень радовался тому, что сотрудники Гугла тоже гуглят :) у них >100 пользователей MySQL, начиная с 2003 года и проектов Ads и Youtube.
Всё-таки естественно у MySQL есть и минусы:
- В нём плохо хранить неструктурированные данные.
- Мастер только один, так что производительность записи всё равно ограничена.
- Репликация statement-based, но это просто потому, что они не заюзали row-based. Она не то что в 5.5 актуальной есть, она и в 5.1 уже была.
- Репликация всегда однопоточная.
Что они делают с MySQL’ем? Как ни странно, довольно очевидное — нечто похожее мы пытались делать во vsem.ru, только там это делали во-первых на 3-ей версии, а во-вторых криво. А гугл сделал прямо:
- Есть N кластеров по M машин. В каждом кластере 1 мастер, который автоматически перекидывается при падении. Примерно секунд 15-20 занимает восстановление. В это время не будет доступна запись, но всё равно останется доступным чтение.
- Используется Semisync репликация. То есть, мастер перед подтверждением коммита ждёт подтверждения коммита от любого одного слейва, но не от всех. Так и данные не теряются, и работает быстрее.
- Как они решают, какой из слейвов сделать мастером? Ответ: у них есть патч, называющийся Group IDs — то есть глобальный по всему кластеру счётчик транзакций. Плюс есть отдельный сервис Decider, который на основе Group IDs ищет самый свежий слейв.
- Изменения схемы БД вносятся так: выводится из кластера один слейв, на нём применяются изменения, делается бэкап и дальше всё восстанавливается из бэкапа.
- Очевидно, что при этом на части серверов будет старая схема БД, поэтому обратно несовместимые изменения схемы и приложений у них не допускаются. Это они проверяют руками и методом пристального взгляда, плюс есть инструкция для программистов из других отделов.
Кое-что из этого находится в OpenSource:
- http://code.google.com/p/google-mysql/ - сам MySQL с патчами, версия пока что не самая свежая 5.1. Думают, на что переходить — новый MySQL? Новую MariaDB?
- http://code.google.com/p/google-mysql-tools/ - мелкие инструменты.
Но вот самого вкусного — готового кластера в том виде, в котором его используют они — в этих репозиториях не обнаружено :-(задал вопрос автору презентации по почте — он ответил, что есть надежда ожидать их версию в открытом доступе к концу зимы, а аналогичный скрипт есть в оригинальной 5.6: http://dev.mysql.com/doc/workbench/en/mysqlfailover.html - интересно, насколько он аналогичный, разве там есть group ids?
Цикл разработки, визуальный деплой, автоматизация и интернационализация / Михаил Буйлов (Mamba)
С записи хорошо поставленным голосом сначала сказали, что сейчас нам расскажут про деплой, а потом произнесли «Михаил, задеплойтесь на сцену» :)
Сначала они разрабатывали всю мамбу в trunk’е SVN’а. Проблемы очевидные:
- В транке код не боевой. То есть, в условиях постоянного внедрения доработок, часть из которых пока что не готова к проносу — никогда не боевой. При этом вообще не понятно, что выкладывать на ру. Плюс нет возможности сегментировать билд, то есть выкладывать сначала одну часть, потом другую.
- В транке код нестабильный. Но это пофиксили установкой системы Continuous Integration (Jenkins), которая гоняет тесты при каждом коммите и ругается на разработчиков, которые «ломают билд».
Дальше они очевидным образом перешли на Git. Вообще в DVCS’ах чувак явно не особо сильно разбирается, потому что произнёс фразу «нормально с ветками можно только в гите работать». Для тех, кто будет это читать, добавлю пометку — вообще-то гит — не единственная хорошая DVCS, а гитовые ветки — это вообще не ветки! Это грёбаные листья — не может лист быть веткой :)
Так вот, они перешли на Git и на разработку в ветках (Feature Branches). Очевидным образом напоролись на вероятность возникновения проблем слияния веток. Для их решения сделали отдельную простенькую веб-систему, в которой разработчики создают «заявки», указывают доработку и имя ветки, а система сама пытается мержить и проверять результат, и откатывать с возвратом разработчику на доработку, если что-то ломается. В частности, проверяются шаблоны сайта на отсутствие в них русского языка — у них там есть система локализации с «меташаблонами» и визуальным интерфейсом для переводчиков, а исходными ID сообщений служат их тексты на русском языке.
Если одновременно проносятся две сильно связанные ветки — обычно руками создаётся третья, являющаяся их объединением, и проносится цельно.
Перед деплоем производится заморозка — запрет на добавление новых заявок. Всё тестируется и вываливается на бой.
Ещё рассказал про то, как надо переключать версии кода при деплое на боевых серверах, «если у вас > 1 одновременного запроса»:
- Тупо копировать всё поверх — очень плохо. По пути PHP-кэшером могут зачитаться недописанные файлы, и ему сорвёт крышу полностью, вплоть до сегфолтов. Лечится только перезапуском.
- Переключать симлинк — плохо. Потому что при выполнении всё-таки может успеть подтянуться часть старых файлов и часть новых, и будут программные ошибки.
- Graceful перезапуск — в условиях высокой нагрузки тоже плоховато. Потому что на некоторое время все сервера разом вообще перестают принимать новые запросы => часть пользователей теряется.
А как делать хорошо? Ответ — переключать Document Root на уровне nginx и делать reload. Тогда все старые запросы обработаются старой версией, а новые — новой.
Ещё была пара слайдов про демон сбора статистики для мониторинга ВСЕГО — BTP. Его сделали открыто-свободным, под GPLv2, есть на гитхабе:
- https://github.com/mambaru/btp-daemon
- https://github.com/mambaru/btp-webui
- https://github.com/mambaru/btp-api
SPDY: быстрее на 146 % / Валентин Бартенев (NGINX)
Доклад про новый гугловский протокол Спиди («SPDY» — ускорятор HTTP), и про то, реально ли он такой спиди. Рассказывал разработчик Nginx’а. К слову, то ли 90 %, то ли даже больший процент всех серверов, поддерживающих спиди на текущий момент — это nginx. Соответственно, доклад — «из первых рук».
Сначала не открывалась презентация, докладчик такой — да… вот со спиди тоже всё сложно… :)
Зачем оно было сделано? А затем, что страницы сейчас, в отличие от 90-х, жирные, с кучей графики, css’ов и яваскриптов. Грузится всё это зачастую с довольно печальной скоростью, в первую очередь из-за многократных round-trip’ов (обменов пакетами туда-сюда) до сервера. А без следующих мер, которые сейчас широко применяются, было бы всё совсем печально:
- Замеры времени загрузки — RRT = RoundTripTime, TTFB = TimeToFirstByte
- Кэширование браузером
- Переиспользование TCP-соединений (HTTP Keepalive)
- Конвейерная отправка запросов (HTTP Pipelining); однако, проблема HTTP-конвейера в том, что он строго последовательный, и отменить посланный запрос (например, при переходе на другую страницу) нельзя.
- Слияние JS’ов / CSS’ов / картинок (спрайтами) в один файл, встраивание всего на страницу (в т.ч и картинок с помощью адресов data://…)
- Асинхронная подгрузка частей страницы AJAX’ом
- Для обхода ограничения старых браузеров (4 коннекта на один домен) — распределение по разным доменам
- Проксирование, раскладывание по CDN
Так вот, говорит докладчик, а гугл предложил заместо всех этих костылей свой кос… протокол. :)
Основные идеи спиди — мультиплексирование в обе стороны, сжатие и server-push, который, правда, работает пока только в Chrome и только криво. Ещё там есть Flow Control, но он тоже пока не работает.
Однако:
- SPDY работает только поверх TLS! И поэтому он медленнее обычного HTTP :(, но, естественно, быстрее HTTPS.
- О том, что сервер поддерживает спиди, он сообщает посредством TLS NPN (Next Protocol Negotiation). Что тоже, пожалуй, костыль.
- Для хорошего сжатия заголовков специально придумали ещё один костыль — LZ77 с предопределённым словарём, состоящим из часто использующихся заголовков, но…
- …Но сжатие заголовков в итоге пришлось отключить, ибо схема «сжать и зашифровать» может быть уязвима к CRIME-атаке.
- …А также в предпоследней редакции протокола были орфографические ошибки в названиях HTTP-заголовков. :)
- На поддержку одного SPDY-соединения расходуется где-то в 100 раз больше памяти, и больше ресурса CPU — мультиплексирование перекладывает нагрузку с сетевой инфраструктуры на сервер. Хотя тем, у кого роутеры собственные, это даже нравится — им-то легче становится.
- При использовании CDN соединения пойдут на разные хосты и от SPDY толку тоже будет мало.
Полнотекстовый поиск в PostgreSQL за миллисекунды / Олег Бартунов, Александр Коротков
Доклад о том, что Постгресовцы наконец-то допёрли, что хранить кроме индекса ещё и отдельную tsvector колонку в таблице для ранжирования результатов запроса — это тормозной костыль, и позиции слов в текстах нужно хранить прямо в индексе. Если так делать, то скорость постгрешного полнотекстового поиска резко подскакивает и становится сильно похожей на Sphinx. То есть очень быстрой. Индекс, правда, вырастает. Однако они там придумали сжатие — «дельта-компрессию» позиций слов — благодаря чему индекс на некоторых тестах получался даже меньше, чем в Sphinx.
Кроме того, и с удалением данных из индекса вопросов не возникает, хотя удаление из обратного индекса — не такая простая операция. Оно как делалось VACUUM’ом, так и делается.
А почему тормозит то, что есть сейчас? А потому, что index scan — операция быстрая, а вот heap scan с проверкой видимости строки — операция медленная. В PostgreSQLьном MVCC в индекс попадают все версии строк, а из результата старые версии отфильтровываются уже после выборки по индексу (что и называется проверкой видимости строки).
Кроме того, хранение позиций в индексе позволит сделать поиск по точной фразе, что было ранее невозможно.
Данную доработку они сразу обобщают на уровень GIN’а (который Generalized Inverted iNdex). Некоторые вопросы там ещё не до конца решены, но к PostgreSQL 9.3 планируют дорешать и включить всё это в релиз. Круто.
Tricky SQL. Особые возможности SQL-диалекта PostgreSQL / Иван Фролков
Чувак рассказывал про альтернативно-одаренные возможности постгрешного SQL, постоянно добавляя «можно? можно. нужно ли? а хрен его знает, зачем, но можно». «Котята! Котята! Курсоры». Запомнились:
CREATE VIEW AS SELECT * FROM VALUES… То есть, VIEW из значений, указанных прямо в запросе. Благодаря тому, что DDL в постгресе транзакционный, можно на это VIEW навесить триггеры, его пересоздающие, и в результате выглядеть оно будет вполне себе как обычная таблица. Если всегда нужно использовать все или почти все данные из него — удивительно, но это ещё и быстрее будет процентов на 10.
Почти что самое безобидное — Top N for M (стандартное «N самых активных пользователей по каждой теме») через использование массивов. Нормальный вариант.
Рекурсивные Common Table Expressions (WITH RECURSIVE) как конечный автомат для, скажем, разбора JSON’а. O_O
WITH parsed AS( SELECT n, token AS token, array[token] AS stack, array['$']::text[] AS path, '' AS jsp, array[0]::INTEGER[] AS poses FROM tokens t WHERE n=1 UNION ALL SELECT t.n, t.token AS token, CASE WHEN t.token IN (']','}') THEN p.stack[1:array_upper(p.stack,1)-1] WHEN t.token IN ('[','{') THEN p.stack || t.token ELSE p.stack END, CASE WHEN t.token IN ('[','{') THEN p.path || CASE WHEN p.stack[array_upper(p.stack,1)]='{' THEN regexp_replace(p.token,'^"|"$','','g') ELSE '[' || (p.poses[array_upper(p.poses,1)]+1)::text || ']' END WHEN t.token IN (']','}') THEN p.path[1:array_upper(p.path,1)-1] ELSE p.path END, CASE WHEN p.stack[array_upper(p.stack,1)]='{' THEN p.token WHEN p.stack[array_upper(p.stack,1)]='[' THEN '[' || (p.poses[array_upper(p.poses,1)]+1)::text || ']' ELSE '' END, CASE WHEN t.token IN ('[','{') THEN p.poses[1:array_upper(p.poses,1)-1]||(p.poses[array_upper(p.poses,1)]+1)||0 WHEN t.token IN (']','}') THEN p.poses[1:array_upper(p.poses,1)-1] ELSE p.poses[1:array_upper(p.poses,1)-1]||(p.poses[array_upper(p.poses,1)]+1) END FROM parsed p, tokens t WHERE t.n=p.n+1 ),
CREATE OR REPLACE FUNCTION generic_cursor(IN SQL text, VARIADIC param text[] DEFAULT ARRAY[]::text[]) RETURNS refcursor AS $BODY$ DECLARE rv refcursor; sthhash text := 'GENCURS'||md5(SQL); EXEC text := 'execute ' || sthhash || CASE WHEN array_length(param,1) IS NULL THEN '' ELSE '('||(SELECT string_agg(COALESCE(quote_literal(pv),'NULL'),',') FROM unnest(param) AS u(pv))||')' END; BEGIN BEGIN OPEN rv FOR EXECUTE EXEC; exception WHEN sqlstate '26000' -- prepared statement does not exist OR sqlstate '0A000' -- table definition had changed OR sqlstate '42703' -- -/- OR sqlstate '42P11' THEN IF sqlstate='0A000' OR sqlstate='42703' THEN EXECUTE 'deallocate '||sthhash; END IF; EXECUTE 'prepare '||sthhash|| COALESCE((SELECT '('||string_agg('text',',') || ')' FROM unnest(param) AS u(pv)),'') ||' as '||SQL; OPEN rv FOR EXECUTE EXEC; END; RETURN rv; END; $BODY$ LANGUAGE plpgsql CREATE OR REPLACE FUNCTION generic_exec(IN SQL text, VARIADIC param text[] DEFAULT ARRAY[]::text[]) RETURNS SETOF record AS $BODY$ DECLARE cr refcursor := generic_cursor(SQL, variadic param); BEGIN RETURN query EXECUTE 'fetch all from '||quote_ident(cr::text); END; $BODY$ LANGUAGE plpgsql
Юзать следующим образом:
SELECT * FROM generic_exec(SELECT n FROM generate_series(1,$1::INTEGER) AS gs(n), 20::text) AS ge(n INTEGER)
Крадущийся сервер, затаившийся диод / Андрей Аксенов (Sphinx)
Очередной доклад Аксёнова, который, как известно, жжот — теперь про то, как правильно делать бенчмарки.
Андрей неплохо прикололся над Badoo:
- Говорит типа — вот, часто результат бенчмарка выглядит так: всего лишь две цифры, одна из которых очевидно больше, другая очевидно меньше.
- Иногда бывает лучше — график зависимости какого-то показателя от параметра, который мы собираемся крутить — количество ядер… серверов… памяти на серверах… китайцев, которые модерируют фотографии…
Публика рукоплескала — один из прошлых докладов был как раз про то, как Badoo «модерирует миллион фотографий в год» 120+ китайцами модераторами.
Мысль доклада номер раз — зачастую бенчмарки проводят криво. Например
- Либо неполно — сводят к 2 числам, внутри каждого из которых целая вселенная;
- Либо не настроив обе системы максимально производительным образом («сфинкс медленнее мамбы»);
- Либо вычисляют не те показатели, которые нужно (среднее время ответа вместо, скажем, 95 % перцентили задержки)…
Мысль доклада номер два — перед тем, как делаете бенчмарк, нужно определить, ЗАЧЕМ вы его делаете, и от этого уже плясать — выбирать показатели и так далее. Варианты целей (копипаст слайда):
- Сравнение двух систем — но его нужно делать аккуратно, так как сравниваете два аж программно-аппаратных комплекса
- Нагрузочное тестирование
- Планирование ёмкости
- Проверка железа
- Ликвидация ВНЕЗАПНЫХ проблем
- Проверка регрессий, воспроизведение проблем и т. п.
Ну, ещё закон Амдала про масштабируемость, и ещё — вместо типичного подсчёта среднего, которое ничего не значит, лучше считать распределение, или хотя бы какие-нибудь перцентили (50 %, 80 %, 95 % и т.п).
Использование очередей асинхронных сообщений с PostgreSQL / Илья Космодемьянский (PostgreSQL-Consulting.com)
Рассказ про mbus — движок для очередей сообщений на основе чистого PostgreSQL. Единственная зависимость — hstore. Реализация весьма банальная — просто таблица с событиями. Возможности получить событие, блокируясь в случае пустой очереди, там нет, просто селекты, завёрнутые в функции. Из паттернов использования — queue, publish/subscribe, request/response, селекторы по параметрам сообщений, задержка доставки, экспайр доставки.
Дополнительные мысли:
- Распределёнщине с 2PC [Two-Phase Commit] может быть больно. Классики жанра показывали, что из ситуации, когда упал координатор и слейв, восстановление тяжёлое/невозможное.
- В области очередей сообщения эталоном может служить спецификация JMS — все граничные случаи там проработаны.
- Под PostgreSQL для очередей есть PgQ — скайповское творение, они в этой области пионэры, поэтому непрерывно ходили по граблям. В реализации участвует отдельный питонский демон и Londiste, администрирование которого ни разу не является простым.
В Roadmap’е mbus’а 2PC и JMS-клиент. Короче говоря, в данный момент mbus к распределёнщине никакого отношения, насколько я понял, не имеет, и вообще хз, зачем нужен.
Суперкомпьютеры сегодня и завтра: архитектура, проблемы, перспективы / Андрей Слепухин (Т-Платформы)
Доклад — история, цифры и фантазии из мира суперкомпьютеров.
История стандартная:
- Суперкомпьютеры — системы для выполнения одной большой задачи, которую обычно трудно разбить на слабосвязанные крупные куски (типа HTTP-запросов в вебе). Задачи обычно счётные. Однако современный суперкомпьютер — это на самом деле всегда суперкластер, отдельный дата-центр :), поэтому в каком-то смысле его архитектура приближается к обычным кластерным. Кстати, 3D-мультики, похоже, вполне себе рендерят на суперкомпьютерах (или чём-то «типа»).
- Архитектура — до 1998 была в основном векторная, потом — в основном массивно-параллельная.
- Важное отличие — наличие интерконнекта. Докладчик рассказал про их основные типы, пропускные способности и топологии.
- Топологии интерконнекта: N-мерный тор/решётка, вплоть до 6-мерной в K Computer-е (2011), N-мерный гиперкуб, Dragonfly
Любопытные факты:
- Современный ноут был бы первым в TOP-500 в 1993 году, смартфон — в 1991. В 2001 году современный ноут всё ещё оставался бы в TOP-500, пусть и на последнем месте.
- В больших суперкомпьютерах постоянно что-нибудь отказывает. Среднее время работы без единого отказа исчисляется несколькими днями. В основном — сбоит интерконнект и оперативка.
- До 50 % энергопотребления может приходиться на интерконнект. А энергопотребление там ого-го, исчисляется мегаваттами.
- >90 % Top500 использует Linux.
Перспективы развития:
- Lustre пока что как есть, так и останется самой популярной ФС.
- MPI как есть, так и останется основным инструментом программирования.
- Возможно разовьётся PGAS (Partitioned Global Address Space).
- Может выстрелить какой-нибудь PCM (Phase-Change Memory), оптические технологии (silicon photonics).
День второй
One Billion Notes as 'Small Data': Scaling Evernote through Horizontal Partitioning / Dave Engberg (Evernote)
Англоязычный доклад рассказывал товарисч из Evernote… про этот самый Evernote.
В начале рассказал, что это такое и почему оно хайлоад. Я это не юзаю, поэтому, например, не знал, что оно пытается распознавать текст с загружаемых туда фотографий. Любопытная фича. Ну, в общем у них там полный хайлоад, 14 миллиардов HTTP-запросов за последние 30 дней.
Они для метаданных используют MySQL, для поиска — Lucene. Любопытный факт: у них Lucene генерирует больше обращений к дискам, чем MySQL. Для хранения файлов — DRBD. Шардят всё это добро по юзерам, благо их дофига и поэтому распределение получается равномерным.
Мысль номер раз — оптимизировать надо 1-2-… основных бутылочных горлышка.
Мысль номер два про облака. Они, конечно, могут оказаться хороши, если вам нужно держать ВНЕЗАПНЫЕ нагрузки, а потом отдавать неиспользуемые ресурсы обратно. И/или если у вас мало обращений к диску… И то не факт.
Но по их подсчётам, для них тот же Amazon Web Services был бы сильно дороже:
- Если поделить стоимость одного их шарда на 4 года, получится почти в 3 раза дешевле, чем AWS (166$ против 455$).
- Аналогично WebDAV-сервера дешевле Amazon S3 в ~6 раз (14$ против 99$).
- Сеть — в 3.5 раза дешевле — 4000$ против 13700$.
Percona XtraBackup: экспертные возможности / Алексей Копытов (Percona)
Рассказ про Percona XtraBackup:
- Есть инкрементальные бэкапы InnoDB (xtrabackup).
- Есть обычные бэкапы нетранзакционных данных (innobackupex).
- Умеет делать бэкап с ограничением нагрузки на сервер.
- Умеет восстановление за заданный момент времени.
- Есть статистика.
- В XtraBackup 2 — встроенное шифрование и сжатие (профит в том, что потом можно восстанавливать отдельные таблицы), потоковые инкрементальные бэкапы, восстановление buffer pool…
- Наверное, не умеет бэкапить tablespace на блочных устройствах. Просто никто не просил.
MySQL Plugins — why should I bother? / Sergei Golubchik (MariaDB)
Обзор плагинов к MySQL’ю. В целом они бывают:
- Storage Engine. Транзакционные, нетранзакционные, а также всякая специфика — сфинкс-коннектор, графовая БД OQGRAPH, FEDERATED и т. п.
- Information schema. Просто плагины, выдающие дополнительную информацию в INFORMATION_SCHEMA.
- Авторизация. Тоже всё ясно — подключить можно разное. Может быть полезно для удобства, для безопасности.
- Full-text parser. Вообще первые плагины, которые появились. То есть, стеммеры и словари.
- Аудит. Ничего не делает, только всё мониторит.
- Демоны. Делают что угодно, но постоянно. Примеры — heartbeat, handlersocket, оракловский thread pool.
В MariaDB — плагины SphinxSE, OQGRAPH, HandlerSocket уже есть искаропки, MyISAM заменён на совместимый ARIA, InnoDB — на совместимый XtraDB.
В целом MariaDB кошерен скоростью работы и очень кошерен свободой от оракла.
Proactive Web Performance Optimization / Marcel Duran (Twitter)
Основная (единственная?) мысль доклада товарища из Twitter’а — прикручивание YSlow к серверу непрерывной интеграции в виде теста на скорость загрузки страниц. Ещё было про webpagetest.
Прикручивать можно, используя headless webkit браузер PhantomJS. phantomjs yslow.js умеет выдавать результаты в виде junit XML, или TAP (Test Anything Protocol). Следовательно, прикрутить можно почти ко всему.
Adventures in Bug Hunting / Joseph Damato (Boundary)
Очередной иностранец с красивой презентацией о том, как он ловил баг в bprobe, а баг оказался в Linux ядре, в драйвере e1000e. Он сначала думал, что в ядро пакеты попадают. А оказалось, что не попадают, причём только на Debian Lenny 64bit)) ну что ж, бывает))
bprobe — это некая его утилита для ловли пакетов на bonding сетевых интерфейсах. Bonding — линуксовый термин, означающий создание одного «общего» сетевого интерфейса из нескольких для распределения нагрузки и обеспечения отказоустойчивости.
Моё мнение о докладе — занимательно, но не более того. Многие линуксоиды таким багхантингом занимаются время от времени))
А картинки были прикольные:
Cервис рекомендаций на виртуальном Hadoop кластере / Роман Зыков (Wikimart)
Чувак рассказывал про рекомендации в викимарте. Раньше он был поклонником вендорских систем, внедрял адобовский SiteCatalyst. Потом одумался и они стали вычислять рекомендации сами. Сначала они пробовали делать это тупо на MSSQL’е, но это было печально. Двуксеон с 48 гигами оперативы и 8 SAS-дисками в RAID10 с задачей справлялся в лучшем случае часов за 5, с 30 % вероятностью — то есть, каждый третий раз — падал по разным причинам (то логи кончались, то ещё что-нибудь), и на всё время обновления блокировал загрузку данных в хранилище.
А потом они решили попробовать Hadoop — Apache’вский свободный аналог распределённого гугловского хранилища BigTable. Собрали маленький кластер всего из 6 более простых компов, по 2 Гб оперативки, 30 гб HDD и 16 ядер (O_o не очень-то попроще компы были))). Поставили на него Cloudera Manager, который бесплатен до 50 нод. Заюзали sqoop для передачи данных из hadoop’а в СУБД. Hive и Pig — для обработки данных. Hive — почти SQL поверх HDFS’а. И тот, и этот поддерживают User-Defined функции. В частности, в Pig 0.10 добавлены оные от LinkedIn (DataFu UDF), типа удобные.
Для сжатия выбрали кодек snappy (by гугл), который может жмёт и немного похуже LZO, но зато распаковывает быстро, что приводит к общему ускорению ввода/вывода. Для этого ускорения он, собственно, и создавался. Плюс у LZO дебильная лицензия, а у snappy нормальная и он есть в hadoop из коробки.
И типа всё стало хорошо, и можно двигаться в сторону аналитики в реальном времени.
Спасение 6 млн файлов в условиях полного Хецнера / Даниил Подольский, Дмитрий Симонов (Setup.ru)
Говорит, есть такой известный немецкий хостер на букву Х, и оборудование у него тоже на букву Х — хорошее. Но не очень надёжное.
Мысль: вполне нормально хранить файлы в Postgreшных блобах. Ибо нет дублирования метаданных на уровне базы и ФС, поиск по параметрами (дате и т. п.) очень быстрый, плюс очень важно, что в PostgreSQL есть API для потокового доступа к блобам, через которое их можно раздавать. Конечно не sendfile и не zero-copy, но утверждают, что не хуже, ибо в сеть упёрлись сильно раньше, чем в процессор — 1000 соединений, 30 % нагрузка на проц, 10 % на диск, всю память под кэш не выжирает, а гигабитный канал забит полностью! То есть «а нам быстрее и не нужно, всё равно в сеть не пролезает».
Ещё пробовали HyperTable, но он пока что нов и падуч.
Бэкапов они не делают :-) типа, потому что всегда есть под рукой живая реплика. Хотя вообще-то бэкапы всё равно нужны, потому что от TRUNCATE TABLE реплика не спасёт. А я посмотрю, как они свои блобы будут rsync’ом бэкапить :-D у них, правда, почему-то 6 миллионов файлов разложено по 6 миллионам директорий, и обход этого дикого дерева занимает 6 часов O_o мда.
«Вывод: технологии каменного века ещё актуальны!»
Выжимаем из сервера максимум! Приёмы кеширования и передачи данных на Java / Андрей Паньгин (Одноклассники)
В одноглазниках 4000 серверов и всё написано на Java, а архитектура сервис-ориентированная. То есть, всё поделено на сервисы, относительно слабо связанные друг с другом. Следствием SOA является то, что, между серверами происходит много взаимодействия. То бишь, данные сериализуются и гоняются по сети. Вот о том, какие с этим проблемы и что же делать, и рассказывал докладчик. Плюс про кэш.
Проблемы Java-сокетов: криво работают неблокирующие сокеты. Где-то они не thread safe, где-то утекают управляемая память из-за финализаторов (не очень понимаю, что имели ввиду, так как не копал тему, но он сказал «мы обнаружили, что в сокетах есть финализаторы»), где-то утекает нативная память, где-то не срабатывают таймауты. А нормального libev’а / libevent’а там нет. Отсюда либо многотредовость и блокирующий ввод/вывод, либо фреймворки типа APR, MINA, Netty.
Сериализация: стандартная медленная и даёт большой объём данных, JBoss’овская отваливается при изменениях в определении класса, ручная — не вариант, ибо классов тысячи. Были варианты использовать Avro / Thrift / Protobuf, но они в итоге написали свою. Чтобы вертеть private свойствами других классов — юзают Unsafe, чтобы обойти верификатор доступа — наследуют sun.reflect.MagicAccessorImpl. При переключении на эту сериализацию производительность резко улучшилась на 20 %, а объём передаваемых по сети данных уменьшился на 50 %. Однако с Protobuf и прочими они её не сравнивали. А и правда, зачем, можно ж своё написать :))
Сериализация, вроде, открыта и находится на гитхабе: https://github.com/odnoklassniki/rmi-samples/ (а может, там только RMI, не проверял)
Кэширование: в Java стандартная проблема, ибо память-то управляемая, и GC должен по ней время от времени проходиться. Если её много, получаются тормоза, самые худшие — когда кучи остаётся совсем мало и начинается Full GC («stop-the-world»). Посему надо как-то использовать off-heap (неуправляемую, нативную) память. Как сказал докладчик — а это опять мой любимый class Unsafe. Либо ByteBuffer.allocateDirect(), либо mmap (через MappedByteBuffer), либо писать свою JNI-обёртку.
Проблема прогрева кэша (медленный старт, пока кэш пустой) решается созданием снимков. Которые должны быть целостными. Но вместо очередного stop-the-world лучше делать fork() и создавать снимок в дочернем процессе — засчёт Copy-On-Write память не задублируется, но при этом состояние снимка меняться не будет. Либо юзать разделяемую память. Они используют именно разделяемую память, сами бьют её на сегменты и сами лочат. Их реализация получилась быстрее Ehcache и JCS, на каких-то операциях раза в 2, а на каких-то раз в 20.
Сие тоже открыто: https://github.com/odnoklassniki/shared-memory-cache
Внимание — Авторы, когда выкладываете что-то куда-то, определяйте лицензию! А то вот это добро выложено, а файла COPYING нету :)
AddressSanitizer, или как сделать программы на C/С++ надежнее и безопаснее / Константин Серебряный (Google)
AddressSanitizer — это такой Valgrind, только гугловский, на основе LLVM и сильно быстрее. Замедление всего в 1.5-2, максимум в 3 раза (редко), по сравнению с Valgrind’овскими минимум 20-ю это очень круто. Но нужно, чтобы ваш проект собирался LLVM’ом. Тогда использовать очень просто — собрать с ключиком -faddress_sanitizer.
Штуковина, собственно, отлавливает ошибки доступа к памяти. Не совсем корректно сравнение с Valgrind — он утечки памяти умеет искать, а эта штука не умеет. Работает относительно просто — на каждые 8 байт памяти сохраняется 1 байт состояния. Вариантов которого всего 9 — от «все 8 байт хорошие» до «все 8 байт плохие», только планка посередине сдвигается. Кроме того, есть «карантин» — только что освобождённая память какое-то время не выделяется снова. Служит для определения доступа к освобождённой памяти. Плюс в комплект входит библиотека, перехватывающая стандартные функции работы с памятью типа memset, memcpy.
Широко используется в гугле и за его пределами (например, Firefox). Постоянно что-нибудь находят. «Всё написано на C/C++, даже если вы об этом не знаете — компиляторы, виртуальные машины, веб-серверы, СУБД…»
«А ещё у них есть ThreadSanitizer и MemorySanitizer». Вот.