Можно ли не делать ничего?
Ты не можешь управлять тем,
что не можешь измерить
Поиск проблем
Открываем черный ящик
Основные проблемы производительности
Подход к решению проблем
Сложность: найти причину плохой производительности
Откуда получить данные о системе?
SHOW
EXPLAIN
Слишком много
"сырых" данных
Визуализация + интерфейсы
Подход к решению проблем
Основные задачи системы мониторинга
/ Мониторинг с Prometheus, Grafana
Подход к решению проблем
Архитектура
/ Мониторинг с Prometheus, Grafana
Prometheus server
Targets
(exporters)
Data visualization and export:
Pull metrics
PromQL
Подход к решению проблем
Targets
(exporters)
Exporters
/ Мониторинг с Prometheus, Grafana
Exporter'ы - программы (GO) для сбора метрик из источников: операционная система, база данных (MySQL, PostreSQL), ...
Работает как процесс, слушает определенный порт и по HTTP запросу "выставляет" метрики.
mysqld_exporter может находиться на одной машине (контейнере), а мониторить другую (hello RDS).
...
mysqld_exporter может собирать разное количество метрик в зависимости от версии сервера MySQL и конфигурации.
Подход к решению проблем
Типы метрик
/ Мониторинг с Prometheus, Grafana
Counter
Gauge
Histogram
Количество 404 ошибок
Количество свободной оперативной памяти в текущий момент времени
Какой процент запросов было выполнено за время < 500 ms?
Подход к решению проблем
Визуализация данных
/ Мониторинг с Prometheus, Grafana
Достаточно данных
Подход к решению проблем
Как найти проблемные запросы?
/ Мониторинг с Prometheus, Grafana
Подход к решению проблем
Slow log
/ Проблемные запросы
# Time: 2020-05-25T20:50:53.399620Z # User@Host: root[root] @ [192.168.240.2] Id: 5333 # Query_time: 3.526603 Lock_time: 0.000147 Rows_sent: 20000 Rows_examined: 1987320 Thread_id: 5333 Errno: 0 Killed: 0 Bytes_received: 0 Bytes_sent: 10469146 Read_first: 1 Read_last: 0 Read_key: 1 Read_next: 0 Read_prev: 0 Read_rnd: 0 Read_rnd_next: 1987320 Sort_merge_passes: 0 Sort_range_count: 0 Sort_rows: 0 Sort_scan_count: 0 Created_tmp_disk_tables: 0 Created_tmp_tables: 0 Start: 2020-05-25T20:50:49.873017Z End: 2020-05-25T20:50:53.399620Z SET timestamp=1590439849; SELECT * FROM test_table_big WHERE number = '50' ORDER BY number LIMIT 20000;
...
Из нечитабельного текстового файла получаем конфету при помощи Anemometer !
Подход к решению проблем
Мониторинг с Anemometer и как он устроен?
/ Проблемные запросы
SELECT STATEMENT_DIGEST_TEXT('SELECT * FROM city WHERE ID = 130') AS digest;
SELECT * FROM `city` WHERE `ID` = ?
Получаем проблемный SQL запрос
Подход к решению проблем
EXPLAIN
/ Проблемные запросы
Достаточно добавить индекс
Подход к решению проблем
Почему возникает проблема?
/ Проблемные запросы
Как сделать быструю базу данных?
InnoDB buffer pool
Небольшой объем буфера (128 MB) + большое количество данных +
много запросов =
плохая производительность
Как правило, диск работает медленнее оперативной памяти
Подход к решению проблем
Создаем highload на ровном месте
2 таблицы:
CREATE TABLE `test_table_*` (
`id` int NOT NULL AUTO_INCREMENT,
`number` tinyint DEFAULT NULL,
`string_short` varchar(5) DEFAULT NULL,
`string_long` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
Table | Rows | Size |
---|---|---|
test_table_small | ~ 100 000 | ~ 70 MB |
test_table_big | ~ 4 000 000 | ~ 2.4 GB |
Нет индексов
(кроме PK)
/ Проблемные запросы
Можно ли с этим жить?
Buffer pool 128 MB
Нет, страдают все
Подход к решению проблем
Table | Query |
---|---|
test_table_small | SELECT AVG(number) FROM test_table_small WHERE number = ? |
test_table_big | SELECT * FROM test_table_big WHERE number = ? ORDER BY number LIMIT 20000 |
/ Проблемные запросы
Добавляем индекс
Но сначала замеряем производительность
Подход к решению проблем
Benchmarks
/ Проблемные запросы
Sysbench
Подход к решению проблем
Benchmarks, Sysbench
/ Проблемные запросы
> sysbench [options] [testname] [command]
Типичный тест состоит из команд:
call
Подход к решению проблем
--mysql-host=playground-db
--threads=1
--time=60
custom_insert_test
run
Результаты
/ Benchmarks, Sysbench
Operation | Threads | Events | Time, s |
SELECT | 1 | 10 | 61.6 |
SELECT | 10 | 46 | 74.4 |
INSERT | 1 | 7205 | 60.0 |
INSERT | 10 | 59382 | 59.83 |
Operation | Threads | Events | Time, s |
SELECT | 1 | 48 | 61.3 |
SELECT | 10 | 145 | 61.4 |
INSERT | 1 | 12601 | 59.7 |
INSERT | 10 | 46905 | 59.8 |
ALTER TABLE `playground-db`.`test_table_big` ADD INDEX `idx_number` (`number` ASC) VISIBLE;
Посмотрим на buffer pool, CPU
Подход к решению проблем
Что еще можно сделать?
/ Проблемные запросы
Увеличить buffer pool size до 4 GB
Подход к решению проблем
Результаты
/ Проблемные запросы
Operation | Threads | Events | Time, s |
SELECT | 1 | 704 | 60.01 |
SELECT | 10 | 1260 | 60.12 |
INSERT | 1 | 14158 | 59.66 |
INSERT | 10 | 56767 | 59.83 |
Operation | Threads | До | После ADD INDEX | После buffer pool size 4 GB |
SELECT | 1 | 10 | 48 | 704 |
SELECT | 10 | 46 | 145 | 1260 |
INSERT | 1 | 7205 | 12601 | 14158 |
INSERT | 10 | 59382 | 46905 | 56767 |
Общая таблица по events
Подход к решению проблем
Результаты
/ Проблемные запросы
Подход к решению проблем
Выводы
/ Проблемные запросы
Подход к решению проблем
Tips and tricks
Tips and tricks
Не всегда получается оптимизировать. Другие варианты
Спасибо
Ссылки
Запустить тестовый стенд из презентации можно локально:
https://github.com/helters/mysql-playground
https://habr.com/ru/company/southbridge/blog/455290/
https://github.com/akopytov/sysbench
https://github.com/prometheus/mysqld_exporter
https://hub.docker.com/r/boxinc/anemometer
https://github.com/grafana/grafana
https://github.com/percona/grafana-dashboard
https://www.percona.com/doc/percona-toolkit/LATEST/pt-query-digest.html