저자는 Write for Donations 프로그램의 일환으로 Open Internet/Free Speech Fund를 기부 대상으로 선택했습니다.
소개
모니터링은 데이터베이스 관리의 중요한 부분으로, 데이터베이스의 성능 및 전반적인 상태를 이해할 수 있도록 합니다. 데이터베이스 성능을 모니터링함으로써 현재 용량을 더 잘 파악할 수 있으며, 시간이 지남에 따라 작업 부하가 어떻게 변하는지 관찰하고, 데이터베이스가 한계에 다다를 때 확장할 준비를 할 수 있습니다. 또한 예기치 않은 데이터베이스 사용의 급격한 증가와 같은 하드웨어 문제나 비정상적인 동작을 알아차릴 수 있습니다. 마지막으로, 모니터링은 데이터베이스를 사용하는 애플리케이션의 문제를 진단하는 데 도움이 될 수 있습니다. 이는 병목 현상을 일으키는 응용 프로그램 쿼리와 같은 문제점을 발견하는 데 도움이 됩니다.
MongoDB에는 데이터베이스 성능을 관찰할 수 있는 다양한 도구와 유틸리티가 설치되어 있습니다. 이 튜토리얼에서는 내장된 명령어와 도구를 사용하여 데이터베이스 메트릭을 요청 시 모니터링하는 방법을 배우게 될 것입니다. 또한 MongoDB의 데이터베이스 프로파일러를 사용하여 최적화되지 않은 쿼리를 감지하는 방법에 익숙해지게 될 것입니다.
필수 조건
이 튜토리얼을 따르려면 다음이 필요합니다:
- A server with a regular, non-root user with
sudo
privileges and a firewall configured with UFW. This tutorial was validated using a server running Ubuntu 20.04, and you can prepare your server by following this initial server setup tutorial for Ubuntu 20.04. - 서버에 설치된 MongoDB. 이를 설정하려면 Ubuntu 20.04에 MongoDB 설치하는 방법 튜토리얼을 따르십시오.
- 서버의 MongoDB 인스턴스를 인증을 활성화하고 관리자 사용자를 생성하여 보안합니다. 이렇게 MongoDB를 보안하려면 Ubuntu 20.04에서 MongoDB 보안하는 방법 튜토리얼을 따르십시오.
- MongoDB 컬렉션 쿼리 및 결과 필터링에 대한 이해. MongoDB 쿼리를 사용하는 방법은 MongoDB에서 쿼리 만드는 방법 가이드를 참조하십시오.
참고: 서버 구성, MongoDB 설치 및 MongoDB 설치를 보호하는 방법에 대한 링크된 튜토리얼은 Ubuntu 20.04를 기준으로합니다. 이 튜토리얼은 주로 운영 체제와 관계없이 인증이 활성화되어 있으면 어떤 MongoDB 설치에서든 작동합니다.
단계 1 — 테스트 데이터 준비
MongoDB의 성능을 모니터링하는 방법을 설명하기 위해이 단계에서는 로컬에 설치된 MongoDB 인스턴스에 연결하고 그 내에 샘플 컬렉션을 생성하는 방법에 대해 설명합니다.
이 가이드에서 사용되는 샘플 컬렉션을 생성하려면 관리자 사용자로서 MongoDB 셸에 연결하십시오. 이 자습서는 전제조건인 MongoDB 보안 자습서의 관례를 따르며 이 관리 사용자의 이름이 AdminSammy이고 인증 데이터베이스가 admin
임을 가정합니다. 다음 명령에서 이러한 세부 정보를 자신의 설정과 다르다면 변경하십시오:
접근 권한을 얻으려면 설치 중 설정한 암호를 입력하십시오. 암호를 제공한 후에는 >
프롬프트 부호가 표시됩니다.
참고: 새 연결에서 MongoDB 셸은 기본적으로 test
데이터베이스에 연결합니다. MongoDB 및 MongoDB 셸을 실험하는 데 이 데이터베이스를 안전하게 사용할 수 있습니다.
또는 이 자습서에서 제공된 모든 예제 명령을 실행할 다른 데이터베이스로 전환할 수도 있습니다. 다른 데이터베이스로 전환하려면 use
명령 다음에 데이터베이스 이름을 입력하십시오:
작은 데이터 세트로 작업할 때 데이터베이스 모니터링은 매우 실용적이거나 유용하지 않습니다. 왜냐하면 데이터베이스 시스템은 어떤 쿼리에 대해서도 몇 개의 레코드만 스캔해야하기 때문입니다. MongoDB의 성능 모니터링 기능을 설명하기 위해서는 MongoDB가 쿼리를 실행하는 데 상당한 시간이 걸리는 충분한 데이터가 있는 데이터베이스가 필요합니다.
이를 위해,이 가이드 전반에 걸쳐 예제는 많은 문서를 포함하는 accounts
라는 샘플 컬렉션을 참조합니다. 각 문서는 무작위로 생성된 계좌 잔액을 나타냅니다. 컬렉션 내의 각 문서는 다음과 같은 구조를 갖습니다:
이 예시 문서에는 다음 정보가 포함되어 있습니다:
number
: 이 필드는 주어진 계정의 계좌 번호를 나타냅니다. 이 컬렉션에서 각 계정 번호는 증가하는 숫자 식별자를 가진1000-
접두사가 있습니다.currency
: 이 필드는 각 계좌의 잔액이 저장된 통화의 종류를 나타냅니다. 각 계정의currency
값은USD
또는EUR
중 하나일 것입니다.balance
: 이는 각 은행 계좌의 잔액을 나타냅니다. 이 샘플 데이터베이스에서 각 문서의balance
필드는 무작위로 생성된 값을 갖게 됩니다.
대량의 문서를 수동으로 삽입하는 대신, 다음 JavaScript 코드를 실행하여 동시에 accounts
라는 컬렉션을 생성하고 백만 개의 이러한 문서를 삽입할 수 있습니다:
이 코드는 연이어 백만 번 실행되는 for
루프를 실행합니다. 루프가 반복될 때마다, 새 문서를 삽입하기 위해 계정 컬렉션에서 insertOne()
메서드를 실행합니다. 각 반복에서 메서드는 해당 반복의 i
값으로 이루어진 1000-
접두사와 함께 number
필드에 값을 제공합니다. 이는 루프가 처음 반복될 때 number
필드 값이 1000-1
로 설정되고, 마지막으로 반복될 때 1000-1000000
으로 설정됩니다.
통화는 숫자가 500000보다 높은 계정에 대해 항상 USD
로 표시되고, 해당보다 낮은 숫자의 계정에 대해 EUR
로 표시됩니다. 잔액 필드는 Math.random()
함수를 사용하여 0부터 1 사이의 난수를 생성한 다음 이 난수를 100000으로 곱하여 더 큰 값을 제공합니다.
참고: 이 루프를 실행하는 데 시간이 오래 걸릴 수 있으며, 10분 이상 걸릴 수 있습니다. 작업이 완료될 때까지 작업을 실행하도록 안전합니다.
출력에서는 성공 여부를 알려주고 삽입된 마지막 문서의 ObjectId
를 반환합니다:
Output{
"acknowledged" : true,
"insertedId" : ObjectId("61a38a4beedf737ac8e54e82")
}
문서가 올바르게 삽입되었는지 확인하려면 인수 없이 count()
메서드를 실행하여 컬렉션의 문서 수를 검색할 수 있습니다:
Output1000000
이 단계에서는 이 가이드에서 MongoDB가 제공하는 성능 모니터링 도구를 설명하는 데 사용되는 테스트 데이터의 예제 문서 목록을 성공적으로 생성했습니다. 다음 단계에서는 기본 서버 사용 통계를 확인하는 방법을 배우게 됩니다.
단계 2 — 서버 사용 통계 확인
MongoDB는 자동으로 여러 유용한 성능 통계를 추적하며, 이를 정기적으로 확인하는 것은 데이터베이스를 모니터링하는 기본적인 방법입니다. 이러한 통계는 데이터베이스에서 무슨 일이 일어나고 있는지에 대한 실시간 통찰력을 제공하지는 않지만, 데이터베이스가 어떻게 작동하는지 및 임박한 문제가 있는지를 판단하는 데 유용할 수 있습니다.
경고: 이 안내서에서 소개하는 MongoDB 모니터링 명령은 데이터베이스 및 성능에 대한 잠재적으로 민감한 정보를 반환합니다. 따라서 이러한 명령 중 일부는 고급 권한이 필요합니다.
구체적으로, 이 단계에서 소개된 serverStatus()
메서드와 다음 단계에서 강조된 mongostat
및 mongotop
명령은 사용자가 이를 실행하려면 clusterMonitor
역할이 부여되어야 합니다. 마찬가지로, 단계 4에서 소개된 setProfilingLevel()
메서드는 dbAdmin
역할이 필요합니다.
이 안내서에서의 예제를 따라가려면 Ubuntu 20.04에서 MongoDB를 보안하는 방법에 대한 필수 자습 안내서를 따르고 해당 안내서에서 생성한 관리자 사용자로 MongoDB 인스턴스에 연결되었다고 가정하고, 이러한 추가 역할을 부여해야 합니다.
먼저 사용자의 인증 데이터베이스로 전환하십시오. 다음 예제에서는 admin
입니다. 사용자의 인증 데이터베이스가 다르면 해당 데이터베이스로 연결하십시오:
Outputswitched to db admin
다음으로 grantRolesToUser()
메서드를 실행하여 사용자에게 clusterMonitor
역할과 함께 accounts
컬렉션을 만든 데이터베이스에서 dbAdmin
역할을 부여하십시오. 다음 예제는 accounts
컬렉션이 test
데이터베이스에 있는 것으로 가정합니다:
사용자 프로필을 특정 목적에 전용으로 사용하는 것이 일반적으로 더 안전하다는 점에 유의하십시오. 이렇게 하면 어떤 사용자도 불필요하게 넓은 권한을 가지지 않습니다. 프로덕션 환경에서 작업하는 경우 데이터베이스를 모니터링하는 데 전용 사용자를 가질 수 있습니다.
다음 예제는 MongoDB 사용자인 MonitorSammy를 생성하고 이 자습서의 예제를 따라 진행하기 위해 필요한 역할을 부여합니다. 이 사용자에게는 클러스터의 모든 데이터베이스에서 데이터를 읽고 쓸 수 있게 하는 readWriteAnyDatabase
역할도 포함됩니다:
적절한 역할을 사용자에게 부여한 후에는 accounts
컬렉션이 저장된 데이터베이스로 돌아갑니다:
Outputswitched to db test
stats()
메서드를 실행하여 전체 데이터베이스 통계를 확인하는 것으로 시작하십시오:
이 메서드의 인수인 1024*1024
는 스케일 팩터로, MongoDB에게 스토리지 정보를 메가바이트 단위로 반환하도록 지시합니다. 이를 생략하면 값이 모두 바이트로 표시됩니다.
stats()
메서드는 현재 데이터베이스와 관련된 몇 가지 중요한 통계를 간결하고 간략하게 반환합니다:
Output{
"db" : "test",
"collections" : 3,
"views" : 0,
"objects" : 1000017,
"avgObjSize" : 80.8896048767171,
"dataSize" : 77.14365005493164,
"storageSize" : 24.109375,
"indexes" : 4,
"indexSize" : 9.9765625,
"totalSize" : 34.0859375,
"scaleFactor" : 1048576,
"fsUsedSize" : 4238.12109375,
"fsTotalSize" : 24635.703125,
"ok" : 1
}
이 출력은 이 MongoDB 인스턴스가 저장하고 있는 데이터에 대한 개요를 제공합니다. 이 출력에서 반환되는 다음 키들은 특히 유용할 수 있습니다:
objects
키는 데이터베이스에 있는 문서의 총 수를 보여줍니다. 이를 사용하여 데이터베이스의 크기를 평가하고 시간이 지남에 따라 성장을 관찰할 수 있습니다.avgObjectSize
는 이러한 문서의 평균 크기를 보여줍니다. 데이터베이스가 크고 복잡한 문서 또는 작은 문서에서 작동하는지에 대한 통찰력을 제공합니다. 이 값은 항상 바이트로 표시되며 스케일 인수를 지정하더라도 변하지 않습니다.collections
및indexes
키는 현재 데이터베이스에 정의된 컬렉션과 인덱스의 수를 나타냅니다.totalSize
키는 데이터베이스가 디스크에서 차지하는 저장 공간을 나타냅니다.
stats()
메서드가 반환하는 이 정보는 현재 데이터베이스에 저장된 데이터 양에 대한 아이디어를 제공하지만 성능이나 기존 문제에 대한 통찰력을 제공하지는 않습니다. 그 대신, 훨씬 자세한 serverStatus()
메서드가 유용합니다:
이 메서드의 출력은 길며 서버 사용에 대한 많은 정보를 제공합니다:
Output{
"host" : "ubuntu-mongo-rs",
"version" : "4.4.6",
"process" : "mongod",
"pid" : NumberLong(658997),
"uptime" : 976,
. . .
"ok" : 1
}
이 모든 정보가 잠재적으로 유용할 수 있지만, 이 가이드에서는 특히 세 가지 섹션에 중점을 둘 것입니다. 먼저, 이 출력의 connections
섹션을 찾으십시오:
Output . . .
"connections" : {
"current" : 4,
"available" : 51196,
"totalCreated" : 4,
"active" : 2,
"exhaustIsMaster" : 1,
"exhaustHello" : 0,
"awaitingTopologyChanges" : 1
},
. . .
각 데이터베이스 서버는 한 번에 지원할 수 있는 연결 수에 제한이 있습니다. current
키는 현재 데이터베이스에 연결된 클라이언트 수를 보여주고, available
은 데이터베이스가 사용 가능한 잔여 사용되지 않은 연결 수를 나타냅니다. totalCreated
값은 서버 시작부터 사용된 연결 수를 보유합니다.
대부분의 응용 프로그램은 기존 연결을 재사용하도록 설계되어 있으며 자주 여러 연결을 열지 않습니다. 따라서 높은 연결 수는 예상치 못한 경우 클라이언트가 서버에 액세스하는 방법을 잘못 구성한 것의 경고 신호가 될 수 있습니다.
작업 부하의 특성으로 인해 높은 연결 수가 예상되는 경우, 샤드 클러스터에 하나 이상의 샤드를 추가하여 트래픽을 여러 MongoDB 인스턴스에 분산시키는 것을 고려할 수 있습니다.
다음으로, 출력의 globalLock
섹션을 찾으십시오. 이 섹션은 전체 데이터베이스 서버에 걸친 전역 락에 관련이 있습니다:
Output . . .
"globalLock" : {
"totalTime" : NumberLong(975312000),
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 0,
"readers" : 0,
"writers" : 0
}
},
MongoDB는 여러 작업을 수행할 때 데이터 일관성을 보장하기 위해 락을 사용하여 두 개의 쿼리가 동시에 동일한 데이터를 수정하지 않음을 보장합니다. 많이 사용되는 서버에서는 하나 이상의 쿼리가 락이 해제될 때까지 대기하여 실행되기를 기다리는 경우가 발생할 수 있어 락이 병목 현상을 일으킬 가능성이 있습니다.
currentQueue.total
값은 락이 해제되기를 기다리는 쿼리 수를 나타냅니다. 이 값이 높으면 데이터베이스의 성능이 영향을 받고 쿼리가 완료되는 데 시간이 더 오래 걸릴 것입니다.
이는 종종 많은 장기 실행 쿼리가 잠금을 보유하고 있어서 인덱스의 비효율적인 사용이나 잘못 설계된 쿼리 등의 가능성을 나타낼 수 있습니다.
마지막으로, opcounters
섹션을 찾으세요:
Output "opcounters" : {
"insert" : NumberLong(10000007),
"query" : NumberLong(6),
"update" : NumberLong(6),
"delete" : NumberLong(0),
"getmore" : NumberLong(0),
"command" : NumberLong(1298)
},
serverStatus()
출력의 이 섹션은 데이터베이스 서버가 대부분 읽기 또는 쓰기에 사용되는지, 또는 사용이 잘 균형되었는지에 대한 개요를 얻을 수 있습니다. 이 예에서는 테스트 문서를 삽입한 후에 insert
작업의 카운터가 query
작업보다 훨씬 높습니다. 실제 시나리오에서 이러한 값은 다를 것입니다.
쓰기 중심 데이터베이스는 샤딩을 통해 수평으로 확장하는 것이 유리할 수 있습니다. 비슷하게, 읽기 중심 MongoDB 데이터베이스는 보통 복제로 이점을 얻을 수 있습니다.
이러한 통계는 서버의 사용 방식 및 액세스할 때 장기 잠금 대기열과 같은 성능 문제가 있는지를 전반적으로 알려줄 수 있습니다. 그러나 실시간 정보는 제공하지 않습니다. 이에 대해 mongostat
및 mongotop
명령은 유용한 도구입니다.
단계 3 — mongostat
및 mongotop
사용하여 실시간 데이터베이스 통계 얻기
몽고DB의 서버 통계에 액세스하는 데 사용되는 명령어는 서버가 어떻게 사용되었는지에 대한 통찰력을 제공할 수는 있지만, 현재 어떤 컬렉션이 가장 활발하게 사용되고 있는지 또는 어떤 종류의 쿼리가 실행되고 있는지에 대한 실시간 정보를 제공할 수는 없습니다.
몽고DB는 실시간 모니터링을 위한 두 가지 유용한 시스템 도구를 제공하며, 이 도구들은 데이터베이스 활동을 분석하고 제공되는 정보를 지속적으로 새로 고칩니다: mongostat
및 mongotop
. mongostat
은 몽고DB 인스턴스의 현재 상태에 대한 간단한 개요를 제공하며, mongotop
은 인스턴스가 읽기 및 쓰기 작업에 소비하는 시간을 추적합니다. 이 두 도구는 몽고DB 셸이 아닌 명령줄에서 실행됩니다.
mongostat
을 사용하려면 현재 몽고DB 셸 연결을 유지한 채로 다른 터미널 창을 열어 서버 셸에 액세스하십시오. 두 번째 서버 셸에서 mongostat
명령을 실행하십시오:
이전에 언급한대로, mongostat
을 실행하려면 고급 권한이 필요합니다. MongoDB 인스턴스에서 인증을 활성화하고 적절한 역할을 갖춘 사용자를 설정한 경우 해당 사용자로 인증해야 하며, 이를 위해 사용자의 사용자 이름과 인증 데이터베이스(다음 예시에 표시된대로)를 제공한 다음 암호를 입력해야 합니다.
기본 구성에서 mongostat
은 현재 실행 중인 쿼리의 카운터를 1초 간격으로 인쇄합니다:
Outputinsert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.4k 7 Nov 28 15:40:40.621
*0 *0 *0 *0 0 2|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 224b 84.8k 7 Nov 28 15:40:41.619
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.5k 7 Nov 28 15:40:42.621
*0 *0 *0 *0 0 3|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 365b 85.0k 7 Nov 28 15:40:43.619
mongostat
출력에서 특정 쿼리 유형의 값이 0
으로 표시되면 해당 유형의 작업이 데이터베이스에서 실행되지 않음을 나타냅니다. 이 예시 출력은 현재 활성으로 실행되는 쿼리가 없으므로 각 쿼리 유형에 대해 0
을 보여줍니다.
여전히 첫 번째 터미널 창을 열어 MongoDB 셸에 연결해야 합니다. accounts
컬렉션에 몇 가지 테스트 문서를 추가하고 mongostat
이 활동을 감지하는지 확인하십시오:
이것은 Step 1에서 실행한 것과 유사한 for
-루프입니다. 이번에는 루프가 10000개의 항목만 삽입합니다. 계좌 번호는 항상 2000
으로 접두사가 붙고 통화는 항상 USD입니다.
새 문서가 삽입되는 동안 mongostat
출력을 확인하세요:
Output. . .
*0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 112b 42.5k 4 Nov 28 15:50:33.294
*0 *0 *0 *0 0 0|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:34.295
755 *0 *0 *0 0 1|0 0.1% 38.8% 0 1.54G 210M 0|0 1|0 154k 79.4k 4 Nov 28 15:50:35.294
2853 *0 *0 *0 0 0|0 0.4% 39.1% 0 1.54G 211M 0|0 1|0 585k 182k 4 Nov 28 15:50:36.295
2791 *0 *0 *0 0 1|0 0.7% 39.4% 0 1.54G 212M 0|0 1|0 572k 179k 4 Nov 28 15:50:37.293
2849 *0 *0 *0 0 0|0 1.0% 39.7% 0 1.54G 213M 0|0 1|0 584k 182k 4 Nov 28 15:50:38.296
745 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 153k 79.2k 4 Nov 28 15:50:39.294
*0 *0 *0 *0 0 0|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:40.295
*0 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 167b 42.7k 4 Nov 28 15:50:41.293
. . .
쿼리가 실행되는 동안 mongostat
에서 반환된 새 줄은 0
이 아닌 값들을 표시하기 시작합니다. 데이터베이스에 새 데이터를 삽입하는 쿼리 수를 나타내는 insert
열에서 값은 여러 초 동안 더 높았습니다. mongostat
은 1초 간격으로 데이터를 표시하기 때문에, 다른 종류의 데이터베이스 작업에 대한 삽입 비율 뿐만 아니라 데이터베이스가 새 데이터를 삽입하는 속도도 확인할 수 있습니다. 이 예에서는 서버가 초당 거의 3000개의 삽입을 달성했습니다.
mongostat
을 사용하여 데이터베이스 서버의 현재 작업량을 쿼리 유형별로 모니터링할 수 있습니다. MongoDB가 함께 제공하는 두 번째 도구인 mongotop
은 컬렉션별로 데이터베이스 서버 활동을 표시합니다.
mongostat
을 두 번째 터미널 창에서 CTRL + C
를 눌러 실행을 중지합니다. 그런 다음 해당 터미널에서 mongotop
을 실행합니다. 다시 말하지만, 인증이 활성화되어 있는 경우 적절히 권한이 있는 사용자로 인증해야 합니다:
mongotop
은 데이터베이스의 모든 컬렉션 목록을 출력하고, 읽기 및 쓰기에 소요된 시간과 총 시간이 시간 창 내에서 그룹화됩니다. mongostat
과 유사하게, 출력은 매 초마다 새로 고칩니다:
Output2021-11-28T15:54:42.290+0000 connected to: mongodb://localhost/
ns total read write 2021-11-28T15:54:43Z
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
test.accounts 0ms 0ms 0ms
. . .
데이터베이스에 몇 개의 문서를 더 삽입하여 mongotop
에 활동이 등록되는지 확인해 보세요. MongoDB 셸에서 다음과 같은 for
루프를 실행한 후 mongotop
이 실행되고 있는 터미널 창을 관찰하세요:
이번에는 mongotop
통계에서 활동이 보일 것입니다.
Output. . .
ns total read write 2021-11-28T15:57:27Z
test.accounts 127ms 0ms 127ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
ns total read write 2021-11-28T15:57:28Z
test.accounts 130ms 0ms 130ms
admin.$cmd.aggregate 0ms 0ms 0ms
admin.system.roles 0ms 0ms 0ms
admin.system.version 0ms 0ms 0ms
config.system.sessions 0ms 0ms 0ms
config.transactions 0ms 0ms 0ms
local.system.replset 0ms 0ms 0ms
. . .
여기에서 mongotop
은 모든 데이터베이스 활동이 test
데이터베이스의 accounts
컬렉션에서 발생했음을 보여주며, 시간 창에서의 모든 작업이 쓰기 작업임을 나타냅니다. 이 모든 것은 실행한 for
루프 작업과 일치해야 합니다.
mongostat
과 마찬가지로 mongotop
을 실행을 중지하려면 CTRL + C
를 누르면 됩니다.
피크로드 중 관찰할 때 mongotop
을 사용하여 데이터베이스 활동이 다른 컬렉션에 어떻게 퍼지는지 모니터링하여 스키마를 더 잘 이해하고 스케일링을 위한 계획을 세울 수 있습니다. 또한 컬렉션 사용이 더 많이 읽히는지 쓰기 중심인지에 대한 통찰력을 제공합니다.
단계 4 — MongoDB의 데이터베이스 프로파일러를 사용하여 느린 쿼리 식별
데이터베이스 성능 병목 현상은 여러 원인에서 발생할 수 있습니다. 데이터베이스의 확장(수평 또는 수직)이 종종 성능 병목의 해결책이지만, 그 원인은 실제로 데이터베이스의 한계가 아닐 수 있으며 스키마나 쿼리 설계 문제일 수도 있습니다.
쿼리가 너무 오래 실행되면 인덱스의 비효율적인 사용이나 쿼리 자체의 오류일 수 있습니다. 오랜 시간 동안 실행되는 쿼리는 주로 테스트 데이터 세트가 너무 작거나 조건이 프로덕션과 다르기 때문에 응용 프로그램 개발 중 감지되지 않는 경우가 많습니다.
당신은 수동으로 테스트 쿼리를 실행하고 어떤 것이 성능이 낮은지 확인하여 가능한 원인을 찾을 수 있습니다. 그러나 이는 매우 지루할 수 있습니다. 다행히도 MongoDB의 데이터베이스 프로파일러 도구가 이를 자동으로 수행할 수 있습니다.
MongoDB의 데이터베이스 프로파일러는 특정 조건을 충족할 때 쿼리와 그 실행에 대한 통계를 기록할 수 있습니다. 이러한 조건 중 가장 중요한 것은 쿼리의 실행 시간입니다. 쿼리가 지정된 시간보다 더 오래 걸린다면 프로파일러는 해당 쿼리를 문제가 있는 것으로 자동으로 플래그 처리합니다. 프로파일러를 사용하여 성능이 낮은 쿼리를 식별한 다음 해당 문제를 해결하는 데 집중할 수 있습니다.
프로파일러를 사용하기 전에 다음 쿼리를 실행하세요. 이 쿼리는 삽입한 계정 중 하나를 검색할 것입니다. 하지만 처음에 보이는 것만큼 간단하지는 않습니다.
다음 명령은 정확한 계정을 검색합니다:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
쿼리가 즉시 실행되지 않고 MongoDB가 계정을 찾는 데 몇 초 정도 걸렸음을 알아챘을 것입니다. 실제 응용 프로그램에서는 성능이 낮은 많은 종류의 쿼리가 있을 수 있으며 실제로 성능 저하를 인식하지 못할 수 있습니다.
MongoDB를 구성하여 예상보다 오래 걸리는 쿼리를 식별할 수 있도록 설정할 수 있습니다. 이를 위해 먼저 다음 명령을 실행하여 프로파일러를 활성화하세요:
setProfilingLevel()
메서드에는 두 개의 인수가 필요합니다. 첫 번째는 프로파일링 레벨이며 0
, 1
, 또는 2
중 하나일 수 있습니다:
0
은 프로파일러를 비활성화합니다1
은 조건을 충족하는 느린 쿼리에서만 프로파일러를 활성화합니다.2
모든 쿼리에 대한 프로파일러를 활성화합니다.
이 예에서 프로파일러는 두 번째 인수 { slowms: 100 }
에 정의된대로 100밀리초 이상 실행되는 쿼리를 분석합니다.
참고: 프로파일러를 사용하면 MongoDB가 쿼리를 실행하는 것 외에도 쿼리를 분석해야 하므로 성능이 저하됩니다. 성능 병목 현상을 모니터링할 때만 적게 사용해야 합니다.
프로파일러가 기록할 쿼리의 하위 집합을 더 세밀하게 조정하려면 특정 비율의 쿼리만 프로파일링하도록 구성하거나 쿼리 유형별로 필터링하도록 구성할 수 있습니다. 프로파일러에 대한 더 많은 제어를 얻는 방법에 대해 자세히 알아보려면 관련 공식 문서를 참조하십시오.
이 방법은 성공 메시지를 반환합니다:
Output{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
이제부터 데이터베이스 프로파일링이 활성화되며 MongoDB가 실행하는 모든 쿼리를 주의 깊게 모니터링하여 100밀리초 이상 소요되는 쿼리를 찾을 것입니다.
다양한 쿼리를 실행하여 이를 확인해 보십시오. 먼저 count
명령을 사용하여 accounts
컬렉션에 있는 문서 수를 찾습니다:
이 명령은 컬렉션에 있는 문서 수를 빠르게 반환합니다:
Output1020000
그런 다음 컬렉션에 나타나는 첫 번째 세 개의 은행 계좌를 찾아보십시오:
데이터베이스는 결과를 빠르게 반환할 것입니다:
Output{ "_id" : ObjectId("61ef40640f2ba52efc56ee17"), "number" : "1000-1", "currency" : "EUR", "balance" : 25393.132960293842 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee18"), "number" : "1000-2", "currency" : "EUR", "balance" : 63629.42056192393 }
{ "_id" : ObjectId("61ef40640f2ba52efc56ee19"), "number" : "1000-3", "currency" : "EUR", "balance" : 75602.12331602155 }
마지막으로 특정 은행 계좌에 대한 검색 쿼리를 다시 실행합니다:
이 쿼리는 결과를 반환하지만, 이전 작업보다 시간이 조금 더 걸릴 것입니다:
Output{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }
프로파일러는 자체 출력을 생성하지 않습니다. 그러나 쿼리가 시각적으로 더 느렸습니다. 대신, 느린 작업에 대한 세부 정보는 데이터베이스 내의 특수 컬렉션인 system.profile
에 등록됩니다. 이 컬렉션은 크기가 1MB를 초과하지 않는 캡된 컬렉션입니다. 즉, 항상 최신 느린 쿼리 목록만 포함하게 됩니다.
프로파일러에서 식별된 쿼리에 대한 정보를 검색하려면 다음과 같은 방식으로 system.profile
컬렉션을 쿼리해야 합니다:
이 쿼리는 일반적으로 find()
메서드를 사용합니다. 또한 최신 쿼리를 먼저 정렬하기 위해 인수로 { "ts" : -1 }
을 포함하는 sort
절도 포함합니다. 마지막으로 더 읽기 쉬운 형식으로 출력을 표시하기 위해 끝에 pretty()
메서드가 포함됩니다.
각 느린 쿼리는 일반 문서로 표시되며, system.profile
은 일반 컬렉션과 같습니다. 이는 결과를 필터링하고 정렬하며 심지어 집계 파이프라인에서 사용하여 프로파일러에 의해 식별된 쿼리 목록을 좀 더 좁히거나 분석할 수 있다는 것을 의미합니다.
결과가 단일 문서만으로 구성되는 것에 유의하세요. 다른 두 쿼리는 프로파일러를 트리거하지 않을 만큼 충분히 빨리 실행되었습니다:
Output{
"op" : "query",
"ns" : "test.accounts",
"command" : {
"find" : "accounts",
"filter" : {
"number" : "1000-20"
},
. . .
},
"nreturned" : 1,
"keysExamined" : 0,
"docsExamined" : 1030000,
. . .
"millis" : 434,
"planSummary" : "COLLSCAN",
. . .
}
이 출력은 느린 쿼리의 실행에 대한 여러 세부 정보를 제공합니다:
op
키는 이 정보가 어떤 종류의 작업을 나타내는지를 보여줍니다. 여기서는find()
를 사용하여 데이터베이스에서 데이터를 검색하는 작업을 나타내므로query
입니다.ns
키는 작업에 참여한 데이터베이스와 컬렉션을 나타냅니다. 출력에서 볼 수 있듯이, 이 작업은test
데이터베이스의accounts
컬렉션을 조회했습니다.command
키는 쿼리 자체에 대한 추가 정보를 제공합니다. 이 경우filter
하위 키에 전체 필터 문서가 포함되어 있습니다.op
및command
필드에서 가져온 정보를 사용하여 해당 쿼리를 재구성할 수 있습니다.millis
필드에서는 쿼리를 완료하는 데 걸린 정확한 시간을 찾을 수 있습니다. 이 예에서는 거의 반 초가 걸렸습니다.docsExamined
필드는 결과 집합을 반환하기 위해 스캔된 문서 수를 제공합니다.nreturned
는 쿼리가 반환한 문서 수를 나타냅니다. 이 예에서는 백만 개가 넘는 문서 중 하나만 반환되었습니다.planSummary
는 MongoDB가 쿼리를 실행하는 데 사용한 방법을 보여줍니다.COLLSCAN
은 전체 컬렉션 스캔에 해당하며, 즉 일치하는 은행 계정을 찾기 위해 컬렉션의 모든 문서를 하나씩 찾아 보았음을 의미합니다.
이 모든 정보는 몽고디비가 이 쿼리를 빠르게 실행할 수 있도록 돕는 인덱스가 필요하다는 점을 강조합니다. 데이터베이스는 단일 문서를 찾기 위해 전체 컬렉션을 검색해야 했으며, 검토된 문서 수와 반환된 문서 수 사이의 큰 차이 및 실행 전략에서 나타납니다.
이 구체적인 예에서는 number
필드를 기반으로 데이터를 필터링하는 쿼리를 지원하는 인덱스를 생성하면 이러한 종류의 쿼리의 성능을 즉시 향상시킬 수 있습니다. 실제 시나리오에서 느린 쿼리에 대한 해결책은 다를 수 있으며 문제를 일으키는 정확한 쿼리에 따라 달라집니다.
프로파일링 세션을 마치려면 프로파일러를 비활성화하여 프로파일링 수준을 제로로 설정할 수 있습니다:
작업은 확인 메시지와 함께 성공합니다:
Output{ "was" : 1, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }
이제 데이터베이스는 프로파일링이 백그라운드에서 진행되지 않는 정상 작동 상태로 돌아갑니다.
데이터베이스 성능에 부정적인 영향을 미칠 수 있는 느린 쿼리가 있다고 의심될 때마다 데이터베이스 프로파일러를 사용하여 이를 찾고 그 구조와 실행 방식을 더 잘 이해할 수 있습니다. 이 정보를 바탕으로 조정하여 성능을 향상시킬 수 있습니다.
결론
이 가이드를 따라서 MongoDB의 서버 통계를 찾고 mongotop
, mongostat
와 같은 진단 도구를 사용하는 방법을 배웠습니다. 또한 MongoDB의 데이터베이스 프로파일러 메커니즘을 사용할 수 있습니다. 이를 사용하여 데이터베이스의 작업 부하를 더 잘 이해하고, 가장 활발한 컬렉션을 결정하고, 서버가 주로 쓰기 작업 또는 읽기 작업을 수행하는지 확인할 수 있습니다. 또한 MongoDB의 성능에 영향을 미치는 느린 쿼리를 식별하여 더 효율적인 쿼리로 대체할 수 있습니다.
이것들은 MongoDB 설치의 건강과 성능을 모니터링하고 그에 대응하는 것에 사용할 수 있는 도구와 기술의 선택일 뿐입니다. 이러한 도구 각각은 더 정밀한 서버 성능 통찰력을 제공하기 위해 더 구성 및 사용자화될 수 있습니다. 우리는 공식 MongoDB 문서를 공부하여 서버 성능을 모니터링하고 그에 대응하는 데 사용할 수 있는 기술에 대해 더 많이 배우실 것을 권장합니다.
Source:
https://www.digitalocean.com/community/tutorials/how-to-monitor-mongodb-s-performance