매일 밤 12시가 가까워지면 교통 정체로 인해 속도가 느려지나요?

매일 밤 12시가 가까워지면 교통 정체로 인해 속도가 느려지나요?

느린 로그를 확인했는데 2시간 동안 4개의 쿼리만 받았는데 모두 다음과 유사했습니다.

"SELECT HEX(uhash) AS uhash, vehid, IF(deleted = 0 AND follow_price_drop = 1, 1, 0) AS follow_price_drop, email, deleted 
       FROM wp_ product_favorite_count AS cfc 
       INNER JOIN wp_ product_favorite_user AS cfu ON cfc. product_favorite_user_uhash = cfu.uhash
       WHERE cfc.updated > '2021-09-23 12:49:02' OR cfu.updated > '2021-09-23 12:49:02'"

나는 top과 htop을 확인했고 종종 6개의 CPU 코어 모두에서 100 CPU 사용량을 얻었습니다.

대부분의 CPU 사용량은 mysqld에서 발생하므로 db를 기록했습니다.

https://pastebin.com/BBv7ngW5

iostat -xm 5 3은 나에게 다음을 제공했습니다:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          11.34    0.01    1.80    1.13    0.08   85.65

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda             39.75   720.61   79.81  192.29     0.99     3.57    34.30     0.02    0.09    0.19    0.04   0.09   2.53

^[[A^[[A^[[Aavg-cpu:  %user   %nice %system %iowait  %steal   %idle
          84.15    0.00    6.16    0.05    0.03    9.61

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.80    31.00   14.40   19.80     0.65     0.20    50.95     0.02    0.73    0.93    0.58   0.43   1.48

^[[A^[[Bavg-cpu:  %user   %nice %system %iowait  %steal   %idle
          84.54    0.00    4.95    0.10    0.05   10.36

Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.00     2.40   22.60    1.60     1.77     0.02   151.40     0.02    1.02    1.04    0.75   0.64   1.56

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) 128341
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 128341
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

느린 쿼리 로그를 확인한 후 일반 쿼리 로그를 확인해 보니 쿼리가 너무 많아서 놀랐습니다. 트래픽이 정상일 때 136235개의 쿼리를 얻었으며 대부분은 10분 후 SELECT 쿼리입니다. 그리고 트래픽이 높을 때 10분 안에 195650개의 쿼리를 받았습니다. 방문자가 195650명인지는 의심스럽지만 어떤 이유에서인지 호출은 General_log 내부에 있습니다. Slow_query_log에는 쿼리가 4개만 있었고 최적화되지 않은 쿼리처럼 보이지 않았습니다. 내가 살펴봐야 할 다른 것이 있습니까? 아니면 트래픽 때문이라고 추측하기에 충분합니까? 서버를 업그레이드해야합니까?

top은 대략 이렇습니다. 제 시간에 캡처할 수는 없지만 CPU가 95% 이상에 도달했을 때 화면은 다음과 같았습니다.

top - 13:04:51 up 1140 days, 19:59,  2 users,  load average: 26.57, 16.21, 8.92
Tasks: 429 total,  12 running, 421 sleeping,   0 stopped,   0 zombie
Cpu(s): 91.3%us,  1.6%sy,  0.0%ni, 65.7%id,  3.1%wa,  0.0%hi,  0.2%si,  0.1%st
Mem:  32877280k total, 31367584k used,  1509696k free,  3960824k buffers
Swap:        0k total,        0k used,        0k free,  3980580k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                 
14576 mysql     20   0 12.9g 8.5g 8424 S 951.6 27.2  18841:47 mysqld                                                  
 6032  martind     20   0  510m  65m 9160 S 61.4  0.2   2:49.40 php-fpm                                                  
 7329  martind     20   0  498m  63m 5556 R 57.6  0.2   0:47.15 php-fpm                                                  
 7321  martind     20   0  487m  52m 5532 R 46.1  0.2   0:45.18 php-fpm                                                  
 7160  martind     20   0  488m  52m 5540 R 44.1  0.2   1:02.67 php-fpm                                                  
 6031  martind     20   0  511m  67m 8076 S 42.2  0.2   2:50.87 php-fpm                                                  
 6696  martind     20   0  498m  63m 5700 S 38.4  0.2   1:36.38 php-fpm                                                  
 7283  martind     20   0  494m  59m 5268 S 34.5  0.2   0:46.19 php-fpm                                                  
 7314  martind     20   0  490m  55m 5536 R 33.0  0.2   0:44.22 php-fpm                                                  
 7330  martind     20   0  496m  60m 5436 R 26.4  0.2   0:46.82 php-fpm                                                  
 7305  martind     20   0  494m  58m 5572 R 25.4  0.2   0:48.85 php-fpm                                                  
 6706  martind     20   0  507m  62m 8060 S 13.7  0.2   1:40.55 php-fpm                                                  
 7276  martind     20   0  498m  63m 5264 S  7.7  0.2   0:49.89 php-fpm                                                  
17464 redis     20   0 4328m 2.3g  888 R  7.7  7.3   7827:30 redis-server                                             
 6402  martind     20   0  511m  67m 8056 S  5.8  0.2   2:15.21 php-fpm                                                  
 6405  martind     20   0  512m  69m 9204 S  5.8  0.2   2:14.32 php-fpm                                                  
 6703  martind     20   0  513m  67m 8056 S  5.8  0.2   1:39.40 php-fpm                                                  
 6705  martind     20   0  513m  68m 9040 S  5.8  0.2   1:36.18 php-fpm                                                  
 7303  martind     20   0  493m  57m 6556 S  5.8  0.2   0:47.04 php-fpm                                                  
 7304  martind     20   0  494m  59m 5264 S  5.8  0.2   0:48.70 php-fpm                                                  
 7323  martind     20   0  511m  67m 7772 S  5.8  0.2   0:45.53 php-fpm                                                  
24515 nginx     20   0  123m  66m 2452 S  5.8  0.2   7231:17 nginx                                                    
 6039  martind     20   0  507m  63m 8200 S  3.8  0.2   2:48.39 php-fpm                                                  
 6400  martind     20   0  511m  68m 8204 S  3.8  0.2   2:13.54 php-fpm                                                  
 6401  martind     20   0  510m  66m 9052 S  3.8  0.2   2:13.36 php-fpm                                                  
 6404  martind     20   0  512m  68m 9048 S  3.8  0.2   2:12.75 php-fpm 

그래서 SQL 쿼리가 너무 많아 속도가 느려지는 경향이 있기 때문에 트래픽이 많아서 발생하는 것이라고 생각합니다. cronjobs(wordpress cronjobs 및 php cronjobs)를 확인했는데 속도가 느려지면 아무것도 실행되지 않는 것 같습니다. 동시에 실행 중인 rsync 프로세스가 있을 수 있지만 rsync 프로세스는 항상 실행되므로 이것이 원인인지 의심됩니다. 제가 확인할 수 있는 것이 있나요?

답변1

글로벌 상태 및 변수 분석:

관찰:

  • 버전: 10.4.12-MariaDB
  • 32GB RAM
  • 가동 시간 = 19일 23:11:43
  • MyISAM과 InnoDB를 모두 실행 중인 것 같습니다.
  • 240QPS

더 중요한 문제:

느린 로그에서 더 많은 쿼리를 포착할 수 있도록 으로 long_query_time변경 하세요 . 1(이제 10초 남았습니다. 이는 쿼리를 4개만 찾은 이유일 것입니다.) 일부 쿼리가 비효율적으로 실행되고 있다는 몇 가지 단서가 있습니다. 이러한 쿼리를 찾는 방법은 다음과 같습니다. http://mysql.rjweb.org/doc.php/mysql_analytic#slow_queries_and_slowlog

MyISAM을 사용하는 이유는 무엇입니까? 값이 혼란스럽습니다. 마치 대규모 MyISAM 테이블에 대한 인덱스를 [재]구축했지만 다른 작업을 수행하지 않은 것과 같습니다. 대부분의 경우 InnoDB를 사용하는 것이 더 좋습니다.

innodb_buffer_pool_sizeInnoDB 쿼리 속도를 향상시키기 위해 아마도 증가될 수 있습니다.

주의하세요 general_log. 디스크가 오히려 빠르게 채워집니다.

"쿼리 캐시"가 비효율적으로 실행되고 있습니다. 완전히 끄는 것이 query_cache_type=off좋습니다 query_cache_size=0.

Max_used_connections152번이 떴는데, 이는 동시에 많은 사용자가 접속했음을 의미합니다. (152개의 쿼리가 동시에 실행되었다는 의미는 아닙니다.)

세부 사항 및 기타 관찰 사항:

MyISAM에서 InnoDB로 변환 ( Key_blocks_used * 1024 / key_buffer_size ) = 460 * 1024 / 128M = 0.35%-- key_buffer가 사용된 비율입니다. 하이 워터마크. -- 불필요한 메모리 사용을 방지하려면 key_buffer_size(현재 134217728)를 낮추세요.

( (key_buffer_size / 0.20 + innodb_buffer_pool_size / 0.70) ) = ((128M / 0.20 + 8192M / 0.70)) / 32768M = 37.7%-- 사용 가능한 RAM의 대부분을 캐싱에 사용할 수 있어야 합니다. --http://mysql.rjweb.org/doc.php/memory

( general_log ) = general_log = ON-- 모든 쿼리 실행의 로그(FILE 또는 TABLE)입니다. -- 사용하지 않을 때는 General_log를 끕니다(현재 ON). 해당 로그는 디스크를 매우 빠르게 채울 수 있습니다.

( innodb_buffer_pool_size ) = 8,192 / 32768M = 25.0%-- InnoDB buffer_pool에 사용된 RAM의 비율 -- 사용 가능한 RAM의 약 70%로 설정합니다. (낮을수록 효율성이 떨어지고, 너무 높을수록 교체 위험이 있습니다.)

( (key_buffer_size / 0.20 + innodb_buffer_pool_size / 0.70) ) = ((128M / 0.20 + 8192M / 0.70)) / 32768M = 37.7%-- (RAM 사용량을 판단하기 위한 측정항목)

( innodb_lru_scan_depth * innodb_page_cleaners ) = 1,024 * 4 = 4,096-- 매초 페이지 클리너 작업량. -- "InnoDB: page_cleaner: 1000ms 의도된 루프 소요 ..."는 lru_scan_깊이를 낮추면 해결될 수 있습니다. 1000 / innodb_page_cleaners(현재 4)를 고려하십시오. 교환 여부도 확인해보세요.

( innodb_lru_scan_depth ) = 1,024 -- "InnoDB: page_cleaner: 1000ms 의도한 루프가 걸렸습니다..."는 lru_scan_length를 낮추면 수정될 수 있습니다.

( innodb_io_capacity ) = 200-- 플러시할 때 이만큼의 IOP를 사용합니다. -- 읽기가 느리거나 급격하게 진행될 수 있습니다.

( Innodb_log_writes ) = 43,856,157 / 1725103 = 25 /sec

( Innodb_os_log_written / (Uptime / 3600) / innodb_log_files_in_group / innodb_log_file_size ) = 137,804,939,264 / (1725103 / 3600) / 2 / 48M = 2.86-- 비율 -- (분 참조)

( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 1,725,103 / 60 * 48M / 137804939264 = 10.5-- InnoDB 로그 회전 간격(분) 5.6.8부터 동적으로 변경될 수 있습니다. my.cnf도 변경하십시오. -- (회전 간격 60분 권장은 다소 임의적입니다.) innodb_log_file_size(현재 50331648)를 조정합니다. (AWS에서는 변경할 수 없습니다.)

( innodb_flush_method ) = innodb_flush_method = fsync-- InnoDB가 OS에 블록 쓰기를 요청하는 방법. 이중 버퍼링을 방지하려면 O_DIRECT 또는 O_ALL_DIRECT(Percona)를 제안하세요. (적어도 Unix의 경우) O_ALL_DIRECT에 대한 주의 사항은 chrischandler를 참조하세요.

( default_tmp_storage_engine ) = default_tmp_storage_engine =

( innodb_flush_neighbors ) = 1-- 디스크에 블록을 쓸 때 약간의 최적화가 이루어졌습니다. -- SSD 드라이브에는 0을 사용합니다. 1은 HDD용입니다.

( innodb_io_capacity ) = 200- 디스크에서 사용할 수 있는 초당 I/O 작업 수입니다. 느린 드라이브의 경우 100; 회전 드라이브의 경우 200; SSD의 경우 1000-2000; RAID 요소를 곱합니다.

( innodb_adaptive_hash_index ) = innodb_adaptive_hash_index = ON-- 일반적으로 ON 상태여야 합니다. -- OFF가 더 좋은 경우도 있습니다. innodb_adaptive_hash_index_parts(현재 8)(5.7.9 이후) 및 innodb_adaptive_hash_index_partitions(MariaDB 및 Percona)도 참조하세요. ON은 드문 충돌(버그 73890)과 관련이 있습니다. 10.5.0은 기본값을 OFF로 결정했습니다.

( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF-- 모든 교착 상태를 기록할지 여부입니다. -- Deadlocks로 인해 어려움을 겪고 있다면 이 기능을 켜십시오. 주의: 교착 상태가 많으면 디스크에 많은 양이 기록될 수 있습니다.

( character_set_server ) = character_set_server = latin1 -- charset 문제는 ​​Character_set_server(현재 latin1)를 utf8mb4로 설정하면 도움이 될 수 있습니다. 이것이 미래의 기본값입니다.

( local_infile ) = local_infile = ON -- local_infile (현재 ON) = ON은 잠재적인 보안 문제입니다.

( Key_blocks_used * 1024 / key_buffer_size ) = 460 * 1024 / 128M = 0.35%-- key_buffer 사용 비율 . 하이 워터마크. -- 불필요한 메모리 사용을 방지하려면 key_buffer_size(현재 134217728)를 낮추세요.

( Key_writes / Key_write_requests ) = 19,978,377 / 40284646 = 49.6%-- 쓰기에 대한 key_buffer 효율성 -- RAM이 충분하다면 key_buffer_size(현재 134217728)를 늘리는 것이 좋습니다.

( query_cache_size ) = 524,288 = 0.5MB-- QC 크기 -- 너무 작음 = 많이 사용되지 않음. 너무 크다 = 오버헤드가 너무 많다. 0 또는 50M 이하를 권장합니다.

( Qcache_lowmem_prunes ) = 125,234,412 / 1725103 = 73 /sec-- QC 공간 부족 -- query_cache_size 증가(현재 524288)

( Qcache_lowmem_prunes/Qcache_inserts ) = 125,234,412/146211296 = 85.7%-- 제거 비율(메모리 부족으로 인해 정리해야 하는 빈도)

( Qcache_not_cached ) = 78,413,835 / 1725103 = 45 /sec-- SQL_CACHE가 시도되었지만 무시되었습니다. -- 캐싱을 다시 생각해 보세요. qcache 조정

( Qcache_hits / Qcache_inserts ) = 37,201,050 / 146211296 = 0.254-- 삽입 적중률 -- 높을수록 좋음 -- 쿼리 캐시를 끄는 것이 좋습니다.

( Qcache_hits / (Qcache_hits + Com_select) ) = 37,201,050 / (37201050 + 282029692) = 11.7%-- 적중률 -- QC를 사용한 SELECT -- 쿼리 캐시를 끄는 것을 고려하세요.

( Qcache_hits / (Qcache_hits + Qcache_inserts + Qcache_not_cached) ) = 37,201,050 / (37201050 + 146211296 + 78413835) = 14.2%-- 쿼리 캐시 적중률 -- QC를 끄는 것이 가장 좋습니다.

( (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache / query_alloc_block_size ) = (524288 - 78344) / 82 / 16384 = 0.332-- query_alloc_block_size 대 공식 -- query_alloc_block_size 조정(현재 16384)

( Created_tmp_tables ) = 96,501,765 / 1725103 = 56 /sec-- 복잡한 SELECT의 일부로 "임시" 테이블을 생성하는 빈도입니다.

( Created_tmp_disk_tables ) = 23,539,653 / 1725103 = 14 /sec-- 생성 빈도디스크복잡한 SELECT의 일부인 "임시" 테이블 - tmp_table_size(현재 16777216) 및 max_heap_table_size(현재 16777216)를 늘립니다. MyISAM 대신 MEMORY를 사용하는 경우 임시 테이블에 대한 규칙을 확인하세요. 아마도 사소한 스키마나 쿼리 변경으로 인해 MyISAM이 방지될 수 있습니다. 더 나은 색인과 쿼리 재구성이 도움이 될 가능성이 더 높습니다.

( Created_tmp_disk_tables / Questions ) = 23,539,653 / 414140316 = 5.7%-- 온디스크 임시 테이블이 필요한 쿼리 비율입니다. -- 더 나은 인덱스 / 블롭 없음 / 등.

( Select_full_join / Com_select ) = 30,333,225 / 282029692 = 10.8%-- 인덱스 없는 조인인 선택 비율 -- JOIN에 사용되는 테이블에 적합한 인덱스를 추가합니다.

( Com_insert + Com_delete + Com_delete_multi + Com_replace + Com_update + Com_update_multi ) = (87669877 + 27242 + 0 + 0 + 1452911 + 0) / 1725103 = 52 /sec-- 쓰기/초 -- 50개 쓰기/초 + 로그 플러시는 아마도 HDD 드라이브의 I/O 쓰기 용량을 최대화할 것입니다. SSD가 있는 경우 이 측정항목이 적합할 것입니다.

( binlog_format ) = binlog_format = MIXED-- 명령문/행/혼합. -- ROW는 5.7(10.3)에서 선호됩니다.

( long_query_time ) = 10-- "느린" 쿼리를 정의하기 위한 컷오프(초)입니다. -- 제안 2

( Max_used_connections / max_connections ) = 152 / 151 = 100.7%-- 최대 연결 비율 -- max_connections(현재 151)를 늘리거나 wait_timeout(현재 28800)을 줄입니다. 또는 쿼리 속도를 높이세요.

( Connections ) = 11,987,448 / 1725103 = 6.9 /sec-- 연결 -- wait_timeout을 늘립니다(현재 28800). 풀링을 사용 하시겠습니까?

( Connection_errors_accept + Connection_errors_internal + Connection_errors_peer_address + Connection_errors_select + Connection_errors_tcpwrap ) = 0 + 26 + 0 + 0 + 0 = 26-- max_connections 이외의 연결 오류입니다. -- 자세한 내용은 'Connection_errors%'와 같은 전역 상태 표시를 참조하세요.

비정상적으로 작음:

Created_tmp_files = 0.094 /HR
innodb_spin_wait_delay = 4

비정상적으로 크다:

Aria_pagecache_writes = 34 /sec
Aria_transaction_log_syncs = 25,641
Com_show_warnings = 40 /HR
Connection_errors_internal = 0.054 /HR
Handler_read_key = 85109 /sec
Handler_tmp_update = 839 /sec
Innodb_buffer_pool_read_requests = 675158 /sec
Innodb_buffer_pool_read_requests / (Innodb_buffer_pool_read_requests + Innodb_buffer_pool_reads ) = 100.0%
Innodb_rows_updated = 356 /sec
performance_schema_max_cond_classes = 90

비정상적인 문자열:

Innodb_have_punch_hole = OFF
aria_recover_options = BACKUP,QUICK
disconnect_on_expired_password = OFF
ft_boolean_syntax = + -><()~*:
innodb_fast_shutdown = 1
log_output = TABLE
myisam_stats_method = NULLS_UNEQUAL
old_alter_table = DEFAULT
optimizer_trace = enabled=off

관련 정보