Персональные инструменты
 

Highload-2013: Отчёт Виталия Филиппова

Материал из CustisWiki

Версия от 01:04, 12 ноября 2013; VitaliyFilippov (обсуждение | вклад) (Как рассуждать о производительности хранилищ баз данных / Mark Callaghan (Facebook))

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Информация о конференции, организация:

  • Highload-2013, «Конференция разработчиков высоконагруженных систем». Проходила в очередной раз в конференц-зале гостиницы Radisson на м. Киевская.
  • Самая первая и самая распиаренная из Бунинских конференция. Билет стоил аж 21000, плюс ещё были отдельные «учебный» и «VIP» дни (на которых я, естественно, не был).
  • Хайлоад начался с хайлоад-очереди на регистрацию. В разные обработчики она, правда, почему-то была разная (очередь с приоритетами, где каждый оценивает свой приоритет сам?), и встав в другую, ты терял времени на порядок-два меньше.
  • Вайфай нормально не работал, до отваливания в нём удавалось посидеть минут 5.
  • С едой всё было более-менее в порядке — кофе-чай всё время, 2 перерыва, каждый из которых для части людей — кофе-брейк с плюшками, а для другой части — обед (балансировали нагрузку талонами). Небольшие трудности с обедом — народу много, места сесть не хватало, часть еды быстро кончалась. Но голодным там всё равно никто не оставался.
  • Дали большую кучу раздаточных материалов — книжку с частью докладов с прошлой конференции, диск, рекламу, 3 блокнота… Полезный элемент — в этом году вместо ахтунг-стайл красной авоськи дали сумку для ноутбука, в которую и был упакован весь выданный crap.

Общая атмосфера:

  • Атмосфера в целом какая-то «коммерческая», видно, что компании туда ходят уже по накатанной для регулярного пиара.
  • Докладчики (компании) — всё одни и те же лица, посетители — наоборот, похоже, исключительно новые. Правильно Стас выразился — это как с борделем, нормальный человек ходит туда 1 раз в жизни; это ты ходишь постоянно, и тебя уже ничем не удивишь.
  • Девушек на конференции не было почти совсем, «радостную» программистскую тусовку разбавить было некем.
  • Многие зарубежные «звёзды», как обычно, лили воду, содержательной части в докладах от FB, например, процентов 10.
  • Было много докладов от одних и тех же компаний — может это и не плохо, но по-моему свидетельствует о неком спаде доступного разнообразия (или слабом подборе). Ну и badoo (которое сайт знакомств и вообще непонятно, почему в 21 веке имеет столько юзеров) уже слушать как-то неинтересно. Примеры повторов:
    По 3 доклада от Badoo и 2ГИС; по 2 от Одноклассников, Facebook, Monty Program AB, Qrator/HLL, mail.ru, HashiCorp. К этим в общем-то претензий нет, понятно, что вторых таких же чуваков, как Qrator, найти сложно.

Содержание

День 1

Экосистема Сочи 2014. Космос как предчувствие / Михаил Чеканов (Оргкомитет Сочи 2014), Ольга Куликова (Articul Media)

На докладе не был, отмечаю потому, что из интересного там было очевидное :-) сайт сначала сделали на БИТРИКСЕ, но потом всё-таки поняли, что с этого нереального ужоса надо сваливать. И таки свалили — переписали всё сами и довольны.

(незачёт) Как поставить миграцию баз данных на поток / Илья Космодемьянский, Роман Друзягин

Чуваки пытались рассказывать доклад вдвоём попеременно. Это хороший формат выступления, но слайды у них тем не менее были совершенно жуткие, да и сам рассказ таил в себе больше воды.

  • Из содержательного — миграции нужно всегда отрабатывать и нужно всегда иметь план «Б», то есть иметь возможность быстро откатиться назад, если миграция БД не удастся.
  • Из смешного — если будете покупать IBM DB2 — скажите, что мигрируете с оракла, они вам сделают скидку :-D

Полнотекстовый поиск в Почте Mail.Ru / Дмитрий Калугин-Балашов

Зашёл в самом конце, услышал чуть-чуть. В общем, смысл в том, что полнотекстовый поиск написан полностью кастомный, хранит отдельный индекс для каждого пользователя, и умеет сортировать только по дате. Вроде внутри некая лог-структура.

Из смешного — их спросили, неужели вам не подошло ни одно из готовых решений, зачем вы написали свой поиск? Они ответили — потому что есть ресурсы! («because we can!»)

Своевременная оптимизация / Carlos Bueno (Facebook)

Доклад рассказан неплохо, хоть содержательность и хромает. В основном было много общих слов.

Чувак из фейсбука перевёл слайды на русский язык (на каждом слайде фраза была и по-английски, и по-русски)… но, видимо, перевёл google translate’ом, потому что были такие перлы:

  • Optimisation: don’t ever do it! (* except sometimes).
    Оптимизация: никогда не делайте его! (* кроме иногда)
  • Distrust numbers. Especially your own.
    Числа недоверия. Особенно ваше собственное.

Ещё из смешного — доклад он начал со слов:

  • I work at Facebook, it’s a V Kontakte in America. I work at facebook performance team…

И тут кто-то спросил (было в твиттере, было ли в реале — не уверен) :D

  • OK, so when will you begin? [working on facebook performance]

А дальше общие размышления:

  • Проблема должна быть проверяемой, если она непроверяемая — то это не проблема…
  • Два пути решения — повысить производительность либо сдвинуть нагрузку (которой мы можем управлять — обсчёт какой-нибудь и т. п.)
  • Оптимизация это больше не про computer science, а про science science; вообще вся разработка — типа, умение «playing computer in your head». Однако: who is better than you in playing computer? the fucking computer! (не помню, к чему это — видимо к тому, что можно пытаться не придумать, а симулировать нагрузку)
  • Опять про корректность измерений: «I feel really stupid saying about this, but directly measure what you optimize»
  • Говорит, мы в один день проснулись, а Facebook на 10 % быстрее. Он такой — я говорю начальнику, смотри, круто! А он — ты зря радуешься, если много ситуаций, в которых система может ВНЕЗАПНО стать на 10 % быстрее, и лишь малая часть из них — хорошие :-)

Распространение систем на Scala благодаря Finagle / Julio Capote (Twitter)

Товарищ из Twitter’а просто рассказывал какая хорошая scala, и какая у них есть под неё библиотека RPC Finagle, я как-то выпал из контекста.

Опыт переезда соцсети Livestreet с PHP/MySQL на NodeJS/Redis/Lua / Дмитрий Дегтярев (Хабикаса)

Странный доклад… У чуваков был стандартный сайтик на стандартной отстойной блого-социально-подобной CMS’ке Livestreet. Данных там мало, всего несколько тысяч постов. И его вместо того, чтобы просто переписать, переписали на сильно извращённый вариант:

  • В качестве БД — Redis
  • В качестве логики — хранимые процедуры на Lua внутри Redis’а O_O
  • Вместо классической схемы сделали сайт почти целиком на AJAX
  • Генерация маленьких HTML страничек для возможности индексации осталась в Node.js

Сразу отметим: запихивать толстые хранимые процедуры в redis == на корню убивать его производительность, он же однопоточный мультиплексирующий и все команды должны выполняться быстро.

Типа, кэш мы инвалидировать не хотим, давайте сразу всё хранить в кэше… :-) хотя Redis — это вообще-то не кэш, а БД. Просто когда он вылезает за размеры памяти, работает весьма печально, а пока не вылезает, всё и так в памяти и по скорости он таки да, почти как memcache. Ещё в Redis’е есть два понятия — embed и sideload, типа при загрузке связанные сущности могут либо подгружаться по ID отдельно, либо встраиваться прямо в родительскую сущность. Первое, очевидно, меньше занимает места, второе — делает меньше запросов.

Потом чувак сделал мегасерьёзный «бенчмарк» и расстроился, потому что redis с его подходом не получился быстрее MySQL! Бенчмарк заключался в измерении скорости загрузки ВСЕХ ПОСТОВ из базы одним запросом. Офигеть бенчмарк. «На мой взгляд редис должен быть в 10 раз быстрее… но сейчас это не так, или я тест сделать ниасилил подходящий даже» :-)

Ещё в моих заметках отмечено «бред про многопоточный редис», но что это значит, я уже забыл :-)

Потом он полез профилировать redis, и обнаружил, что 50 % времени тот проводит в string2ll (конвертации строки в число). Интересно.

Но в общем и целом, буханка, троллейбус. Badoo’шники того же мнения, их чувак выразился «то есть вы решили пересесть с лёгких наркотиков на тяжёлые».

Дизайн движка метапоиска aviasales / Борис Каплуновский (Aviasales)

Интересный доклад от Aviasales («метапоисковика» авиабилетов), докладчик сначала было испугался, что его, как и предыдущего, сейчас запинают насмерть ребята из Badoo — он сказал, «я наверное тоже по вашему мнению пересел на тяжёлые наркотики», но на самом деле — нет, и архитектура, и доклад вполне адекватны и тот же badoo’шник это признал :-)

Задача: есть куча поставщиков API, которые по запросу умеют отдавать дикого размера XML’ки или JSON’ы с ценами на авиабилеты (1-30 мб). Пользователь выбирает даты, пункт отправки и назначения и число человек, и по этому запросу Aviasales должен максимально быстро сделать запросы ко всем поставщикам, собрать от них цены и отобразить пользователю в порядке возрастания. Кэшировать особо не покэшируешь, так как информация быстро меняется и должна быть максимально актуальной.

Нюанс: поставщики обычно сами тоже агрегаторы и тоже делают запросы к авиакомпаниям. И эти запросы поставщикам API не бесплатны. Соответственно, хоть запросы от Aviasales к ним для самого Aviasales и бесплатны, всё-таки лишние запросы тоже делать нельзя. Короче говоря, задача достаточно простая и прямолинейная.

Ещё нюанс: по их исследованиям конверсия уменьшается на 30 %, если среднее время ответа сайта повышается со 100 до 500 миллисекунд. Так-то.

Как было: Раньше у них всё это было представлено некой системой, написанной на Ruby On Rails, и это было довольно печально, так как RoR — типичный веб-фреймворк:

  • Стартует небыстро, 5-10 секунд (и перезачитывать код на лету видимо не умеет?) — это несколько затрудняет отладку.
  • Занимает немало памяти под каждый процесс зависимостями и т. п. (у них вроде 300 мб, но вероятно с учётом разделямой памяти)
  • Полностью синхронный, и пока какой-то процесс делает запрос к внешней системе — процесс тупо висит, курит бамбук и ждёт ответа на сокете. Занятая память простаивает. Кроме того, пока таким образом не завершатся все скачивания — не получается начать отдачу страницы пользователю (не получается сделать «живой поиск»).

Как стало: В общем, им всё это поднадоело, они решили всё переписать и изобрели свой «сервис-ориентированный» DSL на питоне, на основе сервера Tornado. DSL называется «Ясень», состоит из изолированных обработчиков (у которых на входе 1 объект и на выходе 1 объект) и довольно прост, умеет всего 3 вещи:

  • Последовательные цепочки — выход одного обработчика скармливается другому
  • Параллельные цепочки — выход одного обработчика скармливается набору других
  • Отложенные цепочки — выход всегда равен входу, предназначены для побочных эффектов (логгирование и т. п.)

Цепочки запускаются внутри одного процесса, то есть даже никакие JSON’ы между серверами туда-сюда не гоняются. Каждый обработчик при этом можно дёрнуть извне, таким образом отлаживаясь.

Система в целом написана на этом DSL, и его даже понимают менеджеры — бывает, приходят и говорят: а вставьте-ка мне вот сюда вот такой обработчик… И они вставляют.

Архитектура хранения — данные делятся на несколько видов:

  • Мелкие справочники (например, валюты) — хранятся в памяти процесса на каждом сервере.
  • Толстые справочники (> 1 мб) — хранятся в файловой key-value БД kyotocabinet. Она маппится в память процесса, соответственно, разделяется всеми процессами. Реплицируются на сервера с помощью, кажется, файловым репликатором lsyncd.
  • Логи — всегда пишутся локально, а потом асинхронно перетаскиваются в глобальное хранилище.
  • Динамические данные — пишутся на 2 redis-сервера для отказоустойчивости.

Какие есть процессы:

  • «Пчёлы» — рабочие процессы, «муравьи» — те, что логи переносят, и локальное хранилище (плёлы и муравьи — это не я придумал, это у него в докладе так было).
  • Ещё есть HAProxy для распределения соединений, «многоножка» — интерфейс администрирования, и мониторинг monit, в который смотрит «пингвин»-админ.
  • Если упадёт 1 redis — пофиг, система работает дальше. Если упадёт второй redis — ну, увы. Говорит, если у меня упадёт два редиса, я сначала уволю админа, а потом поставлю третий.
  • Ещё при каких-то видах сбоев (если помрёт глобальное хранилище логов?) — часов 8 оно точно спокойно проживёт, а это время, за которое типичный «пингвин» может выспаться, прийти и всё пофиксить.

Как делается синхронизация данных на серверах после сбоя — он не рассказывал. Возможно, делается руками админа-«пингвина».

Как мы храним 60 тысяч событий в секунду / Арсен Мукучян (AdRiver)

Сурьёзный плюсист в чорном костюме рассказывал, как за 5..10 человеко-лет (5 человек за 2 года вперемешку с другими задачами) они переписали хранилку событий в AdRiver. Событие ≈ показ баннера, занимает от 0.1 до 4 Кб. Старая система работала на основе syslog (оригинально), который дропает события, когда их становится много (это фича, а не баг). Писали они исключительно хранилку, конкретные вычисления статистики отданы на откуп клиентам к хранилищу (то есть, другим отделам).

Рассказывал немного грустновато, я немного отключался. Итог реализации — кажется, поточная схема взаимодействия и «поуровневая» система архивирования: свежие события на «ближних» серверах, старые «дальше», ещё из старых событий может удаляться малополезная, но длинная информация типа Referer…

Нагрузка сейчас 2 гбит/сек (закладывали до 20 гбит/сек), загрузка CPU 20-40 %, обслуживается 5000 клиентов с 10 серверов.

Обзор популярных современных алгоритмов хранения данных на диске: LevelDB, TokuDB, LMDB, Sophia / Константин Осипов (Mail.ru, Tarantool)

Что-то в этом году на хайлоаде было популярно рассказывать про всякие структуры хранения данных, в основном — оптимизированные для быстрой записи. Докладов было аж несколько. Но тем не менее — весьма интересно, я про детали реализации этих структур раньше как-то не слышал.

Во-первых, LSM-деревья (Log-structured merge-tree). Идея в том, что у LSM дерева есть несколько уровней хранения увеличивающихся размеров, первый (нулевой, он же memtable) из которых лежит в памяти, а остальные лежат на диске. Каждый уровень представляет собой дерево или список деревьев, и у каждого уровня есть растущий (обычно в 10 раз на уровень) лимит размера. Вставка производится сначала в нулевой уровень, при переполнении он сбрасывается в первый, при переполнении первого — попадает во второй… И так далее. Вставки получаются быстрые, так как не нужно мучаться с перезаписью отдельных мелких блоков данных. Однако зато мы, во-первых, имеем неслабый write amplification, а во-вторых — при поиске значений должны просматривать все деревья (что не круто). С первым ничего не поделаешь, а со вторым борются поддержание в памяти bloom-фильтров — некой хеш-таблицы, посмотрев в которую, можно сказать, в каких деревьях данных точно НЕТ, а в каких они МОГУТ БЫТЬ.

LSM-деревья используются в библиотеке LevelDB от гугла, встраиваемой SQL БД SQLite 4, в HBase, Wired Tiger и в NoSQL БД Apache Cassandra.

Во-вторых, Cache-oblivious структуры (общий термин, характеризующий то, что структуры эффективно используют кэш процессора, не зная его точного размера). Подход используется в новомодном движке хранения для MySQL — TokuDB (у них это называется Fractal Tree Indexes). Идея в чём-то похожая — просто в каждом узле обычного B-дерева ещё поддерживается «буфер» для вставок, и вставляемые элементы сначала попадают туда, а уже потом сбрасываются в дочерние узлы. Засчёт этого скорость записи опять-таки увеличивается и не падает, даже когда индекс перестаёт влезать в память.

В-третьих, Bitcask, используемый в Basho Riak. Это вообще вещь тупая — данные всегда пишутся последовательно, хеш-индекс всегда держится в памяти.

Ну и последнее — некий гибридный подход, используемый в библиотеке Sophia. Там, с одной стороны, данные делятся на непересекающиеся регионы, индекс которых (min, max для каждого) держится в памяти (получается что-то типа листов B-дерева), с другой — в памяти есть хеш-таблица, в которую в начале попадают новые элементы (чем-то похоже на memtable LSM-дерева). На диск последний хеш пишется в виде «журнала» (чтобы данные не терялись). А когда данных в этом хеше становится слишком много — данные распределяются по регионам, которые в свою очередь при переполнении разбиваются на под-регионы.

В конце докладчика спросили — а как Tarantool-то хранит?! Как, как — да никак. В памяти он хранит. В будущем, возможно, его научат хранить и на диске.

Статистика на практике для поиска аномалий в нагрузочном тестировании и production / Антон Лебедевич

Доклад интересный — про то, как можно применять методы статистики для выявления потенциальных проблем системы по графикам кучи показателей с кучи серверов. Ну или как их хотя бы сгруппировать / почистить так, чтобы количество стало вменяемым и в нём мог разобраться человек.

Выявление аномалий:

  • Поиск изменения среднего. С помощью банального скользящего обычного или экспоненциального среднего.
  • Поиск изменения распределения данных (делим данные на две части, применяем критерий Колмогорова-Смирнова).
  • Выявление нелинейного роста.
  • Выделение тренда с учётом сезонности + сильный выход за его границы (классический Холт-Винтерс). Минус в том, что нет нормального алгоритма для трёх сезонов, а их обычно как раз три :-) да и вообще в реальных данных часто встречается, например, график вида «пила».
  • Нарушение автокорреляции показателя.

Группировка показателей (поиск зависимостей между графиками):

  • Применяются методы кластеризации (k-средние, иерархическая группировка).
  • На основе, например, корреляции или среднеквадратичного отклонения между графиками.
  • Однако есть минус — такая группировка прекрасно «ловит» ротацию логов (когда старые логи сжимаются/удаляются). Она обычно происходит на всех машинах в один момент, и смена разных показателей в этот момент отлично группирует графики, хотя вообще-то их группировать незачем.

Всё это (или по меньшей мере часть), как ни странно, реализована в опенсорсном виде и её можно пощупать: https://github.com/etsy/skyline, https://github.com/etsy/oculus (части некого Kale Stack).

День 2

Завалить в один запрос: уязвимости веб-приложений, приводящие к DoS / Иван Новиков (ONsec)

Доклад немного в стиле «капитан ясен хрен», и явно было заметно, что товарищ пиарил свою конторку.

Рассказывал про баги в сайтиках, через которые «всё поломать» не получится, но DoS устроить вполне можно. Часть идей была полным (или НЕполным) бредом:

  • Бажные парсеры — типа бывают баги в парсерах (XML, CSV, входных параметров и т. п.), из-за которых оные зацикливаются. Утверждал бред, что если передать PHP параметр вида ?a[][][]…[][][], то он зациклится. Это конечно не отменяет того, что такие баги _возможны_, но явно не в этом месте.
  • Ещё одна бредовая идея — чувак утверждал, что популярные новомодные «классификаторы» (типа ютинетовского) тормозят, если им выдать что-то непонятное («синий красный зелёный одновременно фиолетовый и вес меньше 100кг»). Дурь. С чего им тормозить? Разве что имеются ввиду движки, которые по условию (< 100кг) вытаскивают все возможные значения веса и ищут по множеству? Но и это к серьёзным тормозам не приведёт. Ютинетовский подтупливает, конечно, но он и в целом небыстрый… а на DoS в один запрос это как-то не тянет.
  • Про переполнение хранилища сессий. Типа если сессии очень жирные (если там хранится вся история посещений со всеми полями запроса), то их туда можно накидать своих, и других людей не будет логинить, или если они в tmpfs, память кончится (что бред — tmpfs ограничен в размере). Но даже если всё так, то эксплуатировать довольно геморно — это надо реально долбить сервер запросами, иначе ваши «толстые» сессии всё равно будут вытесняться.
  • А вот эта относится к классу «капитан ясен хрен»: вспомнил поиск по регэкспам в БД, которые при этом ещё и берутся из параметров запроса. Не, то есть я не против, PHP-сайтики много ССЗБ пишут — многие популярные движки, например, исполняемый код в базе хранят (битрикс, Invision Power Board, например). Но это же реально ССЗБ — ясно же, что поиск по регэкспу в БД медленный ВСЕГДА. А он говорил, что типа можно сделать такой регэксп, который будет делать очень глубокий поиск с возвратом (backtracking) и тормозить.

Некоторые идеи были вполне ничего:

  • Часто ограничивают заливаемую картинку размером в килобайтах, но не ограничивают размер в пикселях. А ведь в PNG можно создать хоть 100000x100000 картинку маленького размера, залитую одним цветом — там же сжатие. И в итоге на масштабирование, и даже на кроп такой картинки приложение тут же потратит всю память сервера. Лучше даже так рассчитать размер, чтобы в OOM процесс сваливаться не успевал, а чтобы просто дико свопился — пожалуйста, DoS в один запрос.
  • Пример с яндексом — они нашли баг в WebDAV сервисе яндекс диска — попытка перемещения папки в свою дочернюю приводила к зацикливанию. Им даже 5000 рублей за эту находку дали.
  • Любые взаимодействия по сокетам, в которые можно подсунуть свой адрес — например, OpenID. Дело в том, что таймаут запроса часто работает не в целом, а на 1 операцию чтения из сокета. Тогда делаем свой сервер, который на запрос будет раз в (таймаут-1) секунд отвечать 1 байтом. Подсовываем его URL и делаем с ним штук 80-100 запросов к сайтику. Итог — все рабочие процессы заняты тем, что прилежно ждут, пока наш сервер им посылает данные по 1 байту.

Но про самое классическое чувак почему-то не вспомнил! Самое классическое — это банальное открытие последних страниц какого-нибудь длинного тяжёлого поиска. В один запрос, конечно, не завалишь, но лёгким DoS’ом заставить сайт дико тупить от такого действия можно очень часто.

Масштабирование скомпилированных приложений / Joe Domato

Причем тут «масштабирование» — непонятно. Рассказ был про автоматизацию сборки и CI. Послушал чуть-чуть, услышал про:

  • На винде все эти автотесты и CI настраивать геморно, на нормальных системах сильно удобнее.
  • Тестов мы не хотим много и не хотим мало.
  • Сборка должна быть повторяемой.

(полный отстой) Анализ производительности и оптимизация MySQL / Пётр Зайцев (Percona)

Тут я даже заметок никаких не напишу. Доклад вообще ни о чём, его можно было не делать. Там были не просто общие слова, а 100%-ная вода, состоящая из тривиальнейших идей. Про оптимизацию MySQL там не было вообще ничего, ни одной фразы.

Кто после такого доклада пошёл ещё и на мастер-класс этого мастера лить воду — лопух ;-)

Платформа для Видео сроком в квартал / Александр Тоболь (Одноклассники)

Рассказ о том, как Одноглазники передалали свой видеосервис на собственную платформу. До этого он работал сначала на платформе видео@мейл.ру, потом на rutube. Но, судя по всему, ни качество, ни стабильность ни того, ни другого их не устроило, а задача создания средненького видеосервиса — она в принципе не такая уж и суперсложная, поэтому они его решили сделать сами.

Объёмы нормальные, в день: 10 млн уников, 60 млн просмотров (до 100 гб/сек), 50 тысяч новых видео (= 5 ТБ = до 5 гб/сек).

Итого устроено всё довольно просто:

  • Хранилище — 70 серверов, 5 петабайт, БД и кэш — ещё 30, парк ffmpeg’ом под zookeeper’ом для трансформации — ещё 60, раздача и загрузка — ещё 30.
  • Есть возобновляемая загрузка (failover).
  • Используют flash. Хотят доделать HTML5 плеер.
  • Как обычно, псевдостриминг (и правильно, все так делают, кроме тупого рутуба). То есть, не RTMP или что-то подобное, а обычная раздача MP4 через HTTP, а если нужно перемотаться — HTTP Range Request.
  • Собственный вариант qt-faststart — скрипта, который перемещает MOOV Atom (заголовок видео) в начало файла (он в MP4 по дефолту в конце O_o), а также удаляет из него информацию о лишних keyframe’ах.
  • Нюансы перепаковки: несколько качеств, в 15 % случаев требуется коррекция длительности.
  • Чтобы всё это работало быстро, они, во-первых, напилили собственный кэш на своих one-nio и unsafe кэше, в который всегда попадают все заголовки видео, плюс попадает само видео кусками по 256 Кб.
  • Для кэша используется 96 Гб RAM и 4 ТБ SSD’шек на каждом сервере, плюс OBS. 80 % cache hit.

Вещание видео на 10 ГБит/с / Максим Лапшин (Erlyvideo)

Erlyvideo теперь вышел на американский рынок и называется Flussonic. И, видимо, теперь его используют разные группы нехороших лиц, наживающихся на продаже «нихрена» (контента). Сам Erlyvideo от этого, правда, хуже не стал (а то и стал лучше) и остался опенсорсным, что, безусловно, хорошо.

Рассказывал про разные нюансы раздачи видео с одного сервера на 10 гигабит. Типа процы в принципе не особо ускорились за 5 лет, но зато подешевели 10 гбит каналы, и появились SSD’шки, и вроде как стало можно раздавать и 10 гигабит. Например, на нагрузках в несколько гигабит у них подыхал software raid. И прочее — прерывания, дисковые очереди и т. п.

DDoS атаки в России в 2013 / Александр Лямин (QratorLabs/HLL)

Обзор ситуации с DDoS’ом в России за этот год.

Интересное:

  • Атак стало больше в 1.5 раза, рекорд за день вырос в 2 раза, макс. размер ботнета тоже немного подрос, рекорд длительности — наоборот, упал.
  • Spoofed атак («с чужого IP») стало больше, чем прямых.
  • В основном пик активности был в конце зимы и весной (в отличие от 2012 — пик был летом).
  • Уверенный лидер по атакам как в 2012, так и в 2013 — внимание, магические услуги! O_o за ним идёт правительство с почти четырёхкратным отставанием. Это что, такая «чёрная ddos магия»? Или просто кармическое наказание для шОрлатанов?
  • Отличная картинка и фраза про «год фиолетового DNS» (DNS amplification): тут есть всё — и фиолетовые пони, и облака, и кирпичи высокой кристаллизации… А почему пони фиолетовый — это потому, что его уже просто больше нельзя бить, он сплошная гематома
    Год фиолетового DNS.jpg
  • Товарищ зачем-то ругал UDP, потому что типа «любой протокол без авторизации и с плечом ответа» может привести к такому же усилению. Что-то мне кажется, что глупо UDP ругать — не будет его, будет что-нибудь ещё. А вот ratelimit на публичных сервисах — это правильно, да.

История MySQL и MariaDB / Michael Widenius (Monty Program Ab)

Видениус забавен, говорит с совершенно аццким акцентом. Рассказывал просто обзор фич MariaDB (аналогично https://mariadb.com/kb/en/mariadb-versus-mysql-features/). Напоминаю, MariaDB — это такой правильный MySQL, который пишут в основном те же люди, что писали изначально, вместо индусов из Oracle. О чём Видениус и напомнил, сказав, что программисты оракла явно не совсем понимают код, над которым работают.

Хотел я у него спросить, что у них там происходит с движком Aria, но не успел :-(. Aria — это «безопасный MyISAM», который в будущем они планировали сделать и транзакционным. Интересно, насколько он развивается, и есть ли вообще смысл в том, чтобы делать из него транзакционный движок — есть подозрение, что с появлением транзакционности все его плюсы (которые были) растворятся, и получится ещё один InnoDB, тормозящий на вставках.

Оптимизатор запросов в MariaDB: теперь и без индексов! / Сергей Голубчик (Monty Program Ab)

Отличный доклад — разработчик марии рассказывал о том, как они недавно наконец-то запилили в MariaDB статистику, независимую от движка хранения.

Типа, раньше статистика полагалась на движок и на индексы, так как говорила движку: «оцени мне cardinality этого индекса», «сколько строк в таблице?», «сколько стоит фуллскан?». А движки врут. Ну, не то, чтобы явно врут, но бывает, что а) подкручивают значения так, чтобы получать нужные планы, и б) просто делают неточную оценку. В итоге, например, значения от разных движков вообще могут различаться.

А теперь сама мария умеет считать статистику по таблицам, индексам и даже колонкам (без индексов, ищет мин/макс, процент NULL, среднюю длину, обратную мощность и умеет считать гистограммы) путём ANALYZE, работающего через фулскан таблицы. Используются гистограммы равной высоты (то есть с неравномерной шкалой).

Нюансы, я так понял, такие: во-первых, надо иногда делать ANALYZE (само оно статистику не считает), во-вторых, часть оптимизаций полезна для «медленных» выполнений запроса, без индексов.

Из юмора:

  • Показывал пример с таблицами сотрудников — «вот, смотрите, это такой странный набор данных, где мало менеджеров…»
  • Ему задавали вопрос, он такой, «я не уверен что я понял запрос вопрос…» :D

Как рассуждать о производительности хранилищ баз данных / Mark Callaghan (Facebook)

А вот и ещё один доклад про всевозможные LSM-деревья, LevelDB и подобное. В принципе нормальный доклад, но не совсем про производительность, а именно что про «рассуждения».

А именно — про Write Amplification, Read Amplification и Space Amplification — то есть, про увеличение числа записанных/прочитанных/хранимых данных по сравнению с тем, что мы реально хотим записать/прочитать/хранить. Понятное дело, что зачастую Write Amplification есть у оборудования (например, SSD), у СУБД (redo/undo лог), ФС (мин. единица записи — 1 сектор). Space Amp: метаданные, фрагментация, старые версии данных… Read Amp: как раз относится ко всяким LSM, когда чтобы что-то прочитать, нужно сходить во все уровни. Типа, Write/Read Amp ограничивает производительность — она не может быть больше, чем максимальная скорость работы дисков делить на усиление.

А теперь примерные оценки этих значений:

Алгоритмpoint read-amprange read-ampwrite-ampspace-amp
B-дерево11..2page/row * GC1..2
LSM leveled1 + N*bloomN10*уровни1.1 X
LSM с N частями1 + N*bloomNвозможно < 10can be > 2
log-only (bitcask)1N1 / (1-%live)1 / %live
memtable+L1 (sophia)11размер БД/размер L01
memtable+L0+L1 (MaSM)1 + N*bloomN32
tokudb1210*уровни1.1 X

Примечания:

  • Это копия со слайда, только я про разные типы B-дерева опустил — у них всех один и тот же показатель. Разница только в сборке мусора
  • Если постоянно коммитить в B-деревьях, то Write Amp — очень большой (1 на лог + размер страницы делить на размер строки), есть нет — то меньше. Space Amp зачастую около 2, так как страницы держатся полными на ~60 %.

(10 — это типичная разница в размерах между уровнями)

В общем, интересно, но, в принципе, эти «усиления» далеко не всегда определяют производительность благодаря разнице в скорости последовательного и случайного ввода-вывода (и благодаря кэшу, кстати).

См. также linkbench в https://www.facebook.com/MySQLatFacebook

Cassandra vs. In-Memory Data Grid in eCommerce / Александр Соловьев (Grid Dynamics)

Рассказ о том, как они переводили некий продукт с хранилища в оперативной памяти (а конкретно это был Oracle Coherence In-Memory Data Grid) на Кассандру. Именно на неё, потому что у Mongo и HBase обнаружены SPOF, сложное развёртывание, и некоторые эксклюзивные блокировки. Плюс, кассандра умеет работать на несколько датацентров, что тоже было требованием.

Резюме — если данные влезают в память и если немного подтюнить кассандру — она, в принципе, практически так же производительна, как in-memory БД, ибо Linux’овый дисковый кэш работает хорошо.

У них была магическая цифра, с каждым тюном производительность росла на +15 % TPS :-D конкретно тюны были следующие:

  • Выключить swap
  • Commit log и данные — положить на разные диски
  • Асинхронные запросы по многим ключам + token-aware routing → ещё +15 % TPS
  • Юзать последнюю версию — с 1.2.6 на 1.2.8 → ещё +15 % TPS
  • Ключ «родительского» объекта как первый компонент составного ключа «дочернего» (группирует она их, видимо) → ещё +15 % TPS
  • Локальные кэши → ещё +15 % TPS

Сравнение распределенных файловых систем / Marian Marinov (1H Ltd.)

Доклад с качественным вдумчивым бенчмарком нескольких распределённых файловых систем (линуксовых, разумеется).

  • Сначала про ethernet контроллеры — из типичного гигабитного выжимается ~500 mbit всего лишь. Чтобы приблизиться к теоретическому лимиту (~920 mbit), нужно покупать дорогой контроллер.
  • Потом про ядро — почесать разные сетевые sysctl (см. презентацию: http://www.slideshare.net/profyclub_ru/marian-marinov), ethtool (всякие segmentation offload, receive offload)
  • Потом переходим к бенчмаркам: GlusterFS, XtremeFS, FhgFS, Tahoe-LAFS.
  • Итог — наилучший вариант это FhgFS, так как скорость хорошая и нет внезапных тормозов.

JIT компиляция в виртуальной машине Java / Алексей Рагозин

Тот же мэн, что рассказывал на SECR’е про Performance Test Driven Development. «Серия» из двух докладов, с общим названием «JVM Deep Dive» :-)

Первый доклад — про JIT.

  • Бывает классический JIT. Просто берёт код и компилит в машинный код перед запуском. Это .net, jvm, v8, ionmonkey.
  • Бывает трассирующий JIT (tracing JIT) — который сначала запускает в интерпретируемом варианте, а потом повторяющиеся куски («трассы») JIT’ит. Они получаются идеальные и без ветвлений совсем. Это flash, tracemonkey, pypy, luajit.
  • JIT в JVM (и официальной, и OpenJDK) довольно крутой. Он умеет разные оптимизации:
    • Умеет на лету inline’ить функции
    • Умеет заменять метод на стеке — в момент возврата из функции управление получает JIT, подменяет реализацию метода (вдруг заинлайнить что-то решил, например) и подменяет адрес возврата.
    • Умеет превращать простые объекты в наборы скаляров (типа Point = float x, float y).
    • Умеет инкрементальную компиляцию.
    • Умеет ликвидировать код синхронизации там, где он не нужен (если значение не утекает за пределы текущего вызова функции). Например, StringBuffer.
    • Умеет девиртуализацию функций (если вариантов нет) и инлайн final static членов класса.

Cборка мусора в Java без пауз / Алексей Рагозин

Второй доклад, тоже интересный, теперь про сборку мусора и про то, бывает ли она без пауз.

Резюме — нет, сборки мусора без пауз не бывает. Если очень много выделять памяти и не освобождать автоматически, в какой-то момент она всё равно кончится и придётся останавливать мир :-). А ещё — паузы можно уменьшить, и их отсутствие мало от чего спасёт — в real-time применениях всё равно найдётся ещё 100500 других проблем (свопинг, кривые руки и т.п).

Какие вообще есть алгоритмы сборки мусора?

  • Простейшее (mark&sweep) — остановили всех, прошлись рекурсивно по всем объектам, пометили достижимые, удалили остальные.
  • Concurrent mark&sweep с барьерами на запись: Немножко всех тормозим, находим корневые ссылки, потом всех возобновляем и маркируем достижимые объекты, потом всех приостанавливаем снова, перемаркируем то, что было изменено, опять всех возобновляем и удаляем отмеченное недостижимым. Барьер — это просто bitmap, который даёт нам понять, что же было изменено.
  • Разделение кучи на поколения — «старые» объекты живут долго и редко собираются, «молодые» — живут недолго и собираются часто.
  • Алгоритм «метроном» — сборка копированием с барьерами на чтение. Есть 2 области памяти: «старая» и «новая». Сначала все объекты в старой. Параллельным потоком включается сборка мусора, и начиная с этого момента, если поток при чтении видит, что объект в «старой» области — он его нерекурсивно копирует в новую и обновляет ссылку. Таким образом, код работает только с «новыми» объектами. Мусорщик параллельно тоже перемещает «старые» объекты в «новую» область памяти, обновляя ссылки. Процесс когда-то заканчивается. В общем-то идея хороша, но — накладные расходы немаленькие.
  • JVM-суперкомпьютер Azul Vega. По сути, хитрожопый вариант «метронома» с поколениями и аппаратной поддержкой, а именно — с дополнительными битами в адресах, служащими как барьеры (плюс для работы со слабыми ссылками). Но — физические JVM CPU делать невыгодно, они уже все почти повымерли, поэтому потом они сделали Azul JVM с той же идеей, которая использовала сначала виртуализацию, а потом и просто модуль ядра Linux x86-64 для поддержки этих самых бит. Ещё у неё есть 3 стратегии копирования — байтами (до 256 Кб), 4 Кб страницами (до 16 Мб), и 2 Мб страницами (> 16 Мб объекты).

См. также «шпаргалку» по сборке мусора в JVM от автора.


Любые правки этой статьи будут перезаписаны при следующем сеансе репликации. Если у вас есть серьезное замечание по тексту статьи, запишите его в раздел «discussion».


Репликация: База Знаний «Заказных Информ Систем» → «Highload-2013: Отчёт Виталия Филиппова»