Amazon RDS for MySQL에서 높은 복제 지연 문제를 해결하려면 어떻게 해야 합니까?

6분 분량
0

MySQL용 Amazon Relational Database Service(RDS)를 사용할 때 복제 지연이 발생하는 원인을 찾고 싶습니다.

간략한 설명

Amazon RDS for MySQL은 비동기 복제를 사용합니다. 즉, 복제본이 기본 DB 인스턴스를 따라잡지 못하는 경우가 있습니다. 따라서 복제 지연이 발생할 수 있습니다.

복제 지연을 모니터링하려면 바이너리 로그 파일 위치 기반 복제와 함께 Amazon RDS for MySQL 읽기 전용 복제본을 사용하세요.

Amazon CloudWatch에서 아마존 RDS의 ReplicaLag 메트릭을 확인하세요. ReplicaLag 메트릭은 SHOW SLAVE STATUS 명령의Seconds_Behind_Master 필드 값을 보고합니다.

Seconds_Behind_Master 필드는 복제본 DB 인스턴스의 현재 타임스탬프 간의 차이를 표시합니다. 또한 복제본 DB 인스턴스의 이벤트 처리를 위해 기본 DB 인스턴스에 로깅된 원래 타임스탬프도 표시됩니다.

MySQL 복제는 Binlog Dump 스레드, IO_THREADSQL_THREAD의 세 가지 스레드에서 작동합니다. 이러한 스레드의 작동 방식에 대한 자세한 내용을 알아보려면 복제 스레드에 대한 MySQL 설명서를 참조하세요. 복제가 지연되는 경우, 복제본 IO_THREAD 또는 복제본 SQL_THREAD로 인해 지연이 발생하는지 확인하세요. 그러면 지연의 근본 원인을 확인할 수 있습니다.

해결 방법

어떤 복제 스레드가 지연되고 있는지 확인하려면 다음 예를 참조하세요.

1.    기본 DB 인스턴스에서 SHOW MASTER STATUS 명령을 실행한 다음 출력을 검토합니다. 출력은 다음과 유사하게 표시됩니다.

mysql> SHOW MASTER STATUS;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.066552|      521 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

참고: 이 예제 출력에서 원본 또는 기본 DB 인스턴스는 바이너리 로그를 mysql-bin.066552 파일에 기록합니다.

2.    복제본 DB 인스턴스에서 SHOW SLAVE STATUS 명령을 실행한 다음 출력을 검토합니다. 출력은 다음 예시와 비슷합니다.

예시 1:

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
Master_Log_File: mysql-bin.066548
Read_Master_Log_Pos: 10050480
Relay_Master_Log_File: mysql-bin.066548
Exec_Master_Log_Pos: 10050300
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

예제 1에서 Master_Log_File: mysql-bin.066548은 복제본 IO_THREAD가 바이너리 로그 파일 mysql-bin.066548에서 읽음을 나타냅니다. 기본 DB 인스턴스는 바이너리 로그를 mysql-bin.066552 파일에 기록합니다. 이 출력은 복제본 IO_THREAD가 4개의 binlog보다 뒤쳐져 있음을 보여줍니다. 그러나 Relay_Master_Log_Filemysql-bin.066548이며, 이는 복제본 SQL_THREADIO_THREAD와 동일한 파일에서 읽는다는 것을 나타냅니다. 즉, 복제본 SQL_THREAD는 따라잡고 있지만 복제본 IO_THREAD가 지연되고 있다는 의미입니다.

예시 2:

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Master_Log_File: mysql-bin.066552
Read_Master_Log_Pos: 430
Relay_Master_Log_File: mysql-bin.066530
Exec_Master_Log_Pos: 50360
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

예제 2는 기본 인스턴스의 로그 파일이 mysql-bin-changelog.066552임을 보여줍니다. 출력은 IO_THREAD가 기본 DB 인스턴스를 따라잡고 있음을 보여줍니다. 복제본 출력에서 SQL 스레드는 Relay_Master_Log_File: mysql-bin-changelog.066530을 수행합니다. 결과적으로 SQL_THREAD는 22개의 바이너리 로그가 지연됩니다.

일반적으로 IO_THREAD는 기본 또는 소스 인스턴스에서 바이너리 로그만 읽기 때문에 IO_THREAD는 큰 복제 지연을 일으키지 않습니다. 그러나 네트워크 연결 및 네트워크 지연 시간은 서버 간 읽기 속도에 영향을 줄 수 있습니다. 대역폭 사용량이 높기 때문에 IO_THREAD 복제본의 성능이 느려질 수 있습니다.

복제본 SQL_THREAD가 복제 지연의 원인인 경우 다음과 같은 상황에서 지연이 발생할 수 있습니다.

  • 기본 DB 인스턴스의 장기 실행 쿼리
  • DB 인스턴스 클래스 크기 또는 스토리지가 충분하지 않음
  • 기본 DB 인스턴스에서 병렬 쿼리 실행
  • 복제본 DB 인스턴스의 디스크에 동기화된 바이너리 로그
  • 복제본의 Binlog_format이 ROW로 설정됨
  • 복제본 생성 지연

기본 인스턴스의 장기 실행 쿼리

복제본 DB 인스턴스에서 실행하는 데 동일한 시간이 걸리는 기본 DB 인스턴스의 쿼리를 오래 실행하면 seconds_behind_master가 증가할 수 있습니다. 예를 들어 기본 인스턴스에서 변경을 시작하고 실행하는 데 1시간이 걸린다면 지연은 1시간입니다. 복제본에서 변경을 완료하는 데에도 1시간이 걸린다면 완료 시점의 총 지연은 약 2시간입니다. 이는 예상된 지연이지만 기본 인스턴스에서 느린 쿼리 로그를 모니터링하여 이 지연을 최소화할 수 있습니다. 또한 장기 실행 명령문을 식별하여 지연을 줄일 수도 있습니다. 그런 다음 장기 실행 명령문을 더 작은 명령문이나 트랜잭션으로 나눕니다.

DB 인스턴스 클래스 크기 또는 스토리지가 충분하지 않음

복제본 DB 인스턴스 클래스 또는 스토리지 구성이 기본 인스턴스보다 낮은 경우 리소스 부족으로 인해 복제본이 병목 현상이 발생할 수 있습니다. 이는 복제본이 기본 인스턴스의 변경 내용을 따라갈 수 없기 때문입니다. 복제본의 DB 인스턴스 유형이 기본 DB 인스턴스와 같거나 더 높은지 확인하세요. 복제가 효과적으로 작동하려면 각 읽기 전용 복제본에 원본 DB 인스턴스와 동일한 양의 컴퓨팅 및 스토리지 리소스가 필요합니다. 자세한 내용을 보려면 DB 인스턴스 클래스를 참조하세요.

기본 DB 인스턴스에서 병렬 쿼리 실행

기본 쿼리를 병렬로 실행하면 쿼리가 복제본에서 순차적으로 커밋됩니다. 이는 MySQL 복제가 기본적으로 단일 스레드(SQL_THREAD)이기 때문입니다. 원본 DB 인스턴스에 대한 대량의 쓰기가 동시에 발생하는 경우 읽기 전용 복제본에 대한 쓰기가 직렬화됩니다. 읽기 전용 복제본에 대한 쓰기는 단일 SQL_THREAD를 사용하여 직렬화합니다. 이로 인해 원본 DB 인스턴스와 읽기 전용 복제본 간에 지연이 발생할 수 있습니다.

멀티스레드(병렬) 복제는 MySQL 5.6, MySQL 5.7 이상 버전에서 사용할 수 있습니다. 멀티스레드 복제에 대한 자세한 내용을 보려면 바이너리 로깅 옵션 및 변수에 대한 MySQL 설명서를 참조하세요.

멀티스레드 복제로 인해 복제에 공백이 발생할 수 있습니다. 예를 들어 멀티스레드 복제는 복제 오류를 건너뛰는 경우 권장되지 않는데, 이는 건너뛰는 트랜잭션을 식별하기 어렵기 때문입니다. 이로 인해 기본 DB 인스턴스와 복제 DB 인스턴스 간의 데이터 일관성에 차이가 생길 수 있습니다.

복제본 DB 인스턴스의 디스크에 동기화된 바이너리 로그

복제본에서 자동 백업을 활성화하면 바이너리 로그를 복제본의 디스크에 동기화하는 데 오버헤드가 발생할 수 있습니다. 파라미터 sync_binlog의 기본값은 1로 설정되어 있습니다. 이 값을 0으로 변경하면 MySQL 서버가 바이너리 로그를 디스크와 동기화하는 기능도 해제됩니다. 운영 체제(OS)는 디스크에 로깅하는 대신 바이너리 로그를 디스크에 플러시하는 경우가 있습니다.

바이너리 로그 동기화를 끄면 커밋할 때마다 바이너리 로그를 디스크에 동기화하는 데 필요한 성능 오버헤드를 줄일 수 있습니다. 그러나 정전이 발생하거나 OS 충돌이 발생하면 일부 커밋이 바이너리 로그와 동기화되지 않을 수 있습니다. 이러한 비동기화는 PITR(시점 복원) 기능에 영향을 미칠 수 있습니다. 자세한 내용을 보려면 sync_binlog에 대한 MySQL 설명서를 참조하세요.

Binlog_format이 ROW로 설정되었습니다.

SQL 스레드는 다음 두 가지 요소에 해당하는 경우 복제 시 전체 테이블 스캔을 수행합니다.

  • 기본 DB 인스턴스의 binlog_formatROW로 설정되어 있습니다.
  • 원본 테이블에 프라이머리 키가 없습니다.

이는 파라미터 slave_rows_search_algorithms의 기본값이 TABLE_SCAN,INDEX_SCAN이기 때문에 발생합니다.

이 문제를 단기간에 해결하려면 검색 알고리즘을 INDEX_SCAN, HASH_SCAN으로 변경하여 전체 테이블 스캔의 오버헤드를 줄이세요. 장기적으로는 각 테이블에 명시적 프라이머리 키를 추가하는 것이 좋습니다.

slave-rows-search-algorithms 파라미터에 대한 자세한 내용을 보려면 slave_rows_search_algorithms에 대한 MySQL 설명서를 참조하세요.

복제본 생성 지연

Amazon RDS는 DB 스냅샷을 찍어 MySQL 기본 인스턴스의 읽기 전용 복제본을 생성합니다. 그런 다음 Amazon RDS는 스냅샷을 복원하여 새 DB 인스턴스(복제본)를 생성하고 둘 인스턴스 사이에 복제를 설정합니다.

Amazon RDS는 새 읽기 전용 복제본을 생성하는 데 시간이 걸립니다. 복제를 설정한 후에는 기본 DB 인스턴스의 백업을 생성하는 데 걸리는 시간 동안 지연이 발생합니다. 이 지연을 최소화하려면 복제본 생성을 요청하기 전에 수동 백업을 생성하세요. 그러면 DB 스냅샷은 증분 백업입니다.

스냅샷에서 읽기 전용 복제본을 복원할 때 복제본은 소스로부터 모든 데이터가 전송될 때까지 기다리지 않습니다. 복제본 DB 인스턴스는 DB 작업을 수행하는 데 사용할 수 있습니다. 기존 Amazon Elastic Block Store(Amazon EBS) 스냅샷 로드는 백그라운드에서 새 볼륨을 생성합니다.

참고: Amazon RDS for MySQL 복제본(EBS 기반 볼륨) 의 경우, 처음에는 복제본 지연이 증가할 수 있습니다. 이는 지연 로딩 효과가 복제 성능에 영향을 미칠 수 있기 때문입니다.

새로 만든 읽기 전용 복제본의 테이블에 대해 지연 로드가 미치는 영향을 줄이기 위해 전체 테이블 스캔과 관련된 작업을 수행할 수 있습니다. 예를 들어, 특정 테이블 또는 데이터베이스의 읽기 복제본에서 mysqldump 작업을 실행할 수 있습니다. 이를 통해 Amazon RDS가 Amazon Simple Storage Service(S3)에서 백업된 모든 테이블 데이터의 우선 순위를 지정하고 다운로드할 수 있습니다.

또한 “온디맨드” InnoDB 캐시 워밍 기능을 사용하는 것도 고려해 보세요. InnoDB 캐시 워밍 기능은 디스크의 버퍼 풀 상태를 InnoDB 데이터 디렉터리의 ib_buffer_pool이라는 파일에 저장합니다. 이렇게 하면 읽기 전용 복제본을 생성하기 전에 기본 DB 인스턴스의 버퍼 풀 현재 상태를 덤프하여 성능을 높일 수 있습니다. 그런 다음 읽기 전용 복제본을 생성한 후 버퍼 풀을 다시 로드합니다.

관련 정보

아마존 RDS에서 MySQL 복제본으로 작업

MySQL 읽기 전용 복제본으로 작업