Apache/MySQL의 높은 CPU 사용량

Apache/MySQL의 높은 CPU 사용량

WordPress, Apache, MySQL을 사용하는 웹사이트에서 CPU 사용량에 문제가 있습니다. 하루 동안 때때로 MySQL과 Apache의 CPU 사용량이 최대 2400%까지 올라가고(총 코어 수는 24개입니다) 서버가 정지되고 평균 로드가 24개까지 올라갑니다.

최근에는 평소보다 교통량이 조금 늘었는데, 이게 영구적으로 있어서는 안 되겠죠? 커널, 데이터베이스, 라이브러리를 업데이트하고 여러 번 다시 시작했습니다. 그리고 여전히 얼어붙습니다. DB의 프로세스 목록을 살펴봤지만 특별한 것은 없습니다. 데이터베이스에는 꽤 많은 양의 데이터가 있습니다. 불과 몇 주 전에는 잘 작동했는데 지금은 그렇지 않습니다. 따라서 최적화되지 않은 쿼리가 되어서는 안 됩니다.

그러한 행동의 원인은 무엇입니까?

업데이트:

A) SHOW GLOBAL STATUS LIKE 'com_%r%_table'의 결과;

+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Com_alter_table       | 5     |
| Com_create_table      | 34    |
| Com_drop_table        | 0     |
| Com_rename_table      | 0     |
| Com_show_create_table | 0     |
+-----------------------+-------+
5 rows in set (3.04 sec)

B) 'uptime%'과 같은 전역 상태를 표시합니다.

+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| Uptime                    | 455524 |
| Uptime_since_flush_status | 455524 |
+---------------------------+--------+
2 rows in set (0.01 sec)

C) '%dirty%'와 같은 전역 상태를 표시합니다.

+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| Innodb_buffer_pool_pages_dirty | 0     |
| Innodb_buffer_pool_bytes_dirty | 0     |
+--------------------------------+-------+
2 rows in set (0.00 sec)

ps. 아직 서버에 문제가 있습니다. 데이터베이스 중 하나에서 문자 집합을 변경해야 했고, 행이 400,000개에 불과해 완료하는 데 하루가 조금 넘게 걸렸습니다. 예전에는 시간이 좀 걸렸지만 그렇게 많지는 않았어요. DDOS 공격 후에 데이터베이스가 일부 변경되어 성능이 저하될 수 있는지 궁금합니다.

업데이트 2:

mysqltuner 결과:

[--] Skipped version check for MySQLTuner script
[OK] Logged in using credentials from Debian maintenance account.
[OK] Currently running supported MySQL version 8.0.26-0ubuntu0.20.04.2
[OK] Operating on 64-bit architecture
 
-------- Log file Recommendations ------------------------------------------------------------------
[OK] Log file /var/log/mysql/error.log exists
[--] Log file: /var/log/mysql/error.log(0B)
[--] Log file /var/log/mysql/error.log is empty. Assuming log-rotation. Use --server-log={file} for explicit file
 
-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA 
[--] Data in InnoDB tables: 262.4G (Tables: 179)
[OK] Total fragmented tables: 0
 
-------- Analysis Performance Metrics --------------------------------------------------------------
[--] innodb_stats_on_metadata: OFF
[OK] No stat updates during querying INFORMATION_SCHEMA.
 
-------- Security Recommendations ------------------------------------------------------------------
[--] Skipped due to unsupported feature for MySQL 8
 
-------- CVE Security Recommendations --------------------------------------------------------------
[OK] NO SECURITY CVE FOUND FOR YOUR VERSION
 
-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 5d 11h 4m 6s (15M q [31.945 qps], 191K conn, TX: 80G, RX: 2G)
[--] Reads / Writes: 99% / 1%
[--] Binary logging is enabled (GTID MODE: OFF)
[--] Physical Memory     : 31.4G
[--] Max MySQL memory    : 9.8G
[--] Other process memory: 0B
[--] Total buffers: 176.0M global + 65.1M per thread (151 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 9.8G (31.14% of installed RAM)
[OK] Maximum possible memory usage: 9.8G (31.14% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (0/15M)
[!!] Highest connection usage: 100%  (151/151)
[OK] Aborted connections: 0.09%  (174/191712)
[!!] name resolution is active : a reverse name resolution is made for each new connection and can reduce performance
[--] Query cache have been removed in MySQL 8
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 5M sorts)
[OK] No joins without indexes
[OK] Temporary tables created on disk: 0% (0 on disk / 2M total)
[OK] Thread cache hit rate: 92% (15K created / 191K connections)
[OK] Table cache hit rate: 99% (21M hits / 21M requests)
[OK] table_definition_cache(2000) is upper than number of tables(506)
[OK] Open file limit used: 0% (6/10K)
[OK] Table locks acquired immediately: 100% (9 immediate / 9 locks)
[OK] Binlog cache memory access: 99.57% (25538 Memory / 25647 Total)
 
-------- Performance schema ------------------------------------------------------------------------
[--] Memory used by P_S: 72B
[--] Sys schema is installed.
 
-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.
 
-------- MyISAM Metrics ----------------------------------------------------------------------------
[--] MyISAM Metrics are disabled on last MySQL versions.
 
-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[!!] InnoDB buffer pool / data size: 128.0M/262.4G
[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (75 %): 48.0M * 2/128.0M should be equal to 25%
[OK] InnoDB buffer pool instances: 1
[--] Number of InnoDB Buffer Pool Chunk : 1 for 1 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size & Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 98.29% (925392031 hits/ 941450541 total)
[!!] InnoDB Write Log efficiency: 309.39% (25100125 hits/ 8112662 total)
[!!] InnoDB log waits: 0.00% (65 waits / 33212787 writes)
 
-------- Aria Metrics ------------------------------------------------------------------------------
[--] Aria Storage Engine not available.
 
-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.
 
-------- XtraDB Metrics ----------------------------------------------------------------------------
[--] XtraDB is disabled.
 
-------- Galera Metrics ----------------------------------------------------------------------------
[--] Galera is disabled.
 
-------- Replication Metrics -----------------------------------------------------------------------
[--] Galera Synchronous replication: NO
[--] No replication slave(s) for this server.
[--] Binlog format: ROW
[--] XA support enabled: ON
[--] Semi synchronous replication Master: Not Activated
[--] Semi synchronous replication Slave: Not Activated
[--] This is a standalone server
 
-------- Recommendations ---------------------------------------------------------------------------
General recommendations:
    Reduce or eliminate persistent connections to reduce connection usage
    Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1
    Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: *link*
Variables to adjust:
    max_connections (> 151)
    wait_timeout (< 28800)
    interactive_timeout (< 28800)
    innodb_buffer_pool_size (>= 262.4G) if possible.
    innodb_log_file_size should be (=16M) if possible, so InnoDB total log files size equals to 25% of buffer pool size.
    innodb_log_buffer_size (>= 16M)

업데이트 3:

오늘 내 서버가 다시 정지되었습니다. CPU에 과부하를 준 프로세스는 apache2였습니다. 서비스를 중지하는데 성공했습니다. 그리고 갑자기 모든 것이 순조롭게 진행되기 시작했습니다. 행이 많은 데이터베이스의 백업을 시도했는데 제대로 작동했습니다. 그러나 얼마 후 모든 것이 다시 멈췄습니다. 일부 프로세스의 CPU 사용량은 2400%였으며 로드 평균은 24를 초과했습니다. 따라서 내 제안은 MySQL이 아니라 CPU를 로드하는 것은 아파치가 아니라는 것입니다. 백업에 사용하고 있는 htop이나 gzip과 같은 일부 프로세스도 때때로 CPU 사용량이 높습니다. 그러면 무엇이 될 수 있습니까? 이것이 DDOS 공격의 결과일 수 있습니까? 그렇다면 어떻게 해결할 수 있습니까?

답변1

초당 속도 = RPS

my.cnf [mysqld] 섹션에 대해 고려해야 할 제안

innodb_buffer_pool_size=22G  # from 128M to better accomodate your 262G of data
max_connections=256  # from 151 since you have had all connections used
thread_cache_size=150  # from 9 to reduce threads_created RPhr of 111
innodb_log_file_size=4G  # from 50M to support more than and hour before rotation
innodb_log_buffer_size=1G  # from 16M to support ~ 30 min before write to media

성능이 크게 향상되어야 합니다. 성과를 향상시킬 수 있는 기회는 더 많습니다. 성능 향상을 위해 연락처 정보 및 무료로 다운로드 가능한 유틸리티 스크립트에 대한 프로필을 확인하세요.

답변2

말하기는 매우 어렵지만 WordPress를 실행 중이고 최대 24개 코어가 100%에 도달했다고 말하고 있습니다. 단, 단일 쿼리가 한 번에 1개의 스레드만 사용할 수 없다는 점을 기억하십시오.

쿼리 성능이 매우 나쁘고 Apache 웹 서버에 직접 연결되지 않는 것 같습니다. 쿼리 조회를 저장하기 위해 쿼리를 Redis에 캐시하기 위해 "WP Redis Cache" 플러그인을 사용해 보셨나요?

설치하려고 시도할 수 있는 다음 플러그인은 "Query Monitor"입니다. 이는 즉석에서 호출하는 SQL 쿼리를 표시하며 WordPress에 매우 유용한 디버깅 도구입니다.

WordPress에서 자체 플러그인을 개발하는 경우 내장된 기능을 사용하여 쿼리 결과를 캐시함으로써 Redis를 직접 관리해야 한다는 점을 기억하세요.

그리고 이 디버깅 방법이 끝나면 1초가 넘는 모든 항목에 대해 MySQL에 대한 느린 로그 쿼리를 활성화하는 것이 좋습니다. 열에 대한 인덱스가 누락된 쿼리를 찾을 수 있습니다.

관련 정보