2010-04-08 2 views
27

MongoDB의 성능에 대해 많은 좋은 점을 알게 된 후 우리는 Mongodb에게 우리가 가진 문제를 해결하기 위해 노력하기로 결정했습니다. 필자는 여러 개의 mysql 데이터베이스에있는 모든 레코드를 mongodb의 단일 컬렉션으로 이동시키는 것으로 시작했습니다. 그 결과 2900 만건의 문서 (각 필드에는 적어도 20 개의 필드가 있음)의 콜렉션이 생성되었으며 HD에서는 약 100GB의 공간이 필요합니다. 모든 문서가 동일한 구조를 가지므로 모든 문서에서 결과를 쿼리하고 집계하기를 원하기 때문에 모든 것을 한 모음에 모으기로했습니다.집계 쿼리에 대한 MongoDB의 성능

내 쿼리와 일치하는 인덱스를 만들었습니다. 그렇지 않으면 간단한 count()에도 몇 년이 걸릴 수도 있습니다. 그러나 distinct() 및 group()과 같은 쿼리는 여전히 너무 오래 걸립니다.

예 : 나는 mongod 로그를 살펴했고 (위의 쿼리를 실행하는 동안)가 이와 같은 라인을 많이 가지고

// creation of a compound index  
db.collection.ensureIndex({'metadata.system':1, 'metadata.company':1}) 

// query to get all the combinations companies and systems 
db.collection.group({key: { 'metadata.system':true, 'metadata.company':true }, reduce: function(obj,prev) {}, initial: {} }); 

:

Thu Apr 8 14:40:05 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1048890 nreturned:417 154ms 
Thu Apr 8 14:40:08 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1050205 nreturned:414 430ms 
Thu Apr 8 14:40:18 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1049748 nreturned:201 130ms 
Thu Apr 8 14:40:27 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1051925 nreturned:221 118ms 
Thu Apr 8 14:40:30 getmore database.collection cid:973023491046432059 ntoreturn:0 query: {} bytes:1053096 nreturned:250 164ms 
... 
Thu Apr 8 15:04:18 query database.$cmd ntoreturn:1 command reslen:4130 1475894ms 

이 쿼리는 1475894ms 발생한 나는 예상했던 것보다 길다. (결과 목록은 약 60 개의 항목을 가지고있다.) 우선, 내 컬렉션에 많은 수의 문서가 있으면이 예상입니까? 집계 쿼리는 일반적으로 mongodb에서 너무 느릴 것으로 예상됩니까? 성능을 어떻게 향상시킬 수 있습니까?

저는 이중 코어와 10GB 메모리가있는 단일 시스템에서 mongod를 실행하고 있습니다.

감사합니다.

+1

글쎄,이 질문은 너무 오래되었고 여전히 MongoDB 집계 프레임 워크를 검색 할 때 엔진을 검색하게됩니다. Mario 당신은 당신의 MongoDB 버전을 언급하지 않았고 2.4에서 AF를 많이 향상 시켰고, 나는 진절머리 나는 m1에서 그것을하고 있습니다. 69m를 가진 3.7G 메모리를 가진 EC2는 이전보다 훨씬 빠릅니다. 새 버전을 사용해 보셨습니까? 아니면 다른 방법을 사용하셨습니까? 물론 AF 대 MapReduce에 대한 벤치 마크가 있지만 10Gen의 최신 벤치 마크를 확인하십시오. http://blog.mongodb.org/post/62900213496/qaing-new-code-with-mms-map-reduce-vs -aggregation tnx – Maziyar

+0

귀하의 의견을 보내 주셔서 감사합니다. 이것은 2010 년으로 거슬러 올라갔습니다. MongoDB 1.4.0과 같은 것을 사용하고 있다고 생각합니다. 그것은 잠시였습니다. 이후 많은 것들이 mongodb에서 변경되었지만, 그 해 이후로 그 프로젝트에서 일하지는 못했습니다 :) –

+0

Thanks Mario for the reply. 방금 MongoDB (약 1 년)를 사용하기 시작했고 프로젝트에 어떤 일이 일어 났는지 궁금합니다. 어쨌든 행운을 빌어 요. – Maziyar

답변

22

여러 컴퓨터에 분산되어있는 공유 데이터베이스에서 MapReduce를 사용하여 집계 쿼리의 성능을 향상시키는 것이 좋습니다.

Mongo의 Mapreduce의 성능을 Oracle에서 동일한 시스템의 그룹 별 선택문과 비교했습니다. 나는 몽고가 약 25 배 더 느리다는 것을 알았다. 즉, Oracle이 단일 시스템에서 제공하는 것과 동일한 성능을 얻으려면 적어도 25 대의 시스템에서 데이터를 분할해야합니다. 필자는 약 1400 만 개의 문서/행을 가진 콜렉션/테이블을 사용했습니다.

mongoexport.exe를 통해 mongo에서 데이터를 내보내고 Oracle에서 외부 테이블로 내 보낸 데이터를 사용하고 Oracle에서 그룹화를 수행하는 것이 Mongo 자신의 MapReduce를 사용하는 것보다 훨씬 빠릅니다.

+0

MongoDB의 버전을 아는 것은 정말로 도움이됩니다. – nilskp

+0

버전 1.4.0과 비슷하다고 생각합니다. –

4

집계 (map reduce 또는 기타)는 mongo가 데이터베이스 엔진이 아닌 javascript VM에 의해 수행되기 때문에 매우 느립니다. 이것은 시계열 데이터에 대한이 (매우 좋은, imo) db의 한계가 계속됩니다.

+1

v2.2에서 집계 파이프 라인은 [기본 작업] (http://docs.mongodb.org/manual/core/aggregation-introduction/#aggregation-pipelines)을 사용합니다. – Tamlyn

8

몇 가지.

1) 귀하의 그룹 쿼리는 개의 데이터을 처리 중입니다. 결과 세트가 작을 때, 작은 결과를 생성하기 위해 콜렉션의 모든 데이터에 대해 테이블 ​​스케일을 수행하는 것처럼 보입니다. 이것은 아마 느린 속도의 근본 원인 일 것입니다. 이 속도를 높이려면 쿼리가 실행되는 동안 iostat을 통해 서버의 디스크 성능을 보면서 병목 현상이 발생할 가능성이 있습니다.

2) 다른 답변에서 지적한 것처럼 그룹 명령은 성능을 제한 할 JavaScript 인터프리터를 사용합니다. 2.1에서 베타 버전으로 출시 된 새로운 집계 프레임 워크를 사용해 볼 수도 있습니다 (참고 : 2012 년 2 월 24 일 현재 불안정한 출시입니다). 좋은 소개는 http://blog.mongodb.org/post/16015854270/operations-in-the-new-aggregation-framework을 참조하십시오.이것은 (1)에서 데이터 볼륨 문제를 극복하지는 않지만 C++로 구현되며 자바 스크립트 시간이 병목 현상이라면 훨씬 빨라야합니다.

3) 다른 방법은 incremental map-reduce를 사용하여 그룹화 된 결과로 두 번째 모음을 생성하는 것입니다. 아이디어는 map-reduce 작업을 실행하여 결과를 한 번 수집 한 다음 새 데이터를 기존 컬렉션으로 다시 줄이는 다른 map-reduce 작업을 주기적으로 실행하는 것입니다. 그런 다음 매회 그룹 명령을 실행하는 대신 앱에서이 두 번째 수집을 쿼리 할 수 ​​있습니다.