Mysql 루프백 주소 대신 Localhost로 접속하자

Hansu Park·2024년 3월 31일
3
post-thumbnail
post-custom-banner

(대상: OS, 네트워크를 전공자 수준으로 이해하시는 분)

서론

안녕하세요. 오늘은 최근에 알게된 사실에 대해 다루어보려고 합니다. 이는 mysql이 루프백 주소 대신 Localhost로 접속할 때 더욱 효율적인 통신방식을 선택하고 있다는 점입니다.

본론

mysql은 기본적으로 커넥션을 맺을 때 TCP/IP 방식을 사용합니다. TCP/IP는 안정성은 뛰어나지만 이에 대한 트레이드 오프로 성능은 비교적 빠르지 않다고 알고있습니다. 제가 속한 BCSD Lab(동아리)가 운영하는 서버는 Mysql과 어플리케이션 서버가 같은 AWS 인스턴스에 위치하고 있었고(~ 24.3), 이러한 환경에서는 TCP/IP 방식의 단점이 두드러진다고 줄곧 생각해왔습니다.

(TCP/IP 방식은 (1) 빈번한 핸드쉐이크 (2) 불필요하게 큰 헤더의 크기 (3) 각종 제어로 인한 오버헤드로 인해 IPC나 UDP에 비해 속도가 빠르지 않다고 알고있습니다.)

어느날, 우연히 보게 된 게시글인 MAMP의 MySQL 포트가 3306이 아닌데도 localhost라고만 적었을 때 접속이 되는 이유 – 형우의 웹개발 에서 localhost라고 작성했을 경우에는 TCP/IP가 아닌 IPC로 통신한다는 사실을 알게되었습니다. 정확히는 Unix/Linux 환경에서는 프로세스를 이용하여 통신하는 유닉스 소켓을, 윈도우즈 환경에서는 메모리 공간을 공유하여 통신하는 공유 메모리 방식을 사용한다는 점을 알게되었습니다. (참고: MySQL :: MySQL 8.0 Reference Manual :: 6.2.4 Connecting to the MySQL Server Using Command Options)

저는 일반적으로 서버에 활용되는 Unix/Linux 환경에서 사용하는 통신 방법인 소켓 방식이 TCP/IP에 비해 얼마나 빠른지 궁금했고 직접 테스트해봤습니다.

테스트 환경

  • mysql: 8.3.0
  • Go: 1.21
  • 테스트 내용: 간단한 조회문(SELECT nickname FROM user WHERE id = 1, id = PK) 1만 회를 마쳤을 때의 시간
  • 변인: 커넥션 타입 (TCP/IP vs Unix Socket)

테스트 진행

작성한 코드 보러가기
Go Mysql TCP/IP vs Socket · GitHub

실행 로그

테스트 결과

테스트 해본 결과 (1만회)

  • 유닉스 소켓: 335ms
  • TCP/IP: 440ms
    로 소켓이 1.3배 정도 빠른 것을 확인했습니다.

테스트 분석

그렇다면 왜 유닉스 소켓 방식이 빠를까요?

단적으로는 위 이미지처럼 불필요한 레이어를 거치지 않기 때문입니다.

자세히는 아래 3가지 때문입니다.

1. 패키징 횟수

레이어를 이동하며 발생하는 패키징, 언패키징 과정이 덜 이루어집니다.

2. 커넥션의 특징

도입부분에서 언급한 대로 TCP 커넥션은 타 네트워크 통신을 위해 설계되었고 유닉스 소켓은 프로세스간 통신을 위해 설계되어 가볍습니다.

TCP 커넥션의 비용

  • TCP 3-way, 4-way 핸드쉐이크 비용.
  • 비효율적으로 큰 헤더의 크기.
  • 데이터의 양이 많은 경우 패킷 분리 및 재조립 비용.
  • 혼잡제어, 흐름 제어, 오류 제어등을 처리하는 비용.

3. 메모리 접근

TCP 커넥션보다 적은 메모리 접근, 복사 과정이 일어납니다.

결론

로컬호스트 환경에서 mysql 통신할 때에는 루프백 주소인 127.0.0.1 보다 localhost를 이용하는 것이 더 빠릅니다.

기타

느낀 점

  • 우연히 저 블로그를 보지 않았다면 해당 내용을 궁금해했음에도 몰랐을 거라는 점을 반성해야 할 것 같습니다. 앞으로는 적극적으로 궁금한 내용을 조사해봐야 할 것 같습니다.
  • DB, Network, OS 등 여러 지식이 혼합되는 사례를 직접 분석해보니 유익했고 CS의 필요성을 느꼈습니다.

아쉬운 점

  • mac 환경에서 localhost를 사용했을 때 유닉스 소켓을 쓰는 것을 확인하고 싶었는데 못했습니다.
    • 도커 환경이 문제인가 싶어서 로컬환경에 mysql 설치 및 실행함.
    • 소켓을 못찾나 싶어서 my.cnf 에 소켓 위치 지정함.
      등을 시도해봤습니다. 설정 방법 아시는 분 있으면 댓글 달아주세요.
  • 로그는 general_log 을 통해 확인했습니다. (쿼리를 통해 옵션을 켜야 합니다.)
  • mongodb, redis도 유닉스 소켓은 가능하나 localhost 설정시 기본으로 되진 않는 것 같다.
    • 참고로 1만회 실행시 성능은 각각 240ms (redis), 4710ms (mongodb) 였다.

참고

post-custom-banner

0개의 댓글