几个星期以来,我一直在努力解决我的一台服务器的性能问题。
配置:配备 Ubuntu 16.04、Mysql 5.7.21(全部为 MyISAM)、Apache 2.4.18(mpm prefork)、Php 7.0.25 的专用服务器。128GB 内存
CPU 使用模式确实很奇怪,我找不到任何可以解释它的东西。 https://i.stack.imgur.com/88VMm.jpg
如您所见,CPU 使用率有连续的水平,这些水平相当稳定。此外,当 Apache CPU 使用率增加时,Mysql CPU 使用率也会增加,而当一个减少时,另一个也会减少。此外,如您所见,整个差异发生在 CPU 系统使用率上。
我查看了 mysql 的查询数/秒,它基本上是恒定的。apache2 上的请求数/秒也是如此。相当恒定。顺便说一句,apache 服务器大约需要 100 个请求/秒,mysql 大约需要 300 个查询/秒(因此 CPU 的峰值似乎与 apache 或 mysql 上的常规高请求量无关)
我查看了慢查询,没有什么特别的。当我执行 SHOW PROCESSLIST 时,没有查询仍然存在。Apache 也是如此。最大页面加载时间小于 1 秒。
当我重启 apache2 服务时,该模式似乎消失了几个小时。当我重启 mysql 服务时,该模式似乎也消失了几个小时。
此外,我还有一些其他 Java 服务也使用此数据库(使用最新的 JDBC 驱动程序,我没有看到任何 CPU 模式变化)。它们最初在服务启动时创建与 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
我刚刚注意到,在那些“高系统 CPU”阶段,我在isolate_freepages_block中占用了很高的 CPU 百分比(我使用 得到这个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 # 以减少 RAM 占用 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
您重新发布它们(它们已经过期)。