Изменения

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

62 040 байтов добавлено, 12:09, 11 декабря 2014
Новая страница: «Информация о конференции, организация: * Highload-2013, «Конференция разработчиков высоконагр…»
Информация о конференции, организация:
* 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).<br /> {{mag|Оптимизация: никогда не делайте его! (* кроме иногда)}}
* Distrust numbers. Especially your own.<br />{{mag|Числа недоверия. Особенно ваше собственное.}}

Ещё из смешного — доклад он начал со слов:
* 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 [https://github.com/twitter/finagle 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 на питоне, на основе сервера [http://www.tornadoweb.org/ Tornado]. DSL называется «Ясень», состоит из изолированных обработчиков (у которых на входе 1 объект и на выходе 1 объект) и довольно прост, умеет всего 3 вещи:
* Последовательные цепочки — выход одного обработчика скармливается другому
* Параллельные цепочки — выход одного обработчика скармливается набору других
* Отложенные цепочки — выход всегда равен входу, предназначены для побочных эффектов (логгирование и т. п.)
Цепочки запускаются внутри одного процесса, то есть даже никакие JSON’ы между серверами туда-сюда не гоняются. Каждый обработчик при этом можно дёрнуть извне, таким образом отлаживаясь.

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

'''Архитектура хранения''' — данные делятся на несколько видов:
* Мелкие справочники (например, валюты) — хранятся в памяти процесса на каждом сервере.
* Толстые справочники (> 1 мб) — хранятся в файловой key-value БД [http://fallabs.com/kyotocabinet/ kyotocabinet]. Она маппится в память процесса, соответственно, разделяется всеми процессами. Реплицируются на сервера с помощью, кажется, файловым репликатором [http://code.google.com/p/lsyncd/ lsyncd].
* Логи — всегда пишутся локально, а потом асинхронно перетаскиваются в глобальное хранилище.
* Динамические данные — пишутся на 2 redis-сервера для отказоустойчивости.

'''Какие есть процессы:'''
* «Пчёлы» — рабочие процессы, «муравьи» — те, что логи переносят, и локальное хранилище (плёлы и муравьи — это не я придумал, это у него в докладе так было).
* Ещё есть [http://haproxy.1wt.eu/ HAProxy] для распределения соединений, «многоножка» — интерфейс администрирования, и мониторинг [http://mmonit.com/monit/ 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) ===

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

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

LSM-деревья используются в библиотеке [http://code.google.com/p/leveldb/ LevelDB] от гугла, встраиваемой SQL БД [http://sqlite.org/src4/doc/trunk/www/design.wiki SQLite 4], в HBase, Wired Tiger и в NoSQL БД [http://cassandra.apache.org/ Apache Cassandra].

Во-вторых, '''Cache-oblivious структуры''' (общий термин, характеризующий то, что структуры эффективно используют кэш процессора, не зная его точного размера). Подход используется в новомодном движке хранения для MySQL — [[wikipedia:TokuDB|TokuDB]] (у них это называется [http://www.tokutek.com/2013/07/tokumx-fractal-treer-indexes-what-are-they/ Fractal Tree Indexes]). Идея в чём-то похожая — просто в каждом узле обычного B-дерева ещё поддерживается «буфер» для вставок, и вставляемые элементы сначала попадают туда, а уже потом сбрасываются в дочерние узлы. Засчёт этого скорость записи опять-таки увеличивается и не падает, даже когда индекс перестаёт влезать в память.

В-третьих, '''Bitcask''', используемый в [http://basho.com/riak/ Basho Riak]. Это вообще вещь тупая — данные всегда пишутся последовательно, хеш-индекс всегда держится в памяти.

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

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

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

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

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

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

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

== День 2 ==

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

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

Рассказывал про баги в сайтиках, через которые «всё поломать» не получится, но DoS устроить вполне можно. Часть идей была полным (или НЕполным) бредом:
* Бажные парсеры — типа бывают баги в парсерах (XML, CSV, входных параметров и т. п.), из-за которых оные зацикливаются. Утверждал бред, что если передать PHP параметр вида ?a[][][]…[][][], то он зациклится. Это конечно не отменяет того, что такие баги _возможны_, но явно не в этом месте.
* Ещё одна бредовая идея — чувак утверждал, что популярные новомодные «классификаторы» (типа [http://utinet.ru ютинетовского]) тормозят, если им выдать что-то непонятное («синий красный зелёный одновременно фиолетовый и вес меньше 100кг»). Дурь. С чего им тормозить? Разве что имеются ввиду движки, которые по условию (< 100кг) вытаскивают все возможные значения веса и ищут по множеству? Но и это к серьёзным тормозам не приведёт. Ютинетовский подтупливает, конечно, но он и в целом небыстрый… а на DoS в один запрос это как-то не тянет.
* Про переполнение хранилища сессий. Типа если сессии очень жирные (если там хранится вся история посещений со всеми полями запроса), то их туда можно накидать своих, и других людей не будет логинить, или если они в tmpfs, память кончится (что бред — tmpfs ограничен в размере). Но даже если всё так, то эксплуатировать довольно геморно — это надо реально долбить сервер запросами, иначе ваши «толстые» сессии всё равно будут вытесняться.
* А вот эта относится к классу «капитан ясен хрен»: вспомнил поиск по регэкспам в БД, которые при этом ещё и берутся из параметров запроса. Не, то есть я не против, PHP-сайтики много <abbr title="Сам Себе Злобный Буратино">ССЗБ</abbr> пишут — многие популярные движки, например, исполняемый код в базе хранят (битрикс, 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.
* Собственный вариант [https://github.com/danielgtaylor/qtfaststart qt-faststart] — скрипта, который перемещает MOOV Atom (заголовок видео) в начало файла (он в MP4 по дефолту в конце O_o), а также удаляет из него информацию о лишних keyframe’ах.
* Нюансы перепаковки: несколько качеств, в 15 % случаев требуется коррекция длительности.
* Чтобы всё это работало быстро, они, во-первых, напилили собственный кэш на своих [https://github.com/odnoklassniki/one-nio one-nio] и [https://github.com/odnoklassniki/shared-memory-cache unsafe кэше], в который всегда попадают все заголовки видео, плюс попадает само видео кусками по 256 Кб.
* Для кэша используется 96 Гб RAM и 4 ТБ SSD’шек на каждом сервере, плюс [http://obsproject.com/ 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): ''тут есть всё — и фиолетовые пони, и облака, и кирпичи высокой кристаллизации… А почему пони фиолетовый — это потому, что его уже просто больше нельзя бить, он сплошная гематома''<br />[[File:Год фиолетового DNS.jpg]]
* Товарищ зачем-то ругал UDP, потому что типа «любой протокол без авторизации и с плечом ответа» может привести к такому же усилению. Что-то мне кажется, что глупо UDP ругать — не будет его, будет что-нибудь ещё. А вот ratelimit на публичных сервисах — это правильно, да.

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

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

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

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

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

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

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

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

Из юмора:
* Показывал пример с таблицами сотрудников — «вот, смотрите, это такой странный набор данных, где мало менеджеров…»
* Ему задавали вопрос, он такой, «я не уверен что я понял <s>запрос</s> вопрос…» :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 ограничивает производительность — она не может быть больше, чем максимальная скорость работы дисков делить на усиление.

А теперь примерные оценки этих значений:
<tab sep="tab" class="wikitable" head="topleft" style="text-align: center">
Алгоритм point read-amp range read-amp write-amp space-amp
B-дерево 1 1..2 page/row * GC 1..2
LSM leveled 1 + N*bloom N 10*уровни 1.1 X
LSM с N частями 1 + N*bloom N возможно < 10 can be > 2
log-only (bitcask) 1 N 1 / (1-%live) 1 / %live
memtable+L1 (sophia) 1 1 размер БД/размер L0 1
memtable+L0+L1 (MaSM) 1 + N*bloom N 3 2
tokudb 1 2 10*уровни 1.1 X
</tab>

Примечания:
* Это копия со слайда, только я про разные типы 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 обнаружены <abbr title="Single Point Of Failure, единая точка отказа">SPOF</abbr>, сложное развёртывание, и некоторые эксклюзивные блокировки. Плюс, кассандра умеет работать на несколько датацентров, что тоже было требованием.

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

У них была магическая цифра, с каждым тюном производительность росла на +15 % TPS :-D конкретно тюны были следующие:
* Выключить swap
* Commit log и данные — положить на разные диски
* Асинхронные запросы по многим ключам + token-aware routing &rarr; ещё +15 % TPS
* Юзать последнюю версию — с 1.2.6 на 1.2.8 &rarr; ещё +15 % TPS
* Ключ «родительского» объекта как первый компонент составного ключа «дочернего» (группирует она их, видимо) &rarr; ещё +15 % TPS
* Локальные кэши &rarr; ещё +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 Мб объекты).

См. также «[http://blog.ragozin.info/2013/11/hotspot-jvm-garbage-collection-options.html шпаргалку]» по сборке мусора в JVM от автора.

{{replicate-from-custiswiki-to-lib}}
[[Категория:Конференции]]