Я уже несколько недель борюсь с проблемой производительности на одном из моих серверов.
Конфигурация: выделенный сервер с Ubuntu 16.04, Mysql 5.7.21 (все MyISAM), Apache 2.4.18 (mpm prefork), PHP 7.0.25. 128 ГБ ОЗУ
Модель использования процессора действительно странная, и я не нашел ничего, что могло бы ее объяснить. https://i.stack.imgur.com/88VMm.jpg
Как вы можете видеть, есть эти последовательные уровни использования процессора, которые довольно постоянны. Кроме того, когда Apache cpu usages увеличивается, Mysql usage cpu увеличивается, а когда один уменьшается, другой уменьшается. Кроме того, как вы можете видеть, вся разница происходит в использовании процессора системой.
Я посмотрел на количество запросов/сек mysql, которое в основном постоянно. То же самое касается количества запросов/сек на apache2. Довольно постоянно. Кстати, сервер apache берет около 100 запросов/сек, а mysql — ~300 запросов/сек на mysql (так что скачки в процессоре, похоже, не связаны с регулярным большим количеством запросов на apache или mysql)
Я посмотрел на медленные запросы, ничего особенного. Когда я делаю SHOW PROCESSLIST, ни один запрос не появляется. То же самое и для apache. Максимальное время загрузки страницы <1 с.
Когда я перезапускаю службу apache2, шаблон, похоже, исчезает на несколько часов. Когда я перезапускаю службу mysql, шаблон, похоже, исчезает также на несколько часов.
Кроме того, у меня есть несколько других служб Java, которые также используют эту базу данных (используя последний драйвер JDBC, и я не вижу никаких изменений в шаблоне ЦП с ними). Изначально они создавали свое соединение с MySQL при запуске служб, но я изменил это поведение, чтобы закрывать соединение/запускать новое каждые 5 минут... Это ничего не изменило
Мой файл my.cnf:
[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0
[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address = 0.0.0.0
key_buffer_size = 36G
max_allowed_packet = 64M
tmp_table_size = 256M
max_heap_table_size = 256M
max_connections = 512
table_open_cache = 8192
bulk_insert_buffer_size = 512M
thread_stack = 192K
thread_cache_size = 8
sort_buffer_size = 64M
myisam_sort_buffer_size = 64M
myisam-recover-options = BACKUP
query_cache_limit = 1M
query_cache_size = 16M
log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 100M
[isamchk]
key_buffer_size = 36G
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M
У моего Apache практически стандартная конфигурация, за исключением того, что (я могу использовать около 350 рабочих процессов, поэтому я и установил это значение)
MaxRequestWorkers 1024
ServerLimit 1024
Я действительно не уверен, что делать дальше в расследовании.
Есть идеи, что может пойти не так?
Спасибо !
Редактировать: Я не увидел ничего подозрительного в журналах Apache или MySQL.
Редактировать: Некоторые данные, заданные в комментариях
ulimit -a:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 514833
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 50000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 514833
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
iostat -x
Linux 4.4.0-112-generic (ns340707.ip-37-187-250.eu) 02/21/2018 _x86_64_ (12 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
14.89 0.29 10.42 1.41 0.00 72.98
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sdb 0.70 51.90 18.37 11.86 1179.98 1894.25 203.33 1.40 46.40 10.29 102.33 2.35 7.11
sda 0.73 51.89 25.27 11.87 1847.55 1894.25 201.50 1.22 32.72 4.37 93.05 2.14 7.93
md0 0.00 0.00 9.63 62.19 758.90 1889.96 73.77 0.00 0.00 0.00 0.00 0.00 0.00
nvme1n1 0.00 0.00 429.64 1214.09 4755.77 6215.04 13.35 0.36 0.19 0.18 0.19 0.03 5.00
md2 0.00 0.00 1567.33 1204.69 14913.87 6204.69 15.24 0.00 0.00 0.00 0.00 0.00 0.00
nvme0n1 0.00 0.00 1204.85 1215.25 10676.20 6219.68 13.96 1.57 0.62 0.14 1.10 0.05 11.93
ПОКАЗАТЬ ГЛОБАЛЬНЫЙ СТАТУС ->https://pastebin.com/AehMqQQq
ПОКАЗАТЬ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ->https://pastebin.com/JyGquqFx
Вывод тюнера Mysql:https://pastebin.com/F8wvbHec
Я только что заметил, что во время фазы «высокой загрузки ЦП» у меня высокий % ЦП в isolate_freepages_block(Я получил это с помощью perf top
). Тем не менее, я не уверен, как решить эту проблему
решение1
Это все динамические переменные, которые можно задать с помощью SET GLOBAL xxx=xxx; пожалуйста, следуйте требуемому порядку. Если вы делаете только ОДНУ переменную в день, выключите и перезапустите, вам понадобится много дней, но затем вы работаете очень хорошо.
ИССЛЕДУЙТЕ и продолжайте, пока позволяет время, странная модель использования, скорее всего, исчезнет в течение этого цикла настройки.
Предложения по разделу my.cnf/ini [mysqld]
max_connections=325 #from 512 to support 270 max_used_connections
#max_allowed_packet=64M # lead for 1M default WHEN YOU NEED more
в начале СЕССИИ, только когда вам это нужно, SET @max_allowed_packet=67108864 # для уменьшения объема оперативной памяти MySQLTuner сообщил
query_cache_size=0 # from 16M, not being used, conserve RAM
query_cache_limit=1K # from 1M, conserve RAM
query_cache_min_res_unit=512 #from 4096, for > results stored, if ever used
thread_cache_size=100 # from 8 to reduce ~ 240,000 threads_created a day
следующие 3 (выполнить все 3 в один день) улучшат управление MyISAM key_buffer
key_cache_division_limit=50 # from 100 default for Hot/Warm separation
key_cache_block_size=64K # from 1K let's clear more RAM when full
key_cache_age_threshold=64800 # from 300 KEEP 18 HRS vs 5M to reduce RD RPS
innodb_lru_scan_depth=128 # from 1024 to conserve CPU cycles
innodb_stats_sample_pages=32 # from 8 to improve statistics cardinality
max_seeks_for_key=32 # from a huge # to limit OPTIMIZER depth
max_write_lock_count=16 # from a huge # to allow RD after NN write locks
table_open_cache=16000 # from 8192 to support ~ 350,000 opened_tables daily
Если у вас есть SSD, возможностей больше. Спросил в комментарии день или около того назад.
решение2
- Переключитесь с MyISAM на InnoDB. (И измените
key_buffer_size
иinnodb_buffer_pool_size
.) - Ниже
MaxRequestWorkers 1024
иmax_connections = 512
-- Лучше не пускать новых людей в продуктовый магазин, чем заполнить его настолько, что никто не сможет двигаться. Даже270 Max_used_connections
может означать «громовое стадо». - Кэш запросов — этовероятновредит больше, чем помогает. В загруженных производственных системах, с большим количествомпишет, QC нужно много промывать. Поэтому, независимо от других тестов, измените на
query_cache_type=0
иquery_cache_size=0
. - Проверьте сборку мусора Java.
Я с радостью рассмотрю их SHOW GLOBAL STATUS;
и SHOW VARIABLES
опубликую снова (срок их действия истек).