Доклад от Parallels:
Методики тестировния производительности database-centric приложений
Описание: При работе над сложными продуктами в database-centric приложениях изменения в коде и тем более в SQL запросах к базе данных могут приводить к неожиданным падениям производительности или же деградации производительности приложения с ростом размера базы данных. Поэтому важно уметь как можно быстрее отлавливать и исправлять причины таких деградаций.
Доклад о том, как устроен процесс мониторинга производительности продукта автоматизации хостинга и облачных сервисов Parallels Automation, для которого определяющим фактором является производительность базы данных.
Компания покажет, как анализирует планы исполнения SQL запросов внутри PostgreSQL, как проверяет насколько быстро и эффективно в целом работают SQL запросы, как определяет стратегию дальнейшей оптимизации.
1. Profit from the Cloud
TM
23 Декабря 2014
Александр Андреев
Методики тестировния производительности
database-centric приложений
на базе продукта Parallels Automation и PostgreSQL
2. Profit from the Cloud
TM
• поделимся своим опытом тестирования производительности
database-centric приложения со структурой данных в виде графа
О чём доклад?
3. 3 Profit from the Cloud
TM
Cross-platform (Virtualization)
• Parallels Desktop (for Mac)
• Parallels Access (iPhone, Android)
Server Virtualization
• Parallels Cloud Server
• Parallels Cloud Storage
• Parallels Containers for Windows
SAAS solutions for service providers
• Plesk
• Plesk Automation
• Parallels Automation
Продукты Parallels
4. 4 Profit from the Cloud
TM
Services
Services
Что такое “Parallels Automation”?
Parallels Automation
(продукт для сервис провайдеров)
Services
Services
Services
Payment
systems
Основные бизнес-функции Parallels Automation:
• Деплоймент сервисов (локальных или удалённых)
• Менеджмент сервисов, аккаунтов и подписок на сервисы
• Фоновые задачи (сбор статистики, отчётов)
• Биллинг
• Интеграция с различными Payment Systems
• предоставление внешнего API для интеграции с другими системами
• shared hosting
• domain hosting
• qMail / Exchange
• O365
• ... +400 more
• VISA
• MasterCard
• PayPal
• ... +100 more
• аккаунты / пользователи
• сервисные планы
• подписки на сервисы
APIAPI
5. 5 Profit from the Cloud
TM
Resources
(Website)
APS2 Graph Data Model used in APS2
User #1
(Иван, сисадмин)
User #2
(Мария, бухгалтер)
Account #1
(ООО Цветочный
магазин)
User #3
(Илья, программист)
User #5
(Виктор, юрист)
User #4
(Василий, сисадмин)
User #6
(Елена, директор)
Account #2
(ЗАО Вебстудия)
Service #1
(Shared Hosting)
Service #2
(Exchange)
“disk space”: “10GB”,
“template”: “standard”,
“backup schedule”: “none”
...
“address”: “url”,
...
“platform”: “Linux”,
...
Resources
(Website)
Resource
(Website)
“disk space”: “10GB”,
“spam filter”: “yes”
...
Resources
(Mailbox)
Resource
(Mailbox)
6. 6 Profit from the Cloud
TM
Parallels Automation actors (security principals)
Parallels Automation
Application
(i.e. Service)
Anonymous
Registered
User
Provider
Reseller
7. 7 Profit from the Cloud
TM
Resource representation
• Рёбра графа определяют его структуру и “visibility” / “security” для actor’ов
Resource
Property
Links
Scoping
Structure
*
**
Все ресурсы
Фильтр по
property (что
actor хочет
видеть)
Видимые
ресурсы
Фильтр по
security (что actor
может видеть)
Выборка подграфа
ресурсов требует
как минимум 2
фильтров
• каждый из фильтров может выгребать огромные данные в зависимости от actor’a,
даже если пересечение мало!
• SQL оптимизатор иногда сваливается в full scan -> получаем слабую
производительность
8. 8 Profit from the Cloud
TM
• хранить графы
• у нас разные actor’ы / security principal’ы
• рёбра графа определяют visibility и security
• schema-less (из-за зоопарка сервисов на APS2)
• до 1-3 миллионов users в одной системе
• поддержка сложного внешнего API (REST + RQL + security principal tokens)
• кросс-платформенность (Linux, Windows)
Итого, что нам нужно?
Возможно стоило бы попробовать MongoDB, или “graph
database” или “RDF database”...
но решили оставить PostgreSQL!!!
• помимо графа есть большое количество стандартных реляционных данных
• важна надёжность, производительность, поддержка, тулзы, etc.
9. 9 Profit from the Cloud
TM
• 20 таблиц под хранение всего графа
• пока никаких application-level кэшей
• почти нет денормализации
• никакого ORM (только SQL abstraction layer for C++)
• при 1 миллионе users имеем:
• до 20 миллионов строк в некоторых таблицах
• база до 100GB на диске, включая индексы
• SQL запросы иногда под 300 строк
Что получили в итоге?
Странно, но всё работает достаточно хорошо,
правда есть проблема – “хрупкость кода”...
• Parallels Automation – это платформа, соответственно
большое количество комбинаций и corner cases
• любой патч может внести деградацию в неожиданном
месте из-за generic data access pattern
Качественное тестирование – очень важно!
10. 10 Profit from the Cloud
TM
• Разбиваем на простейшие бизнес сценарии, например у нас это:
• создание аккаунта и пользователей
• развёртывание сервиса (создание web-сайта, создание mail box’a, etc)
• пользовательские сценарии в web-UI
• login/logout
• стандартные и часто используемые внешние API запросы
• Разбираемся с бизнес требованиями
• какое ожидается максимальное кол-во пользователей?
• какая ожидается нагрузка на систему по каждому сценарию?
• Пишем удобные тесты на каждый бизнес сценарий
• стандартный command line и output у всех тестов
• лучше иметь отдельно тесты, отдельно “запускач” и “генератор отчётов”
• Обеспечиваем удобный/автоматический поиск узких мест
• логирование входа/выхода во всех методах в коде и SQL запросов
• пишем умный log анализатор для логов Parallels Automation
• используем auto_explain в postgresql для медленных запросов (>100 ms)
• собираем автоматом статистику ядра /proc/
• собираем статистику postgresql (расскажем далее)
Как тестировать производительность продукта?
11. 11 Profit from the Cloud
TM
Результаты тестов производительности зависят от многих
факторов
а также
• от версий софта; настроек; характеристик железа...
В идеале нужно тестировать множество комбинаций, но это долго!
12. 12 Profit from the Cloud
TM
• Запускаем тесты на все бизнес функции
• В основном тестируем throughput, сразу на мощном железе, сразу на большой базе
• Если что-то медленно, но удовлетворяет требованиям – то ничего не делаем
• Начинаем с наиболее медленных, но в то же время наиболее важных сценариев
• Находим “узкое” место в коде (например по логам или с помощью профайлера)
• Сначала разбираемся “что делает этот код” и можно ли его “почистить”?
• Оптимизируем “вертикально” до разумного предела
• Если всё-равно медленно, думаем про “горизонтальное” масштабирование
• начинаем сначала
Общая стратегия оптимизации
Усилия
Ускорение
20%
80%
принцип Парето
“20% усилий дают 80% результата”
Бесконечная оптимизация стоит бесконечных денег
13. 13 Profit from the Cloud
TM
Методика “быстрого” тестирования
Кол-во пользователей в базе
Производительность
Сценарий #1. Создание пользователей
Кол-во пользователей в базе
Производительность
Кол-во пользователей в базе
Производительность
Сценарий #2. скорость загрузки Home screen
Сценарий #3. скорость покупки подписки
1Mil
1Mil
1Mil
требование
Забиваем баг, разбираемся с проблемой, фиксим,
накатываем новый билд продукта поверх той же DB опять всё плохо, опять разбираемся
14. 14 Profit from the Cloud
TM
Методика “быстрого” тестирования
15. 15 Profit from the Cloud
TM
• основные принципы
• “быстро отсекаем лишнее”
• нагружаем систему по максимуму и должны увидеть 100% CPU usage in user space
• какой ресурс узкое место: CPU, disk, network, RAM? Запускаем “vmstat 1”
• если “bi”, “bo” большие – то много IO
o кто генерит нагрузку? – “iotop”
o какой IO pattern, какой у нас fsync rate? – “blktrace -d /dev/sdXXX -o - | blkparse -i –”
o вся ли база влезла в RAM?
o помогает ли отключение sync? mount -o remount,barrier=0 /my/mount/point
• если “sy” большое – то много сидим в ядре
o что делает ядро? – используем “perf” или “oprofile”. Обычно это context switch, page fault
• если “id” большое, но у нас запущено много параллельных тестов на системе:
o скорее всего есть локи в приложении
o или на уровне базы данных: https://wiki.postgresql.org/wiki/Lock_Monitoring
• наиболее эффективный способ
• добавить логирование на вход-выход из функции (или использовать gprof)
• написать интеллектуальный log анализатор
• в database-centric приложениях узкое место - сервер БД
• тулзы – pg-top, pg-stat, pg-info
• активно используем EXPLAIN, auto_explain в postgresql
Поиск узких мест
16. 16 Profit from the Cloud
TM
Пример “умного” лог-анализатора
17. 17 Profit from the Cloud
TM
Что полезного в лог-анализаторах?
• суммарный подсчёт времени
• wall time (общее время по “настенным часам”)
• total call time (общее время всех вызовов всех методов; >= wall time)
• total SQL time (можно быстро понять где узкое место – SQL или APP?)
• дерево вызовов
• дерево всех вызовов включая SQL запросы
• чистое время вызова
• полное время (с учётом всех вложенных вызовов)
• общая статистика
• список наиболее медленных внешних вызовов
• список наиболее медленных внутренних методов/вызовов
• список наиболее медленных SQL запросов
• список одинаковых SQL запросов
• оффлайновость
• можно анализировать логи с production систем
18. 18 Profit from the Cloud
TM
pg-top – аналог “top”, но для таблиц postgresql
• смотрим что происходит с таблицами в реальном времени
• writes, inserts, deletes, updates, index update, index scan, seq scan, etc
• можно сортировать по колонкам, ставить на паузу, etc.
Например, можно быстро понять что происходит при каком-то тесте
19. 19 Profit from the Cloud
TM
pg-stat – аналог “vmstat”, но для postgresql
• смотрим что происходит в общем и целом с базой в реальном времени
• writes, inserts, deletes, updates, index update, index scan, seq scan, etc
• как и в vmstat видим “шлейф” статистики
20. 20 Profit from the Cloud
TM
pg-info – быстрая информация по базе
• общая информацию по базе - размер данных и индексов на диске
• размер таблиц по убыванию
• часто/редко используемые индексы
• часто/редко используемые/изменяемые таблицы
21. 21 Profit from the Cloud
TM
Типичные “простые” проблемы на уровне SQL
• отсутствие индексов, лишние индексы, база не влезает в RAM
• легко понять с помощью встроенной postgresql статистики (pg-top, pg-info)
• SELECT (вложенный) оперирующий большой таблицей содержит !=, >,
>=, <, <=
• Финальная выборка как правило всегда маленькая, но внутренняя фильтрация (вложенные
SELECT) могут оперировать большими данными
• UNION вместо UNION ALL
• лишняя сортировка и исключение дубликатов
• SELECT user_name FROM Users WHERE LEFT(user_name, 1) = ‘A’
• индексы не работают
• заменяем на: WHERE user_name LIKE ‘A%’
• ... ТЫСЯЧИ ИХ!
22. 22 Profit from the Cloud
TM
Более сложные проблемы...
• заранее может быть неизвестно, какой из подзапросов (фильтров по property и security)
нужно применить раньше. Вся надежда только на оптимизатор запросов
• другие чудеса (свежайшая проблема)
SELECT ai.uuid, ai.app_instance_id, ai.app_id, app_ver, service_instance_id AS root_service_instance_id,
uri, app_conf_id, ai.prov_type, a.name,
CASE WHEN a.icon_name IS NULL OR a.icon_name = '' THEN '' ELSE
COALESCE(a.images_root_path,'') || a.icon_name END AS app_icon_name,
master_app_instance_id, ai.owner_id, resource_id, sr.sub_id, ai.status, si.disabled, si.unprovided
FROM aps_application_instances ai
LEFT JOIN aps_service_instances si ON ai.app_instance_id = si.app_instance_id
AND service_instance_id =
(SELECT service_instance_id
FROM aps_service_instances
WHERE app_instance_id = ai.app_instance_id
ORDER BY service_instance_id LIMIT 1)
JOIN aps_applications a ON ai.app_id = a.app_id
LEFT JOIN subs_resources sr ON ai.resource_id = sr.rt_instance_id
WHERE ai.app_instance_id = ?
ORDER BY ai.app_instance_id
если ? = 15, получаем <10 msec. http://explain.depesz.com/s/sr9
если ? = 20, получаем 4.8 sec http://explain.depesz.com/s/3nGj
24. 24 Profit from the Cloud
TM
Тот же запрос, другой параметр, медленный план
25. 25 Profit from the Cloud
TM
Итого
• хранить графы в PostgreSQL - это реально (даже на postgresql-9.1)
• 1 Млн юзеров, 100 Млн вершин в графе
• правда нам нужно всего 300 параллельных UI cессий, 100 UI кликов в секунду
• на QA ложится большая нагрузка
• нужно понимать основные бизнес сценарии
• аккуратно тестировать пограничные случаи
• быстро находить bottleneck
• чем круче ваш “tools set”, тем выше в итоге скорость баг фиксинга
• vmstat, top, iotop, perf, oprofile, blktrace,
iostathttp://www.brendangregg.com/Perf/linuxperftools.png
• EXPLAIN, EXPLAIN ANALYZE - http://explain.depesz.com/
• pg-top, pg-info, pg-stat – https://github.com/CloudServer/postgresql-perf-tools
• log analyzers rulez!
• charts help!
• простые рекомендации
• вся база должна быть в RAM
• для ускорения сommit’ов используем SAN storage, в крайнем случае RAID с BBU
• для быстрой проверки иногда можно отключить sync
• крутим настройки postgresql (pg_tune)
26. 26 Profit from the Cloud
TM
Спасибо!
Ваш фидбэк будет крайне полезен!!!
aandreev@parallels.com
наши тулзы:
https://github.com/CloudServer/postgresql-perf-tools