幾週來我一直在努力解決我的一台伺服器上的效能問題。
配置:專用伺服器,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 伺服器大約需要 100req/s,mysql 大約需要 300queries/s(因此 cpu 的峰值似乎與 apache 或 mysql 上的常規大量請求無關)
我查看了慢速查詢,沒有什麼特別的。當我執行 SHOW PROCESSLIST 時,沒有查詢仍然存在。對於阿帕契來說也是如此。最大頁面載入時間<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
重新發布它們(它們已過期)。