MySQL 복제 지연

MySQL의 복제 지연을 줄이기 위한 전략

MySQL 복제지연(replication lag)은 복제 설정에서 주 서버(Primary)와 보조 서버(Replica) 간의 데이터 동기화가 지연되는 현상을 의미합니다. 복제지연은 데이터 일관성 문제를 일으킬 수 있으며, 특히 읽기 부하 분산을 위해 보조 서버를 활용하는 환경에서 심각한 문제가 될 수 있습니다.

최근 AWS Aurora for MySQL을 사용하다가, RDS를 사용하는 곳으로 옮겼더니, 복제 지연에 대한 이슈로 골머리를 썩고 있는 상황이었습니다. 읽기 작업을 분산처리를 해놓긴 했는데 몇가지 문제점이 보였습니다. 이번 포스트에서는 MySQL에서 복제지연을 해결할 수 있는 다양한 방법을 알아보겠습니다.

 

복제 지연이 발생하는 이유

복제 지연의 이유에는 여러가지가 있지만 크게 세가지로 원인을 분류 할 수 있을것 같네요.

  1. 네트워크 이슈
  2. I/O 이슈
  3. MySQL 설정값 (Parameter)

우선 네트워크는 주 서버(Primary)와 보조 서버(Replica) 간에 네트워크 품질에 관련된 문제기 때문에 서버간 네트워크 전송거리, 네트워크 품질, 대역폭 등의 문제로 실제로 네트워크 엔지니어 혹은 클라우드 밴더사의 가이드에 따르는 수밖에 없습니다.

I/O에 관한 문제는 결국 디스크 성능에 가장 큰 영향을 받습니다. HDD를 SSD로 교체한다거나 RAID 구성, 고사양의 스토리지 서버를 사용하여 해결 할 수 있습니다.

세번째로 MySQL 설정으로 인한 이슈는 my.cnf 혹은 AWS라면 RDS의 파라미터 그룹 변경을 통해 해결할 수 있습니다.

 

이론적인 내용이 아닌 실무에서 복제지연이 발생하는 이유

최근 Aurora를 사용함에도 CDC를 위해 Binlog를 켜고 사용한다거나, 별도의 복제를 통해 서비스의 목적에 따라 나누는 경우도 많습니다.

복제지연은 대량의 쓰기 작업이 발생했을 때 가장 많이 발생합니다. 덩치가 큰 테이블의 인덱스를 생성하거나 DDL작업이 발생할 때도 복제지연이 발생할 수 있습니다.

 

복제 지연에 영향을 주는 파라미터 값들

MySQL의 InnoDB 스토리지 엔진은 디스크 I/O 작업을 관리하기 위해 다양한 파라미터를 제공하는데, 그 중 하나가 innodb_io_capacity입니다. 이 파라미터는 InnoDB가 내부 작업(특히 버퍼 풀에서 디스크로의 플러시 작업)을 처리할 때 사용할 수 있는 I/O 작업의 최대 수를 설정합니다. 이 설정은 복제지연(replication lag)에 직접적인 영향을 미칠 수 있습니다. 이번 포스트에서는 innodb_io_capacity가 복제지연에 미치는 영향을 살펴보겠습니다.

innodb_io_capacity, innodb_io_capacity_max

innodb_io_capacity는 InnoDB가 디스크로 플러시할 수 있는 I/O 작업의 최대 수를 지정합니다.

innodb_io_capacity의 설정 값을 찾기 위해서는 아래와 같은 절차를 거쳐야 합니다.

  • 디스크 IOPS 측정: 서버의 디스크가 지원하는 최대 IOPS를 확인합니다. SSD의 경우 일반적으로 높은 값을 사용할 수 있으며, HDD의 경우 상대적으로 낮은 값을 사용해야 합니다.
  • 점진적 조정: innodb_io_capacity 값을 점진적으로 조정하여 최적의 성능을 찾습니다. 기본값(200)에서 시작하여 디스크 I/O 성능과 복제지연을 관찰하면서 값을 조정합니다.
  • 모니터링 도구 사용: MySQL의 성능 스키마와 모니터링 도구(Prometheus, Grafana 등)를 사용하여 복제지연 및 디스크 I/O 사용률을 모니터링합니다.

innodb_io_capacity는 MySQL의 복제지연에 큰 영향을 미치는 중요한 설정입니다. 디스크 I/O 성능에 맞게 적절히 조정하여 InnoDB의 플러시 작업이 원활하게 이루어지도록 해야 합니다. 이를 통해 주 서버와 보조 서버 간의 데이터 동기화 속도를 최적화하고, 복제지연을 최소화할 수 있습니다. 최적의 값을 찾기 위해 디스크 IOPS를 측정하고, 실시간 모니터링을 통해 설정 값을 조정하는 것이 중요합니다.

MySQL innodb_io_capacity의 기본값은 200이며, innodb_io_capacity_max의 기본값은 2000 인데, 이 값을 조정해서 I/O 성능을 조정할 수 있으며, 모니터링을 통해 WriteIOPS가 실제 얼마나 일어나는지를 파악해서 충분히 크기를 늘려주는 것이 좋습니다. 실제 WriteIOPS 가 2000 이상 발생한다면, innodb_io_capacity = 2000 innodb_io_capacity_max 값는 최대 IOPS의 7~80% 수준으로 늘려주는 것이 좋습니다.

AWS RDS 의 경우 IOPS의 계산식은

IOPS = 초당 데이터 전송량 / 블럭크기(단위 데이터 용량)

으로 블럭 크기는 DBMS마다 기준이 다릅니다. Oracle, MS-SQL, PostgreSQL은 8KB, MySQL은 16KB 입니다.

RDS의 스토리지 타입에 따른 스토리지 성능

gp2, gp3, io1, io2 등의 스토리지 타입이 있고 가장 많이 사용하는 gp2, gp3의 IOPS 및 성능표 입니다.

  • gp2

  • gp3

서비스 사용되고 있는 스토리지 크기에 의해 최대 IOPS가 결정되니, 최대 IOPS에서 7~80% 수준의 IOPS를 innodb_io_capacity_max 값으로 설정하면 됩니다.

 

slave_parallel_workers

slave_parallel_workers은 복제 사용하는 프로세스 수를 결정합니다. slave_parallel_workers에 설정된 수 만큼의 멀티 프로세스를 통해 병렬로 복제를 진행할 수 있는데, 이 값은 복제서버의 CPU 코어수에 영향을 미치기 때문에 복제 서버가 가지고 있는 코어를 복제에 다 사용하지 않도록 구성하는 것이 중요합니다.

RDS에서 읽기 복제를 생성하면 slave_parallel_workers의 기본값이 4이기 때문에 너무 작은 인스턴스를 복제 인스턴스로 사용하면 복제하는데 모든 CPU 코어를 사용해버리기 때문에 문제가 생길수 있습니다. 수동으로 값을 줄여주거나, 인스턴스 사이즈를 키워야하는 경우가 발생할 수 있습니다.

 

그 밖에 복제 지연에 영향을 줄 수 있는 파라미터

  • sync_binlog
    • 설명: 이 파라미터는 MySQL이 트랜잭션 로그를 디스크에 기록할 때 얼마나 자주 fsync를 호출할지 결정합니다.
    • 권장 설정: sync_binlog=1은 데이터 일관성을 보장하지만, 성능에 영향을 줄 수 있습니다. 데이터 무결성을 유지하면서도 성능을 개선하려면 이 값을 적절히 조정해야 합니다.
  • innodb_flush_log_at_trx_commit
    • 설명: 이 파라미터는 트랜잭션 커밋 시점에 로그를 디스크에 기록하는 빈도를 제어합니다.
    • 권장 설정: innodb_flush_log_at_trx_commit=1은 데이터 무결성을 보장합니다. 그러나 성능을 고려해 2로 설정하면 디스크 쓰기 빈도가 줄어 성능이 개선될 수 있습니다. 단, 데이터 손실 가능성은 증가합니다.
  • read_buffer_size와 read_rnd_buffer_size
    • 설명: 이 파라미터들은 MySQL이 테이블을 읽을 때 사용할 버퍼의 크기를 설정합니다. 복제 지연에 영향을 줄 수 있는 쿼리 성능을 최적화하는 데 도움이 됩니다. read_buffer는 InnoDB에서는 영향이 없으며, read_rnd_buffer는를 영향을 줄 수 있습니다.
    • 권장 설정: 기본값을 적절히 조정하여 서버의 메모리 용량에 맞게 설정합니다.
  • log_slave_updates
    • 설명: 이 파라미터는 보조 서버가 자신이 받은 복제 이벤트를 자신의 바이너리 로그에 기록할지 여부를 결정합니다.
    • 권장 설정: 보조 서버에서 추가적인 복제를 설정하려는 경우 이 값을 ON으로 설정해야 하지만, 일반적인 복제 성능을 위해서는 OFF로 설정하는 것이 좋습니다.
  • innodb_buffer_pool_size
    • 설명: InnoDB 버퍼 풀은 디스크 I/O를 줄이고 데이터베이스 성능을 향상시키는 데 중요합니다.
    • 권장 설정: 전체 시스템 메모리의 60-80% 정도로 설정하여 InnoDB가 메모리에서 대부분의 데이터를 처리할 수 있도록 합니다.
  • innodb_flush_method
    • 설명: 이 파라미터는 InnoDB가 디스크로 데이터를 플러시할 때 사용할 방법을 지정합니다.
    • 권장 설정: O_DIRECT를 사용하여 페이지 캐시를 우회하고, O_DSYNC를 사용하여 로그 플러시를 최적화할 수 있습니다.
  • relay_log_space_limit
    • 설명: 이 파라미터는 보조 서버가 리레이 로그에 사용할 수 있는 최대 디스크 공간을 지정합니다.
    • 권장 설정: 충분히 큰 값으로 설정하여 보조 서버가 필요한 로그를 모두 저장할 수 있도록 합니다.
  • innodb_thread_concurrency
    • 설명: InnoDB가 동시에 실행할 수 있는 스레드의 수를 제한합니다.
    • 권장 설정: 시스템의 CPU 코어 수에 따라 적절히 조정하여 병목 현상을 줄입니다.
  • innodb_log_file_size
    • 설명: InnoDB 로그 파일의 크기를 설정합니다.
    • 권장 설정: 큰 값으로 설정하면 체크포인트를 줄이고 성능을 향상시킬 수 있습니다. 일반적으로 512MB에서 1GB 사이로 설정합니다.
  • innodb_flush_neighbors
    • 설명: 이 파라미터는 InnoDB가 플러시할 때 인접한 페이지들을 함께 플러시할지 여부를 결정합니다.
    • 권장 설정: SSD를 사용하는 경우 0으로 설정하여 불필요한 플러시 작업을 줄입니다.

복제지연을 줄이기 위해서는 MySQL 설정의 여러 파라미터들을 최적화해야 합니다. innodb_io_capacity와 slave_parallel_workers 외에도 위에서 언급한 파라미터들을 조정하여 전체적인 복제 성능을 향상시킬 수 있습니다. 각 파라미터의 설정은 서버의 하드웨어 사양, 네트워크 환경, 애플리케이션 요구 사항에 따라 다르므로, 실제 환경에 맞게 조정하는 것이 중요합니다. 이를 통해 복제지연을 최소화하고, 안정적이고 빠른 데이터 동기화를 달성할 수 있습니다.

 

 

소셜 미디어로 공유하기

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.