RDS for MySQL과 MariaDB MaxConnection이 다른 이유

이민석's avatar
Sep 26, 2024
RDS for MySQL과 MariaDB MaxConnection이 다른 이유

개요

회사에서 비용 절감을 위해서 최적화를 한 적이 있습니다.
이 당시 RDS for MariaB (10.6)의 일부가 connection*이 부족해졌습니다.
[AWS] RDS max_connections을 수정하는 법이 있었으나 엔진에 밀접한 설정값을 변경하는 것보다 불필요하게 많이 설정된 SpringBoot PoolConnection*을 조절했습니다.

이후 동일한 db.t3.micro에서 MySQL과 MariaDB의 max_connection이 다른것을 동료 개발자 분이 발견하셨습니다. 잠깐 나눈 스몰토크에서는 “엔진의 차이”라고 결론을 내렸습니다.

Q : 동일한 db.t3.micro를 사용하는데 MySQL과 MariaDB는 왜 max_connection이 다른가요?
A : 글쎄요. 서로 다른 엔진과 아키텍처에서 돌아가니까 연산식도 다른거 아닐까요?

이후 왜 max_connection이 다른지에 대한 이유를 찾고 싶어 딥다이브 하였습니다.

Connection* : 클라이언트와 서버가 맺은 물리적인 연결으로 이 역결을 통해서 쿼리와 그 결과를 주고 받음
SpringBoot PoolConnection* : HikariCP를 사용하고 있었으며 PoolConnection은 필요한 만큼의 Connection을 미리 연결하고 어플리케이션에서 이를 Pooling하여 필요한 순간에 필요한 장소에 할당하고 반납을 받는 식으로 운영을 합니다.
초기에 Connection*을 맺는데 필요한 시간을 절약할 수 있으나, 불필요한 Connection을 많이 연결해야 하는 단점도 존재합니다.

결론

결론부터 말하면 max_connection이 다른 이유는 연산식이 다른 것이 원인입니다.
Amazon RDS의 설정값은 주로 Amazon RDS 파라미터 그룹*의 값을 참조합니다.

  • MariaDB 10.6 : LEAST({DBInstanceClassMemory/25165760},12000)

  • MySQL 8.0 : (DBInstanceClassMemory/12582880)

즉 db.t3.micro는 메모리가 1 GB이므로 각각 42, 85 일 것으로 예상할 수 있습니다.

  • MariaDB 10.6 : LEAST({1073741824/25165760},12000)

  • MySQL 8.0 : (1073741824/12582880)

하지만 실제로 RDS를 생성하고 확인하면 max_connection은 각각 30, 60 정도입니다.

SELECT @@max_connections

MariaDB 10.6을 기준으로 오차가 12(42-30) 정도 발생을 하고 있습니다.
이 오차는 GB 표기법에 대한 오해*실 사용가능한 메모리*로 인해 발생합니다.

  1. GB 표기법에 대한 오해*

    1. 클라우드에서 정확한 수치를 나타낼 때는 1 GiB라고 표기하며 1024 MiB와 같습니다.

    2. 근사치를 나타낼 때는 1 GB라고 표기하며 1000 MB와 유사한 수치를 가집니다.

    3. 즉 db.t3.micro의 1 GB는 1 GiB가 아니며 RDS에서 향상된 모니터링*으로 확인하면, 943.5 MB의 용량을 가진 것을 알 수 있습니다.

    4. 역시 이를 바이트로 치환할때도 1024보다는 1000으로 연산하는 것이 옳아 보입니다.

  2. 실제 사용 가능한 메모리*

    1. RDS는 Hypervisor위에 Virtual Machine이 올라가면서 실행이 된다.

    2. 따라서 Hypervisor와 Virtual Machine 및 OS가 사용하는 메모리를 제외해야 한다.

    3. OS 프로세스에서 사용하고 있는 메모리는 약 117.36 MB이기에 사용 가능한 메모리는 826.14 MB일 것이다.

    4. CloudWatch Metric은 하이퍼 바이저의 매트릭이기 때문에 오차가 발생 가능하며,
      향상된 모니터링 및 OS 프로세스 항목은 에이전트(Agent) 레벨의 매트릭이다.
      즉 제공받고 있는 대시보드로는 Hypervisor가 소모하는 메모리 용량을 측정할 수 없으며 이에 따라서 계산식과 실제 max_connection에는 일부 오차가 발생한다.

이를 기준으로 계산하면 MariaDB 10.6의 max_connection은 32.67로 추정된다.

  • MariaDB 10.6 : LEAST({822410000/25165760},12000)

이는 실제 max_connection인 30과 10% 내외의 오차범위를 가지는 값이다.
즉 실제 메모리 총량, OS 프로세스 메모리, Hypervisor 메모리를 고려하면 10% 내외의 오차범위로 max_connection을 추정할 수 있을 것입니다.

딥다이브

하지만 역시 근본적인 의문이 해결되지 않았습니다.

왜 연산식이 다르며 max_connection은 어떤 파라미터들의 영향을 받는가?

이를 이해하기 위해서는 2가지 지식이 필요합니다.

  1. MySQL과 MariaDB의 아키텍처 적인 차이
    - [Ref] MySQL Architectrue 이해하기
    - [Ref] MariaDB Architecture 이해하기

  2. 다양한 파마리터들을 이해하기

open_file_limit 파라미터

open_files_limit은 MySQL 혹은 MariaDB가 열 수 있는 최대 파일 수니다.

MySQL Community 8.0 / MariaDB 10.6을 기준으로 open_files_limit은 5,000의 기본값을 가집니다. 이 값은 특정 DB 버전, OS 종류 및 버전 그리고 세부 설정 등에 따라 달라질 수 있습니다. - [Ref] # 7.1.10. Server Status Variables - open_files_limit

이때 가장 대표적인 파일은 데이터베이스 Engine이 만드는 테이블 파일입니다.
이 파일에는 테이블의 정보 및 정보 그리고 인덱스 데이터가 포함됩니다.
MySQL Community 8.0에서는 .idb라는 파일을 사용합니다. - [Ref]

OS 마다 다르겠지만 open_files_limit은 다음 연산식에 따라 계산됩니다.

10 + max_connections + (table_open_cache * 2)

실제로 어떤 값이 저장되어 있는지는 Amazon RDS의 다음 쿼리로 계산 가능합니다.

SELECT @@oepn_files_limit

다른 설정값들은 Amazon RDS Parameter Group에서 볼 수 있는 것과는 달리
해당 open_files_limit 설정값은 오직 SQL로만 조회가 가능합니다.

innodb_open_files

MySQL Community 8.0과 MariaDB 10.6을
Amazon RDS로 생성하게 된다면 open_files_limit은 어떤 값을 가지게 될까요?

MySQL Community 8.0 과 MariaDB 10.6 버전으로
Amazon RDS를 생성하면 innodb_open_files라는 변수를 사용합니다.
이 값은 Static Intetger 타입으로 Engine Default Variable을 가집니다.

MySQL Community 8.0 버전은
기본적으로 open_files_limit을 결정하기 위해 다음 연산식을 사용합니다.

10 + max_connections + (table_open_cache * 2)

기본적으로 MySQL Community 8.0 기준 아래의 연산식을 사용합니다.

AWS RDS에서 MariaDB에서는 innodb_open_files라는 값을 가집니다.
MySQL 8.0에서는 10 + max_connections + (table_open_cache * 2)의 연산식을 사용하지만 AWS RDS MariaDB 10.0에서는 engine의 default값을 static variables로 사용합니다.

    • MySQL SELECT @@open_file_limit

    • MariaDB

  • table_open_cache

참고 문헌

Share article

Unchaptered