Post on 11-Aug-2020
1
MySQL в жизни высоконагруженных финансовых приложенийФедорков В.В. Москва 2K20
2
О чем будем говорить?• О том как жить с MySQL когда даунтайм стоит очень дорого.
• О стабильности
• О производительности
• О настройках
• Об оптимизации запросов
• О том как жить с двумя датацентрами
• А так же о том, что один в поле не воин
ECOMMPAY Database Meetup, Москва 2020
3
Почему я об этом здесь говорю?• Занимаюсь производительностью систем на основе MySQL c 2006г.
• В Percona, Sphinx, PalominoDB и ProxySQL
• Первый раз попал в офис EcommPay в августе прошлого года
• С октября работаю в EcommPay
ECOMMPAY Database Meetup, Москва 2020
4
• 50+ серверов баз данных
• 40k+ QPS на одну машину
• 5Tb+ данных на одном сервере
• 50Tb+ бекапов в сутки
Что для нас высокие нагрузки?
ECOMMPAY Database Meetup, Москва 2020
5
Стабильность?• Работа DBA очень похожа на работу уборщицы
• Пока все чисто, нас не видно
• Если где-то грязь – это наша недоработка
• Если с базой проблемы – мы в центре событий!
• Отличие в том, что пол неровный, вместо тряпки зубило и все это
происходит в виртуальной среде.
• И по хорошему, наша задача сделать не просто что бы было чисто, а
так, что все успешно добежали до стенда тестирования куда им
нужно
ECOMMPAY Database Meetup, Москва 2020
6
Проактивная работа• Быстрая реакция на инциденты это база, без нее никак.
• Но стабильность прежде всего обеспечивается проактивной
работой
• Подготовкой инфраструктуры
• Анализом нагрузки
• Оптимизацией запросов
• Тестированием и бенчмарками
• Работой с новой функциональностью на стороне кода
ECOMMPAY Database Meetup, Москва 2020
7
Инфраструктура• NO Single Point of Failure вплоть до ДЦ
• Все ДБ сервера стоят в паре <мастер>-<реплика>
• Трафик балансируется между мастером и репликой
• Все работает на ржавом железе
• С виртуализацией только когда нагрузки позволяют
• Два датацентра на расстоянии 10ms друг от друга
ECOMMPAY Database Meetup, Москва 2020
8
Репликация – это боль• Данные между датацентрами должны быть синхронны
• Сбой репликации -> старые данные в ДЦ -> ошибки приложения
• Галера не помогает и даже немножечко вредит
• Поэтому двунаправленная классическая асинхронная репликация
• pt-slave-restart + Alerting = выбор чемпионов
• С последующим анализом логов
• И полуавтоматическим исправлением расхождений
ECOMMPAY Database Meetup, Москва 2020
9
Анализ ситуации – что собираем.• Алерты, логи и postmortem это не просто слова.
• Прыгать на те же грабли два раза - непозволительная роскошь
• Для MySQL собираются:
• Счетчики MySQL (графана, шаблоны PMM)
• Статистика нагрузки OS и железа
• Статистика запросов
• Все что медленнее 100ms немедленно логируется
• innodb_status_output и innodb_status_output_locks по необходимости
ECOMMPAY Database Meetup, Москва 2020
10
Визуализация необходимаДо визуализации
ECOMMPAY Database Meetup, Москва 2020
11
Визуализация необходимаПосле визуализации
ECOMMPAY Database Meetup, Москва 2020
12
Визуализация нагрузки• Шаблоны PMM перекрывают 99% ежедневных потребностей
• Запросы: чтение / запись / DDL / Admin / Prepared
• CPU: общая, прерывания, iowait
• IO: reads, writes, throughput, IOPS
• Network: in / out / connections / aborted / retransmition
• Гранулярность графиков – чем меньше, тем лучше видны
короткие всплески
• И тем сильнее тормозит графана
ECOMMPAY Database Meetup, Москва 2020
13
Анализ ситуации – нагрузка• Общий тренд нагрузки
• Всплески активности
• Ищем источники
• Кроны
• Очереди
• «Живые» пользователи
ECOMMPAY Database Meetup, Москва 2020
14
Нагрузка: где предел?
0
0.5
1
1.5
2
2.5
3
3.5
4
4.5
0
10
20
30
40
50
60
70
80
90
2 4 8 16 24 32 40 48 64 96 128 160 192 256 320
Врем
я о
тклика (
ms)
Запросы
(ты
сяч в
секунду)
Активные клиенты (потоки)
ECOMMPAY Database Meetup, Москва 2020
15
Анализ ситуации – запросы• Всплески «медленных запросов»
• Новый медленный запрос
• Старый медленный запрос
• Временный перегруз MySQL
• Сбой железа
• «Временные сетевые
затруднения»
• Детали – сначала в slow log’е
• Потом в кибане
ECOMMPAY Database Meetup, Москва 2020
16
Читал slow log – много думал # Schema: Database Last_errno: 0 Killed: 0# Query_time: 0.783257 Lock_time: 0.000305 Rows_sent: 360 Rows_examined: 399759 Rows_affected: 0
# Bytes_sent: 4764 Tmp_tables: 1 Tmp_disk_tables: 0 Tmp_table_sizes: 258064# InnoDB_trx_id: 10360A8176# QC_Hit: No Full_scan: No Full_join: No Tmp_table: Yes Tmp_table_on_disk: No# Filesort: Yes Filesort_on_disk: No Merge_passes: 0# InnoDB_IO_r_ops: 0 InnoDB_IO_r_bytes: 0 InnoDB_IO_r_wait: 0.000000# InnoDB_rec_lock_wait: 0.000000 InnoDB_queue_wait: 0.000000# InnoDB_pages_distinct: 5128SET timestamp=1980434228;SELECT DISTINCT id FROM (SELECT … xx.yy AS id, … FROM table xx WHERE xx.a = '181' AND xx.b = '1' AND xx.status = 'active') dctrn_result ORDER BY date1 DESC, date2 DESC LIMIT 18446744073709551615 OFFSET 0;
ECOMMPAY Database Meetup, Москва 2020
17
А что не так с этим запросом?# Schema: Database Last_errno: 0 Killed: 0# Query_time: 0.783257 Lock_time: 0.000305 Rows_sent: 360 Rows_examined: 399759 Rows_affected: 0
# Bytes_sent: 4764 Tmp_tables: 1 Tmp_disk_tables: 0 Tmp_table_sizes: 258064# InnoDB_trx_id: 10360A8176# QC_Hit: No Full_scan: No Full_join: No Tmp_table: Yes Tmp_table_on_disk: No# Filesort: Yes Filesort_on_disk: No Merge_passes: 0# InnoDB_IO_r_ops: 0 InnoDB_IO_r_bytes: 0 InnoDB_IO_r_wait: 0.000000# InnoDB_rec_lock_wait: 0.000000 InnoDB_queue_wait: 0.000000# InnoDB_pages_distinct: 5128SET timestamp=1980434228;SELECT DISTINCT id FROM (SELECT xx.a, xx.b, xx.e, xx.f, … xx.yy AS id, … FROM table xx WHERE xx.a = '181' AND xx.b = '1' AND xx.status = 'active') dctrn_resultORDER BY date1 DESC, date2 DESC LIMIT 18446744073709551615 OFFSET 0;
ECOMMPAY Database Meetup, Москва 2020
18
Главное оружие: EXPLAIN*************************** 1. row ***************************
id: 1select_type: SIMPLE
table: xxpartitions: NULL
type: refpossible_keys: PRIMARY, idx_a_b, idx_a_b_f_m, idx_a_b_c_d_status
key: idx_a_b_c_d_statuskey_len: 8
ref: const,constrows: 861300
filtered: 50.00Extra: Using index condition; Using where; Using temporary;
Using filesort1 row in set, 1 warning (0.01 sec)
ECOMMPAY Database Meetup, Москва 2020
19
Медленные запросы - индексыВыборка: a = ? AND b = ? AND c = ?
Индексы
1. (a,b,c)
2. (b,a,c)
3. (c,a,b)
4. (a,c)
равноценны?
ECOMMPAY Database Meetup, Москва 2020
20
Запросы - CardinalitySELECT COUNT(distinct a) as cnt FROM xx:
2444
SELECT COUNT(distinct b) as cnt FROM xx:
150
SELECT COUNT(distinct status) as cnt FROM xx:
2
ECOMMPAY Database Meetup, Москва 2020
21
Запросы – Selectivity: столбец aSELECT a, COUNT(*) as cnt FROM xx
0
100000
200000
300000
400000
500000
600000
700000
0 1000 2000 3000 4000 5000 6000 7000 8000 9000
Частоты значений А в таблице (всего 5121836 записей)
ECOMMPAY Database Meetup, Москва 2020
22
Запросы – Selectivity: столбец bSELECT b, COUNT(*) as cnt FROM xx
0
1000000
2000000
3000000
4000000
5000000
6000000
0 50 100 150 200 250 300 350
Частоты значений А в таблице (всего 5121836 записей)
ECOMMPAY Database Meetup, Москва 2020
23
Selectivity: statusSELECT status, COUNT(*) as cnt FROM xx
0
1000000
2000000
3000000
4000000
5000000
6000000
active deleted
Частоты значений status в таблице (всего 5121836 записей)
ECOMMPAY Database Meetup, Москва 2020
24
Выбор индекса• Первым ставим поле отсекающее наибольшую часть данных
• С учетом потенциальных «горячих» точек
• Учитываем сортировки
• Помним, что первичный ключ незримо присутствует
• Индекс не бесплатен
• Добавляет до нескольких процентов к времени вставки
• Увеличивает таблицу
• Могут быть варианты лучше
ECOMMPAY Database Meetup, Москва 2020
25
Все медленное починили!
ECOMMPAY Database Meetup, Москва 2020
26
Есть новости!!!• Тюнинга только медленных запросов – недостаточно.
• Большую часть времени базы могут тратить быстрые запросы
• Нужно включать полное логгирование.
ECOMMPAY Database Meetup, Москва 2020
27
Полное логирование• Может быстро закончится место на диске
• Может убить производительность диска
• Дает детальную статистику на момент сбора данных
• Позволяет быстро увидеть чем занят сервер
• Старый добрый pt-query-digest в помощь
ECOMMPAY Database Meetup, Москва 2020
28
Профиль нагрузки# Time range: 2020-01-32T12:21:40 to 2020-01-32T12:25:03# Attribute total min max avg 95% stddev median# ============ ======= ======= ======= ======= ======= ======= =======# Exec time 277s 1us 818ms 96us 287us 3ms 57us# Lock time 45s 0 810ms 15us 20us 3ms 0# Rows sent 1.99M 0 1.23k 0.73 0.99 9.34 0# Rows examine 13.91M 0 343.28k 5.09 0.99 562.38 0# Rows affecte 166.97k 0 1.00k 0.06 0.99 1.15 0# Bytes sent 1.97G 0 187.78k 739.72 2.89k 1.75k 88.31# Merge passes 0 0 0 0 0 0 0# Tmp tables 44.23k 0 1 0.02 0 0.12 0# Tmp disk tbl 1 0 1 0.00 0 0.00 0# Tmp tbl size 4.45G 0 758.05k 1.63k 0 19.62k 0# Query size 298.12M 6 9.91k 109.15 563.87 206.92 31.70# InnoDB:# IO r bytes 64.00k 0 16.00k 0.07 0 33.95 0# IO r ops 4 0 1 0.00 0 0.00 0# IO r wait 2ms 0 262us 0 0 0 0# pages distin 3.27M 1 6.68k 3.70 10.84 20.97 0.99# queue wait 0 0 0 0 0 0 0# rec lock wai 671ms 0 226ms 0 0 272us 0
ECOMMPAY Database Meetup, Москва 2020
29
Хит-парад запросов# Profile# Rank Query ID Response time Calls Item# ==== ================== ============== ======= ============# 1 0x99AA0165670CE848 126.4176 32.0% 1152741 UPDATE db1.table1# 2 0x813031B8BBC3B329 29.5214 7.5% 65293 COMMIT# 3 0x657B379F8BE9439C 24.5091 6.2% 42285 UPDATE db1.table2# 4 0x67BFB5AA766431E8 23.3710 5.9% 42285 INSERT db1.table1# 5 0x052BE56BFBD6FA86 14.1776 3.6% 106916 SELECT db2.table1# 6 0x111FD2D3F3B3B4EB 10.9522 2.8% 1152735 INSERT db1.table4# 7 0x64E0D90726CFA6DC 10.9052 2.8% 90148 SELECT db3.table1# 8 0x7CBD2A3E49D77CF5 9.2416 2.3% 39397 SELECT db1.table1# 9 0x2DF8D785B097BC96 7.0138 1.8% 62167 SELECT db1.table1# 10 0x70B45CDE756AA7F5 6.3765 1.6% 7450 SELECT UNION db1.table1 db1.table4# 11 0x4825E6154DD062DE 5.6855 1.4% 37583 SELECT # 12 0xC3698DA76656983A 5.1965 1.3% 54841 SELECT # 13 0x937FAF7CE7226811 4.8999 1.2% 33797 UPDATE
ECOMMPAY Database Meetup, Москва 2020
30
Хит-парад запросов# Query 3: 209.33 QPS, 0.12x concurrency, ID 0x657B379F8BE9439C at byte 699625474# This item is included in the report because it matches --limit. # Scores: V/M = 0.00 # Time range: 2020-01-32T12:21:43 to 2020-01-32T12:25:05 # Attribute pct total min max avg 95% stddev median # ============ === ======= ======= ======= ======= ======= ======= ======= # Count 1 42285 # Exec time 6 25s 83us 22ms 579us 799us 410us 541us # Lock time 3 1s 12us 4ms 26us 47us 38us 21us # Rows sent 0 0 0 0 0 0 0 0 # Rows examine 0 41.29k 1 1 1 1 0 1 # Rows affecte 18 41.29k 1 1 1 1 0 1 # Bytes sent 0 2.10M 52 52 52 52 0 52 # Merge passes 0 0 0 0 0 0 0 0 # Tmp tables 0 0 0 0 0 0 0 0 # Tmp disk tbl 0 0 0 0 0 0 0 0 # Tmp tbl size 0 0 0 0 0 0 0 0 # Query size 0 3.14M 75 80 77.99 76.28 0.13 76.28 # InnoDB: # IO r bytes 0 0 0 0 0 0 0 0 # IO r ops 0 0 0 0 0 0 0 0 # IO r wait 0 0 0 0 0 0 0 0UPDATE db1.table2 SET counter = counter + 1 WHERE shard = 12\G
ECOMMPAY Database Meetup, Москва 2020
31
Профайла нагрузки – недостаточно• В разных ДЦ запросы могут работать по-разному.
• Нужно ловить новые запросы
• pt-query-digest --review
• Нужно ловить изменение времени работы старых
• Потому что данные меняются
• В идеале нужно отлавливать резкие изменения данных
• Нужно понимать динамику изменений и прогнозировать нагрузку
ECOMMPAY Database Meetup, Москва 2020
32
Коммуникация – ключ к решению• Все знать – невозможно.
• Добавлять в тихую индексы – бестолково
• Разработчики знают как код ДОЛЖЕН работать
• Знают про новые функции
• Администраторы знают как он работает ПО ФАКТУ
• Сложность системы нужно последовательно уменьшать
• Не факт что функция нужна
• Не факт что все данные в таблице нужны
• Комплексные проблемы приложения в одиночку решить не
выйдет
ECOMMPAY Database Meetup, Москва 2020
33
Вопрос!
Можно ли тюнингом MySQL решить
проблемы производительности?
ECOMMPAY Database Meetup, Москва 2020
34
Тюнинг MySQL• Конфигурационных переменных: 574 (MySQL 5.7)
• Параметров файловой системы: 48 (ext4)
• Параметров ядра: 837 (sysctl -a)
• Файлов в /etc: 1986
• Кастомная сборка MySQL
• CPU & IRQ affinity, Timer interrupts и т.п.
• Собственноручно настроенное и скомпилированное ядро
• Переписанный scheduler операционной системы
ECOMMPAY Database Meetup, Москва 2020
35
Тюнинг MySQL• Если существенное время уходит на тюнинг – вы что-то делаете не так
• 5% настроек обеспечивают 95% производительности
• Чем меньше в конфиге – тем лучше.
• Что действительно нужно
• Память
• Сеть
• IO
• Репликация
ECOMMPAY Database Meetup, Москва 2020
36
Тюнинг MySQL: Память• innodb-buffer-pool-size
• innodb-buffer-pool-instances
• table-definition-cache
• table-open-cache
ECOMMPAY Database Meetup, Москва 2020
37
Тюнинг MySQL: Сеть• max-allowed-packet
• max-connect-errors
• skip-name-resolve
ECOMMPAY Database Meetup, Москва 2020
38
Тюнинг MySQL: IO• innodb-log-file-size
• innodb-log-files-in-group
• innodb-flush-log-at-trx-commit
• innodb_read_io_threads
• innodb_write_io_threads
• innodb_io_capacity
• innodb_io_capacity_max
ECOMMPAY Database Meetup, Москва 2020
39
Тюнинг MySQL: Репликация• log-bin
• server_id
• expire-logs-days
• sync-binlog
• GTID
• gtid_mode
• enforce_gtid_consistency
ECOMMPAY Database Meetup, Москва 2020
40
Минимизация времени downtime• В случае отказа реплики трафик перебрасывается на другую ноду
• В случае отказа мастера запись переключается на реплику
• Для контроля трафика используется балансировщик
• Размещение балансировщика прямо на клиенте решает несколько
задач
• Убирает SPoF на стороне хранилища данных
• Дает точную статистику использования базы по источнику
• Часть изменений в работе прямо сейчас
ECOMMPAY Database Meetup, Москва 2020
41
Хотите научиться – работать с MySQL– жить с высокими нагрузками– понимать как работают сложные финансовые информационные системы
Приходите к нам работать!