Крадущийся сервер, затаившийся диод (Андрей Аксенов)

Preview:

Citation preview

Крадущийся сервер,затаившийся диод

Андрей Аксенов, Sphinx

КТО ЗДЕСЬ

• Зовут Андрей, резидент HL ;)• Делал вебню, игры, поиск• Знаю много страшных слов

• Сегодня про “скорость” в целом• Завтра про “поиск” в целом• Ничего нового, все украдено, explicit lyrics

Про скорость

• Как бенчмаркать– Как планировать эксперименты

• Как профайлить• Как планировать емкость

• Везде подразумевается прилагательное“ПРАВИЛЬНО”

Часть 1Бенчмарки

Нередкий бенчмарк

183.4 rps- vs -

2120.7 rps

Еще нередкий бенчмарк

Немного не хватает

Есть• 183.4 rps

Надо• Распределения• График во времени• Время отклика• HW конфигурация• SW параметры• Методология• Цели!

Внутри ОДНОЙ точки…

…бывает маленькая вселенная

А как надо?

Цели uber alles

• Сравнение двух “систем”– HW, SW, версии, конфигурации

• Нагрузочное тестирование• Планирование емкости• Проверка железа• Ликвидация ВНЕЗАПНЫХ проблем• Проверка регрессий, воспроизведение

проблем, и т.д.

Цели => метрики

• Только rps == только bandwidth– Например, диск под нагрузкой– Например, кассы в супермаркете

• Только latency == только best-case wait time– Например, 1 поток, когда надо 16 потоков

• Только loadavg == только queue length– Например, опять касса в супермаркете

Цели => агрегатные функции

• Только среднее == это вообще о ком??– avg ( 1 ms x 999 + 10000 ms x 1) = 11 ms– avg ( 1 ms x 500 + 1000 ms x 500) = 501 ms– Средняя температура по больнице

• Иногда впрочем годятся min, max– Планирование емкости– Планирование катастроф!!!– NB: только при соблюдении ограничений

Шок! Ежа не сменить на ужа!

• Разные метрики НЕ СВЯЗАНЫ• Померили rps, например• 4 ядра, 100 rps == bandwidth• Интуитивно, 10 ms / req == latency, так?• Интуитивно, на 8 ядрах 200 rps, так?

Шок! Ежа не сменить на ужа!

• #АВОТХРЕН• 100 rps => avg ( latency ) = 10 ms, ок– Увы, среднее не значит ничего– Min, max, median ( latency ) – какие угодно

• Cores x 2 => rps x ?– Масштабируемость нелинейна– Может и навредить! (RAM, disk trashing…)

Цели => план борьбы

• “У нас тормозит запрос, давай его оптимизить”

• Насколько станет быстрее?– Даже по малозначащему среднему?

• А ХРЕН ЕГО ЗНАЕТ– 1 ms x 999 + 10000 ms x 1 => ???– Вариант, avg ( 2 ms x 999 + 3000 ms x 1 ) = 5 ms– Вариант, avg ( 0.1 ms x 999 + 10000 ms ) = 10 ms

Как же быть???

Нельзя меритьrps

Нельзя меритьlatency

Нельзя меритьloadavg

Нельзя меритьiowait

Нельзя меритьus/sy/wa

нужно меритьВСЕ МЕТРИКИ

(целевые, а не loadavg)

нужно меритьРАСПРЕДЕЛЕНИЕ

(а не среднее по больнице)

Цели uber alles

• Представьте себя вебсайтом, например• Нужно много, bandwidth• Нужно быстро, latency• Нужно одновременно, конфликт!• Цель?– Типично max { bandwidth | latency<=L }– Бывает min { latency | bandwidth<=B }

Мерь распределения!

• Вот, например, латентность• Не особо годится avg ( latency )• Уже лучше– Percentile_50 ( latency ) = median– Percentile_80, _95, _99 ( latency )– Percentile_100 ( latency )= max, worst case– 95%, насколько это плохо?

• Совсем хорошо, график latency / bw( X )

Видь края!

• Помним про ограничения– Типично max { bandwidth | latency<=L }– Бывает min { latency | bandwidth<=B }

• global_max ( bw ), но зато latency 30 сек– Добро пожаловать на шоссе Энтузиастов!!!

• global_min ( latency ), но только при 5 rps– “Да я в 5 утра за 15 минут в Выхино домчал…”

Помни цель!

• Например, выбрать между системой A, B– В широком смысле!

• Выбрать софт– XyzDB или WtfSQL?

• Выбрать железо– Xeon или Opteron?

• Выбрать настройки– Конкретные buffer_pool_size, число тредов, итп

Часть 1.1План эксперимента

Мерь нужное!

• 10000 CREATE TABLE медленнее=> innodb отстой!

• Avg ( ReportLatency ) улучшилось в 3 раза=> хорошее изменение!

• 1000 x INSERT стал в 2 раза быстрее=> новый CPU рулит!

Но есть нюанс…

• 10000 CREATE TABLE медленнее=> а все остальное?

• Avg ( ReportLatency ) улучшилось в 3 раза=> жалко, все остальное ухудшилось в 2

• 1000 x INSERT стал в 2 раза быстрее=> вот только ядер в 4 раза меньше

Сравнивай сравнимое!

• Собственно, с чего возник доклад…• Срочно в номер, Sphinx в 100500 раз

медленнее Mamba!!!

Сравнивай сравнимое!

• Читаем внимательно• Sphinx, померили… full scan• Mamba, померили… “index” lookup• “Я мастерски соптимизировал запрос с 30

до 20 сек, ну а потом построил индекс”

Сравнивай сравнимое!

• Еще интересные варианты– Guilty as charged…

• Давайте померим отладочный билд!• Давайте оставим дефолтные настройки!• Давайте жахнем один запрос 1000 раз!

• Клади линейку с правильного края!!!• Исключение, маркетинг!!!

Часть 2Профайлинг

Типичная ситуация раз

• Штатный режим• В ходе разработки, плановые тесты• Бывает редко ;)• Методика – понятная– Сделали эксперимент (репрезентативный)– Собрали все подряд счетчики– Посмотрели, отыскали диод, повторили

Типичная ситуация два

• ААА ШЕФ ВСЕ ПРОПАЛО!!!

• Внезапный сбой• Паника!

Типичная ситуация два

• ААА ВСЕ ПРОПАЛО• Давление снаружи и изнутри черепа• Методика – такая же– Физику не обманешь– Правда, эксперимент уже в быстром полете

• Offtopic (?), “как обычно” – быстрее– А вот психику обманешь!

Стандартные тулзы

• Когда в разработке– обычно – gprof (C/C++), xdebug (php) итп– хардкор – нанобенчмарки, vtune!!!

• Когда режем по живому– ps, top, vmstat, iostat, mpstat, netstat, strace,

oprofile…• Когда идем по приборам– sar, munin, cacti, …

Нестандартные тулзы

• В приложении– Встроенные счетчики– Крайне желательно, последовательные

• Снаружи– kill –SEGV + gdb!

• В голове– Знание “мировых констант”– Арифметика и нюх!!!

Offtopic про мировые константы

• CPU, L1 ~ 1,000,000,000 ops 1e9• CPU, L2, misbranch ~ 100,000,000 ops 1e8• RAM access ~ 10,000,000 ops 1e7• ? 10x RAM accesses• SSD megaraid ~ 100,000 ops 1e5• SSD ~ 10,000 ops 1e4• LAN rt / 1MB RAM ~ 1,000 ops 1e3• HDD seek / 1MB LAN ~ 100 ops 1e2• WAN roundtrip ~ 10 ops 1e1

Кейс #1, тормоза… без нагрузки

• Sphinx, trunk, очередной апдейт• Под нагрузкой – все примерно ок• Без нагрузки – адская загрузка CPU• В общем – чуть (?) хуже

• strace, gdb=> pthread_mutex_timedlock + ошибочка!!!

Кейс #2, невидимый диод

• MySQL, prod• Внезапно, чудовищные тормоза– всех запросов– Были миллисекунды, стали минуты (!)

• Ничего не поменялось!– На работе никого, суббота

Кейс #2, исключаем глупое

• Живое железо (виртуализации нет)• Внешний SAN• Проверяем, что все запросы тормозят– SHOW PROCESSLIST, все так

• Проверяем, что SAN чувствует себя ок– Клиент проверил, SAN о сбоях не говорит

Кейс #2, смотрим всякое

• SHOW PROCESSLIST, vmstat, iostat– Запросы висят в commit– 100% утилизация IO, iowait, но все медленно– Видимо, CPU профайлить бесполезно

• stacktrace, strace, oprofile– Ничего подозрительного, см. бесполезно

• sar– В момент сбоя упали rtps, wtps, вырос iowait

Кейс #2, практически нашли!

• Выяснили, это IO подсистема!• Непростая, SAN по FC, много POF– DB сервер– Сам SAN– Соединение по FC– Диск на SAN

• Бенчмарк с другого сервера, все тоже плохо• И внезапно…

Кейс #2, совсем нашли

• Браузер закешировал статус!!!• На самом деле, там таки издох диск ;)

• Мораль – никому не верить ;)– Особенно людям– Даже своим глазам

Часть 3Предсказания

Самое интересное – совсем мало ;)

• Как предсказывать масштабируемость– Предсказываю, наверняка не уложусь по

времени!!!• Зачем? Планирование емкости, в тч. в полете• Ключевые слова– Little’s law– Amdahl’s law– Universal Scalability law– Линейная регрессия, очистка данных

Закон Литтла

• Concurrency = Throughput * Response• Клиенты = Прибытие * Обработка

• Все это средние за длинный период• 10 ядер, 0.5 сек с ядра = 5 клиентов

• В среднем!• Придет больше – будут стоять “клиенты”• Придет меньше – будут стоять “работники”

Закон Амдала

линейной масштабируемости

НЕ БЫВАЕТ

Закон Амдала

Закон Амдала

• 95% работы параллелится, но =>• 5% работы не параллелится (a = 0.05) =>• 20 раз максимум, причем недостижимый– 24 x CPU = 11.1 x– 48 x CPU = 14.3 x– 64 x CPU = 15.2 x

• C(N) = N / ( 1 + a*(N-1) )– C == Capacity

Закон масштабируемости

даже Амдаловой масштабируемости

НЕ БЫВАЕТ

Закон масштабируемости

Universal Scalability Law

• ASL (Gene Amdahl 1967)– C(N) = N / ( 1 + a*(N-1) )– a = степень contention (непараллелящееся)

• USL (Neil Gunther 1993) – C(N) = N / ( 1 + a*(N-1) + b*N*(N-1) )– b = степень coherency (consistency delay)– Общие данные надо синхронизировать :(

Практические выводы?

• Душить contention, улучшать параллелизм• Душить coherency, улучшать параллелизм– App mutex, DB lock, любой другой ресурс

• USL как бы говорит, есть sweet spot– Максимальная Capacity ( NumThreads / Boxes ) – Значит, его можно измерить– Значит, его можно смоделировать!

Итого.

Сводка про бенчмарки

• Помни о целях!• Не путай числа!rps != bandwidth)• Мерь нужное! 99% latency != avg rps• Не мерь среднее!• Мерь распределения!• Видь края-ограничения!• Сравнивай сравнимое!

Сводка про профайлинг

• Пользуй стандартные тулзы– vmstat, iostat, oprofile, ряд других– Обмеряем все типичные диоды– Проблема будет найдена

• Люби арифметику (ну хоть наблюдения)

• Ничего не боимся – см. психология• Никому не верим – см. практика!!!

Сводка про предсказания

• Линейной масштабируемости – нет• Сублинейной масштабируемости – нет• С ростом – может случиться хуже

• Можно померить – а можно предсказать!• Модель нетяжелая – регрессии рулят

Это почти все.

If you have eliminated the impossible,

whatever remains, however improbable,

must be the truth.

Это все.

Вопросы?

shodan@sphinxsearch.com

Recommended