MongoDB 튜닝 방법

MongoDB 튜닝

  • 데이터베이스 튜닝이 필요한 시점
    • 시간이 지남에 따라 처음 설계와 사용자의 패턴이 달라짐
    • 잘못된 설계를 가지고 있는 경우
    • 처음과 달리 데이터가 축척되거나 장비의 노후화
  • 데이터베이스 튜닝 방법
    • 데이터 모델 튜닝
    • 질의 튜닝
    • 아키텍쳐 튜닝
    • 인스턴스 튜닝
    • 하드웨어 튜닝
  • 가장 쉬운 방법은 하드웨어를 업그레이드하는 하드웨어 튜닝
  • 데이터 모델이나, 질의 튜닝은 비즈니스 모델에 대한 깊은 이해를 필요로 하는 어려운 튜닝 방법
  • 아키텍쳐 튜닝이나 인스턴스 튜닝은 실 서비스 단계에서 선택하기에 어려운 점이 많음
  • 데이터 모델이나 질의 튜닝도 데이터 마이그레이션을 동반하기 때문에 라이브 모드에서 쉽지 않다.

데이터 모델 튜닝

  • 데이터 모델 튜닝은 초기에 설계한 데이터 모델이 제대로 성능을 발휘하지 못할 때 필요
    • 데이터를 저장하는 논리적 구조인 컬렉션에 대한 적절한 분석과 설계가 사전에 이루어지지 못했을 경우
    • 예측하지 못했던 데이터를 입력했을 경우
    • 프로젝트 막바지에 용도 변경 등이 발생했을 경우
  • 최종적으로 현재에 알맞은 데이터 모델을 갖고 있지 못한다면 결국 지속적인 시스템 성능 저하가 발생하기 때문에,
    근본적인 해결이 필요 
  • MongoDB에서는 최초로 컬렉션을 생성하면 기본 익스텐트 크기가 할당됨
    • 이 크기가 너무 작게 지정되면 쓰기 작업이 발생할 때 새로운 익스텐트를 할당받을 때마다 지연 발생
    • 결국 이것이 시스템 성능 저하로 이어질 수 있음
    • 이 문제는 MonogoDB만의 문제는 아니고 대부분의 관계형 데이터베이스에서도 발생하는 보편적 문제
  • 초당 몇 만 건 이상 되는 빅데이터 처리를 위해서라면 미리 이 숫자를 예측하여 저장할 필요가 있음
  • MongoDB의 Document 자료 구조
    • 데이터를 중첩하며 Embedding 형태로 데이터를 구성하는 것을 추천
    • 다만 내장된 데이터를 관련도와 상관없이 무조건 Embedding 형태로 만들 필요 없음
    • MongoDB에도 데이터가 밀접하지 않다면 Linking 방식으로 설계하는 것을 고려
  • MongoDB도 빠른 검색을 위한 인덱스 시스템을 가지고 있음
    • 백그라운드 인덱스 타입으로 생성 가능
    • insert 마다 인덱스를 생성하여 성능 저하가 발생하지 않도록 해야 함
  • MonogoDB의 복합 인덱스 ( Compound Index )
    • 기존 RDBMS처럼 다중으로 인덱스를 거는 것이 가능
    • 여러 필드 중 분포도가 좋은 필드를 우선순위로 지정할 필요가 있음
    • 잦은 필드의 수정이나 삭제 입력이 빈번한 필드는 인덱스에서 가능한 배제

질의 튜닝

  • MongoDB는 서버에 질의된 문장을 profiling 하는 것이 가능
  • 이때 분석 결과는 db.system.profile Collection에 저장
  • 다른 RDBMS처럼 explain 함수를 지원하기 때문에 질의 문장들의 분석이 가능
  • 이 명령어를 통해 질의 문장의 성능이 저하되는 원인인 인덱스 문제를 확인할 수 있음
  • 특정한 경우 인덱스를 활용하지 못하는 문제를 발견할 수 있기 때문에,
    인덱스 생성 정책 결정에 도움이 됨

아키텍처 튜닝

  • MongoDB는 운영체제의 메모리 설정을 따라가기 때문에 충분한 map memory 영역이 필요함
  • 불필요하게 하나 이상의 MongoDB 인스턴스를 띄우게 되면 메모리 부족 현상이 발생하기 때문에
    실제 성능은 반드시 저하됨
  • 가능하면 memory를 충분히 사용할 수 있도록 하나의 시스템에서는 한 개의 인스턴스만
    실행하여 스크래치 디스크(메모리가 부족하여 하드디스크 일부 메모리를 임시 저장하는 기능)
    을 생성하지 않도록 해야 함
  • 대용량 데이터가 입력될 때는 단일 노드보다 다중 노드로 서비스하는 것이 유리
  • 아무리 MongoDB가 insert 성능이 뛰어나다고 하더라도 하드웨어 성능 이상을 끌어내가 어려움
  • 샤드 시스템을 갖추면 분산 저장과 Load Balancing의 장점을 얻을 수 있음

하드웨어 튜닝

  • 아무래도 가장 쉬운 방법
    • HDD보다 SSD를 사용
    • 최대의 메모리를 장착하여 충분한 메모리 공간을 확보
    • CPU를 다중 코어를 활용하면 CPU의 과부하를 막을 수 있음
    • 다중 노드를 사용하여 분산 처리가 가능하게 함
  • Mongopref 유틸리티를 사용하면 MongoDB의 Disk I/O 상태 확인 가능
    • 하드 디스크는 가장 저렴한 비용으로 데이터를 저장할 수 있음
    • 디스크라는 물리적 저장장치를 사용하기 때문에 시스템 성능 저하의 가장 큰 원인
    • 빅데이터 처럼 대용량의 쓰기 / 읽기 작업을 필요로 한다면,
      SSD를 도입하여 데이터의 접근 속도를 높일 필요가 있음

Profile 시스템

  • MongoDB는 서버와 사용자에 의해 실행된 질의 결과에 대한 프로파일링 시스템 제공
  • 분석 결과는 .db.system.profile 컬렉션에 저장
  • 로그 정보 중 쿼리가 실행될 때 일정 시간이 초과된 질의 문자들을 필요에 따라 추출 가능
  • 이 문장들을 기준으로 성능 튜닝을 할 명령 대상들을 선정하는 것이 가능
  • Profile 기능을 활용하기 위해서는 환경설정 필요
  • Profile 시스템 도움말 확인
    • > db.commandHelp("profile")
  • 현재 프로파일 설정 상태 확인
    • > db.getProfilingLevel()
    • Profile Level 값이 0이면 프로파일링 시스템을 사용하지 않음
    • 1이면 100ms 이상 걸린 정보 저장, 2면 System에서 발생한 모든 정보를 저장
  • 현재 프로파일링 설정 변경
    • > db.setProfilingLevel(2)
  • 저장된 프로파일 정보 조회
    • > db.system.profile.find() / 전체 내역 확인
    • > db.system.profile.find( {millis:{$gt:5} ) / 특정 시간 이상 걸린 정보들만 조회

MongoDB 보안 팁

인증 설정

  • MongoDB는 설치 과정 중 인증과 관련된 설정을 하는 부분이 없음
    • 설치 후 누구나 DB에 접속할 수 있음
    • 허가된 사용자만이 DB에 접속할 수 있도록 계정 및 패스워드를 설정해야 함
    • Mysql과 마찬가지로 DB 인스턴스 (bin/mongod)를 실행할 때 인증정보를 사용하겠다는
      파라미터 (-auth)를 포함해야 함
  • 데이터베이스별로 계정과 패스워드를 추가하여 사용하는 것을 권장
    • 각 데이터베이스별 계정 정보는 system.users 라는 namespace에 저장
    • db.removeUser(username) 명령으로 계정 삭제 가능

MongoDB 종료

  • MongoDB의 안전 종료 방법
    • 데이터베이스 인스턴스를 foregroud로 실행 시 : Ctrl-C 또는 kill -2 PID, kill -15 PID
    • MongoDB Shell 이용 시 : db.shutdownServer() 명령
    • 드라이버 이용 시 : {"shutdown" : 1} 명령
  • 데이터베이스를 shutdown 하는 것은 관리자만이 할 수 있어야 하기 때문에
    반드시 -auth 파라미터를 사용하여 mongod 인스턴스를 구동시켜야 함
  • 사용하고자 하는 버전에서 db.shutdownServer() 명령이 제대로 지원되는지 확인해야 함

HTTP 인터페이스 보안

  • 누구나 HTTP 인터페이스에 접근해서는 안되기 때문에,
    반드시 -auth 파라미터를 사용하여 mongod 인스턴스를 구현해야 함

+ Recent posts