MongoDB in Action 13

김하영·2022년 3월 2일
0

13.배포와 관리

13.1 하드웨어와 프로버저닝

MongoDB를 배포하기 전에 살펴봐야 할 첫 번째 질문은 '내가 배포해야 할 대상은 무엇인가?'다.
단일 랩톱에서 실제 서비스 전체의 클러스터를 실행한 경우 큰 문제가 발생할 것이다.

요구사항에 적합한 구성을 선택하는 방법, 다양한 하드웨어가 MongoDB에 미치는 영향 및 이 하드웨어를 프로비저닝할 때 사용할 수 있는 옵션에 대해 설명할 것이다.

13.1.1 클러스터 구성

MongoDB에는 총 세 가지 유형의 클러스터가 있다.

  1. 단일 노드
    MongoDB는 테스트 및 스테이징 환경을 지원하는 단일 서버로 실행될 수 있다.
    그러나 실제 서비스 환경 배포의 경우 저널링이 활성화된 경우라 하더라도 단일 서버를 사용하지 않는 것이 좋다.
    하나의 머신만 있으면 백업 및 복구가 복잡해지며, 서버에 장애가 발생해도 대체 작동할 장비가 없으므로 장애조치는 불가능하다. 즉, 신뢰성이 중요하지 않고 데이터 세트가 충분하지 않은 경우 이는 항상 선택사항이다.

  2. 복제세트
    복제 세트의 최소 권장 배치 구성은 세 개의 노드이며, 이 중 두 개는 아비터가 아닌 데이터 저장 노드이어야 한다.
    복제 세트는 자동 장애조치, 쉬운 백업이 지원되면서 단일 장애점을 원하지 않을 경우에 필요하다.

  3. 샤드 클러스터
    하나의 샤드만 있는 샤드 클러스터를 배포하면 샤딩의 이점 없이 오히려 부하만 추가되므로 샤드 클러스터의 최소 권장 배포는 두개의 샤드를 갖는다. 각 샤드는 복제 세트이어야 하며, 단일 장애점이 없도록 세 개의 설정 서버가 있어야 한다.

13.1.2 배포 환경

- 아키텍처

  1. MongoDB는 모든 데이터 파일을 가상 주소 공간으로 매핑하므로 실제 서비스를 위한 모든 배포는 64비트 서버에서 이뤄져야 합니다.

  2. MongoDB 서버와 함께 제공되는 구성 요소는 리틀 엔디언 서버에서 실행되어야 한다.
    (왜..?)

리틀 엔디안(little endian)

리틀 엔디안 방식은 낮은 주소에 데이터의 낮은 바이트(LSB, Least Significant Bit)부터 저장하는 방식이다.
이 방식은 평소 우리가 숫자를 사용하는 선형 방식과는 반대로 거꾸로 읽어야 한다.

대부분의 인텔 CPU 계열에서는 이 방식으로 데이터를 저장한다.
앞서 예를 든 정수 "0x12345678"를 리틀 엔디안 방식으로 저장하면 다음 그림과 같이 저장된다.

- CPU

MongoDB는 CPU를 특별하게 많이 사용하는 애플리케이션은 아니다.
인덱스와 작업 데이터를 램이 다 수용하고 나면 CPU가 많이 필요한 경우가 있을 수 있다.
CPU 코어를 추가해서 성능을 향상시킬 수 있다.

- 램

다른 데이트베이스와 마찬가지로 MongoDB는 램(RAM) 용량이 클 때 최적의 성능을 보인다.
자주 사용하는 인덱스와 작업 데이터를 램이 수용할 수 있도록 충분한 용향의 램을 갖는 하드웨어를 선택해야 한다.

- 디스크

디스크를 선택할 때는 비용, 초당 입출력 연산 횟수, 탐색 시간 그리고 저장소 용량등을 고려해야 한다.

디스크 성능은 다음과 같은 이유로 인해 중요하다.

  1. 높은 쓰기 작업 부하
    MongoDB에 쓰기를 할 때, 서버는 데이터를 다시 디스크로 플러시(flush) 해야한다.
    (flush : 버퍼에 있는 데이터를 모두 처리해라)
    쓰기가 많은 애플리케이션에서 디스크의 속도가 느리면 이 플러시로 인해 전체 시스템 성능이 저하될 수 있다.

  2. 빠른 디스크로 인해 서버가 더 빨리 시작할 수 있다.
    MongoDB에 대해 읽기 또는 쓰기를 연속적으로 수행할 때, 물리적인 메모리가 다 찰 때까지 새로운 가상 메모리 페이지를 램으로 읽어드린다. 디스크가 빠르면 이 프로세스가 빨라지는데, 서버를 재시작할 때 MongoDB의 성능을 향상한다.

  3. 빠른 디스크는 램에 대한 작업 데이터의 필요한 비율을 변경할 수 있다.
    SSD를 사용하면 그렇지 않을 경우보다 훨씬 적은 크기의 램으로 실행할 수 있다.

- 잠금

MongoDB의 잠금모델은 그 자체로 화제다.
실제로 모든 작업 부하가 다르고 경합 지점이 완전히 다를 수 있으므로 잠금 경합이 발생하지 않도록 주의 깊게 모니터링하거나 벤치마크해야 한다.

초기에는 MongoDB가 전체 서버에 대해 전역 잠금을 사용 > 각 데이터베이스 단위의 전역 잠금으로 업데이트 > 디스크 연산 전에 잠금을 해제하기 위한 지원이 추가 되었다.

- 파일시스템

적합한 파일시스템에서 수행할 경우 MongoDB는 최적의 성능을 가질 수 있다.
특별히 ext4와 xfs 파일 시스템은 빠르고 연속적인 디스크 할당이 특징이다.
이 파일 시스템을 이용하면 MongoDB에서 빈번하게 일어나는 선 할당의 속도가 빨라진다.

- 클럭

복제는 시스템 클럭(clock)차이에 민감하며, 이는 복제 세트의 노드를 호스팅하는 서버의 클럭이 서로 달라지게 되면 발생할 수 있다. 복제는 시간 비교에 크게 의존하므로 동일한 복제 세트의 서로 다른 시스템이 현재 시간과 다르면 심각한 문제가 발생할 수 있다.

각 서버에서 네트워크 타임 프로토콜(NTP)을 사용하거나 다른 동기화 프로토콜을 사용해서 클럭을 동기화해야 한다.

- 저너링

저너링이 사용되면 MongoDB는 모든 쓰기를 핵심 데이터 파일에 쓰기 전에 먼저 저널에 쓴다.
MongoDB 서버가 예상치 않게 셧다운되었을 때, 신속하고 정확하게 온라인 상태로 되돌아오게 해준다.

13.2 모니터링과 진단

13.2.1 로깅

로깅은 가장 간단한 수준의 모니터링이다.
배포할 때는 로그를 유지하고 관리할 계획을 세워야 한다.
이것은 큰 문제가 되지 않는데, 왜냐하면 MongoDB는 백그라운드에서 실행할 때는 --logpath 옵션을 지정해야 하기 때문이다.

  • 자세한 로깅 옵션 : -vvvvv 옵션
  • 기존의 로그를 이동하고 파일 이름에 타임스탬프를 덧붙이는 대신 기존 로그에 덧붙인다 : mongod --logappend

13.2.2 MongoDB 진단 명령어

MongoDB에는 내부 상태를 보고하는 데 사용되는 여러 가지 데이터베이스 명령이 있다.

  • 전역 서버 통계 : db.serverStatus()
  • 현재 실행 중인 연산의 통계 : db.currentOp()
  • 각 데이터베이스 카운터 및 액티비티 통계 : db.runCommand({top:1})
  • 메모리 및 디스크 사용 통계 : db.stats()

13.2.3 MongoDB 진단 도구

MongoDB에는 몇 가지 편리한 진단 도구가 함께 제공된다.

  • mongostat : 전역 시스템 통계
  • mongotop : 전역 연산 통계
  • mogonsniff : MongoDB 네트워크 트래픽 덤프
  • bsondump : BSON 파일을 JSON으로 표시

13.2.4 MongoDB 모니터링 서비스

MongoDB 사는 MMS 모니터링을 무료로 제공하여 시스템에 대한 이해를 돕게 하기 위해 대시 보드를 보는 것을 허용한다.

13.2.5 외부 모니터링 애플리케이션

중요한 배포 시스템은 대부분 외부 모니터링 애플리케이션이 필요하다.
배포된 MongoDB 시스템을 모니터링 할 수 있는 오픈 소스 시스템으로는 나기오스와 뮤닌이 인기가 있다.
간단한 오픈 소스 플러그인을 설치함으로써 이들 시스템을 MongoDB에서 이용할 수 있다.

13.3 백업

데이터베이스를 배포할 때, 사고에 대바해야 한다. 백업은 여기서 중요한 역할을 수행한다.
사고가 발생했을 때 백업이 있다면 그런 상황에서 벗어날 수 있다.

MongoDB를 백업하는 데는 일반적으로 다음과 같은 세 가지 방법이 있다.

  • mongodump 와 mongorestore
  • 데이터 파일 복사
  • MMS 백업 사용

13.4 보안

보안 환경, 네트워크 암호화, 인증 및 권한을 비롯한 주요 보안 유형에 대해 살펴보겠다.

13.4.1 안전한 환경

MongoDB도 안전한 환경에서 실행되어야 한다.

MongoDB를 방화벽과 함께 사용하는데 발생할 수 있는 유일한 난관은 어느 서버가 서로 통신해야만 하는지를 아는 것이다. 다행히도 통신 규칙은 상당히 간단하다.

  • 복제 세트의 경우에 각 노드는 다른 모든 노드와 통신할 수 있어야 한다.
  • 모든 데이터베이스 클라이언트는 읽거나 쓰려는 모든 복제 세트 노드에 연결할 수 있어야 한다.
  • 모든 통신은 TCP 프로토콜을 사용하여 수행된다.
  • 연결할 수 있는 노드는, 노드가 수신 대기하도록 구성된 포트에서 연결할 수 있음을 뜻한다.
    예를 들어, mongod는 기본적으로 TCP 포트 27017을 수신하므로 이에 연결 할 수 있으려면 해당 포트에서 연결할 수 있어야 한다.

샤드 클러스터는 부분적으로 복제 세트로 이루어져 있다. 따라서 모든 복제 세트 규칙이 적용되는데,
여기서 클라이언트는 mongos 라우터가 된다. 또한, 다음과 같은 규칙이 추가된다.

  • 모든 샤드는 직접 서로 통신할 수 있어야 한다.
  • 샤드와 mongos 라우터 모두 설정 서버와 통신할 수 있어야 한다.

13.4.2 네트워크 암호화

시스템을 보호하기 위한 가장 기본적인 측면은 네트워크 트래픽을 암호화 하는 것이다.
시스템이 완전히 격리되어 있고 신뢰하지 않는 사람이 트래픽을 볼 수 없는 경우가 아니라면 MongoDB를 암호화와 함께 사용해야 한다.

v2.4부터 MongoDB에는 이러한 암호화를 다루는 SSL이라는 라이브러리가 함께 내장되어 있다.

13.4.3 인증

  • 서비스 인증

MongoDB가 사용하는 SSL 라이브러리는 암호화를 제공할 뿐만 아니라 키를 보내는 사람이 그들이 주장하는 사람인지 확인하기 위해 인증서 인증이라는 것을 제공하는데, 이를 통신에 관여하지 않는 신뢰할 수 있는 제3자를 사용한다.

  • 사용자 인증

공격자가 시스템에 연결하는 것을 방지하기 위해 서비스 인증이 유용하기는 하지만, 때때로 개별 사용자 수준에서 액세스 권한을 부여하거나 회수하는 경우도 발생할 수 있다.

MongoDB에서 역할은 근복적으로 특권의 집합이먀, 특권은 MongoDB에서 수행할 수 있는 모든 연산이다.

  • 기본 인증 설정

auth가 활성화된 mongod 노드를 시작해야 한다. 이 노드가 샤드 클러스터 또는 replica set에 있는 경우 옵션을 전달하며 다른 서버와의 인증을 허용해야 한다.

  • 사용자 삭제

사용자를 삭제하려면 추가된 데이터베이스에서 dropUser 헬퍼를 사용하도록 하자.

13.4.4 복제 세트 인증

복제 세트에서 인증을 사용하려면 추가적인 구성이 필요한데, 이는 클라이언트가 복제 세트로 인증할 수 있을 뿐만 아니라 복제 세트 노드가 서로 인증할 수 있어야 하기 때문이다.

  • 키 파일 인증
  • X509 인증

13.4.5 샤딩 인증

샤딩 인증은 복제 세트 인증을 확장한 것으로

  • 키 파일 인증
  • X509 인증

을 사용하여 인증하도록 설정할 수 있다. 그러고 나면 전체 클러스터에서 인증을 사용할 수 있다.

13.5 관리 작업

13.5.2 압축과 복구

MongoDB는 내장 툴인 데이터베이스의 복구 기능을 가지고 있다.

mongod --repair

복구는 오프라인 작업이다.
실행되고 있는 동안에 데이터베이스는 읽기와 쓰기에 대해 잠금상태에 놓인다.

MongoDB의 복구는 원래는 손상된 데이터베이스를 복구하기 위한 마지막 수단으로 사용되었다.
불시에 셧다운되거나 저널링을 사용하지 않으면 데이터 파일을 다시 일관된 상태로 되돌릴 수 있는 유일한 방법은 복구 뿐이다. 하지만 복구는 피하는 것이 좋다.

그렇다면 데이터베이스 복구는 무엇을 위한 것일까?
복구 작업은 데이터 파일을 압축하고 인덱스를 재구축한다.
이를 통해 램의 공간을 보다 효율적으로 사용할 수 있다.

13.6 성능 문제 해결

13.6.1 작업 데이터

작업데이터는 지정된 시간 간격으로 액세스하는 데이터의 양이다.
만약 8GB 램에 16GB를 한번에 모두 지정할 수 없으므로 수많은 스래싱을 가지게 되고, 많은 양의 데이터가 램 내부 및 외부로 이동한다.

스래싱

너무 자주 페이지 교체가 일어나는 현상으로 어떤 프로세스에 지속적으로 페이지 부재가 발생하여 프로세스의 처리시간보다 페이지 교체시간이 더 많이 발생하는 현상이다.

그러나 쿼리가 제대로 인덱싱 되고 데이터 중 가장 최근에 1/4 정도만 쿼리하는 경우 2GB 메모리만 사용할 수 있다.

올바른 인덱스 추가와 같은 간단한 변경이 성능 특성을 완전히 바꿀 수 있다는 것을 보여준다,

13.6.2 성능 절벽

3.0에서 MongoDB는 단일 연산에서 사용할 수 있는 리소스를 제한하지 않으며, 또한 마비 상황에 있을 때 클라이언트를 명시적으로 다시 밀어내지 않는다. 이는 한계 치에 도달하지 않는 한 이것은 문제가 되지 않지만, 제한에 도달하게 되면 '성능 절벽'을 볼 수 있다.

이를 방지하기 위해 MongoDB 배치가 얼마나 많은 부하를 처리할 수 있는지 정확히 이해하고, 가능하다면 앞에 로드 밸런서를 놓아 벼랑의 끝에서 헤어나올 것을 강력히 추천한다.

13.6.3 쿼리 상호작용

MongoDB가 자원 제한을 시행하지 않는다는 것의 또 다른 부수 효과는 잘못 작동하는 하나의 쿼리가 시스템의 다른 모든 쿼리 성능에 영향을 미칠 수 있다는 것이다.

즉 데이터 베이스를 질의할 수 있는 모든 사람이 잘못된 쿼리로 인해 발생하는 결과를 이해하는지 확인해야한다.

(몽고는 성능을 위해 고려해야할게 많은 것 같다...)

profile
Back-end Developer

0개의 댓글