몇 주 동안 내 서버 중 하나의 성능 문제로 어려움을 겪고 있습니다.
구성: 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은 mysql에서 ~300queries/s입니다(따라서 CPU의 급증은 Apache 또는 mysql에서 정기적으로 많은 양의 요청과 연결되지 않는 것 같습니다).
나는 특히 느린 쿼리를 살펴보았습니다. SHOW PROCESSLIST를 수행해도 여전히 쿼리가 없습니다. 아파치도 마찬가지입니다. 최대 페이지 로드 시간은 1초 미만입니다.
apache2 서비스를 다시 시작하면 패턴이 몇 시간 동안 사라지는 것 같습니다. mysql 서비스를 다시 시작하면 몇 시간 동안 패턴도 사라지는 것 같습니다.
또한 이 db를 사용하는 몇 가지 다른 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
내 아파치는 기본 구성과 거의 동일합니다(약 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
기한이 만료되었습니다.