Tuning & Monitoring

Tuning

  • 시간이 지남에 따라 처음 설계와 사용자의 패턴이 달라지는 경우
  • 잘못된 설계를 가지는 경우
  • 데이터 축적, 장비의 노후화에 따른 성능 감소

위와 같은 상황이 발생하는 경우, Tuning을 통해 성능을 높일 수 있다.

Types of Tuning

HW Tuning

가장 간단한 튜닝 방식으로, 하드웨어 스펙을 높이는 방식이다. 데이터 모델, 쿼리 튜닝의 경우 비즈니스 모델에 깊은 이해가 동반되어야 하며, 아키텍처, 인스턴스 튜닝의 경우 실제 서비스 단계에서 적용하기 어려운 튜닝 방식이다. hdd->ssd, memory 증축, 다중 코어의 cpu 사용 등이 해당된다.

데이터모델 튜닝

초기에 설계한 데이터 모델의 성능이 좋지 않을 경우 적용되는 튜닝방식으로, 사전에 컬렉션에 대한 적절한 분석, 설계가 이루어지 않았거나, 예측하지 못한 데이터가 입력되는 경우, 용도 변경 등의 상황이 발생하는 경우 적용할 수 있는 튜닝방식이다.

MongoDB에 최초로 collection을 생성하게 되면 기본 익스텐트 크기가 할당되는데, 초기에 해당 크기가 너무 작게 설정되는 경우 쓰기 작업이 발생할때 새로운 익스텐트를, 할당받게 됨에 따라 지연이 발생하게 된다. 이와 같은 문제는 MongoDB 뿐만아니라 RDMBS에서도 종종 발생하는 문제이다. 초당 수만건의 빅데이터가 활용되는 환경에서, 적절한 크기의 익스텐트를 지정하는 것이 필요하다.

쿼리 튜닝

explain 기능을 통해 쿼리가 동작하는 방식을 분석하여 성능이 저하되는 부분을 확인하여 해당 부분을 개선한 쿼리를 활용한다. full-table scan을 index scan을 활용한 쿼리로 변환하는 것이 쿼리 튜닝에 해당된다.

아키텍쳐 튜닝

MongoDB는 메모리를 활용하여 데이터를 읽고 쓰기 때문에 충분한 크기의 map memory 영역이 요구되며, 가능한 하나의 시스템에서는 하나의 인스턴스 만을 동작하여 스크래치 디스크(메모리가 부족하여 하드디스크에 데이터를 일부 저장하는 기능)이 생성되지 않도록 한다. 단일 노드보다는 다중 노드를 활용하여 대용량 데이터를 처리하고 분산 저장, load balancing 기능을 활용할 수 있도록 구조를 설계한다.

Profile

MongoDB는 실행되는 쿼리 결과에 대해 프로파일링을 진행한다. 분석된 결과를 토대로 일정 시간 이상으로 실행되는 쿼리를 개선하여 성능을 높일 수 있다.

profile 기능 켜기

Enterprise admin> db.setProfilingLevel(2)
/*
*0: 프로파일링 기능이 꺼진 상태
*1: 100ms 이상 걸린 정보를 저장
*2: system에서 발생한 모든 정보를 저장
*/
{ was: 0, slowms: 100, sampleRate: 1, ok: 1 }

profile 분석 결과 확인

Enterprise admin> db.system.profile.find()
[
  {
    op: 'query',
    ns: 'admin.system.profile',
    command: {
      find: 'system.profile',
      filter: {},
      lsid: { id: new UUID("1fd88d60-192c-4aec-9ccf-edc9871d68f9") },
      '$db': 'admin'
    },
    keysExamined: 0,
    docsExamined: 0,
    cursorExhausted: true,
    numYield: 0,
    nreturned: 0,
    queryHash: '17830885',
    queryFramework: 'classic',
    locks: {
      FeatureCompatibilityVersion: { acquireCount: { r: Long("1") } },
      Global: { acquireCount: { r: Long("1") } },
      Mutex: { acquireCount: { r: Long("1") } }
    },
    flowControl: {},
    responseLength: 109,
    protocol: 'op_msg',
    millis: 0,
    planSummary: 'COLLSCAN',
    execStats: {
      stage: 'COLLSCAN',
      nReturned: 0,
      executionTimeMillisEstimate: 0,
      works: 2,
      advanced: 0,
      needTime: 1,
      needYield: 0,
      saveState: 0,
      restoreState: 0,
      isEOF: 1,
      direction: 'forward',
      docsExamined: 0
    },
    ts: ISODate("2023-01-16T02:46:44.949Z"),
    client: '127.0.0.1',
    appName: 'mongosh 1.6.1',
    allUsers: [],
    user: ''
  },
  {
    op: 'query',
    ns: 'admin.things',
    command: {
      find: 'things',
      filter: {},
      lsid: { id: new UUID("1fd88d60-192c-4aec-9ccf-edc9871d68f9") },
      '$db': 'admin'
    },
    keysExamined: 0,
    docsExamined: 0,
    cursorExhausted: true,
    numYield: 0,
    nreturned: 0,
    queryFramework: 'classic',
    locks: {
      FeatureCompatibilityVersion: { acquireCount: { r: Long("1") } },
      Global: { acquireCount: { r: Long("1") } },
      Mutex: { acquireCount: { r: Long("1") } }
    },
    flowControl: {},
    responseLength: 101,
    protocol: 'op_msg',
    millis: 0,
    planSummary: 'EOF',
    execStats: {
      stage: 'EOF',
      nReturned: 0,
      executionTimeMillisEstimate: 0,
      works: 0,
      advanced: 0,
      needTime: 0,
      needYield: 0,
      saveState: 0,
      restoreState: 0,
      isEOF: 1
    },
    ts: ISODate("2023-01-16T02:49:52.175Z"),
    client: '127.0.0.1',
    appName: 'mongosh 1.6.1',
    allUsers: [],
    user: ''
  }
]

Security

인증

RDBMS와 달리 설치 과정에서 인증과 관련된 설정이 없어 누구나 DB에 접속이 가능하다는 점 보안 취약점을 가지고 있는데, 허가된 사용자만 DB에 접속할 수 있또록 계정/패스워드를 설정하는 것이 필요하다. 계정/패스워드 설정 이후에 –auth 옵션을 활용하여 인증 기반의 접속을 활용한 DB를 실행한다. 또한, 각각의 db 별로 계정/패스워드를 추가하여 사용하는 것이 좋다.

MongoDB 종료

DB 서비스를 안전하게 종료하기 위해 shell을 접속하여 db.shutdownServer() 명령어를 수행하여 종료하는 것이 가장 안전하다. DB 서비스를 종료하는 것 또한 관리자의 기능이므로 위의 인증 기반의 인스턴스 실행을 통해 종료 기능에 대한 접근을 제한하도록 한다.

References

댓글남기기