티스토리 뷰

MongoDB aggregate 를 통해 데이터를 집계하다가 아래와 같은 오류를 접하게 되었습니다.

{ errmsg: \"exception: aggregation result exceeds maximum document size (16MB)\", code: 16389, ok: 0.0 }"}

원인은 MongoDB의 경우 Document기반의 NoSQL DB로 Document size가 16MB로 고정되어 있습니다.(기본적으로는 수정 불가, 단, GridFS 적용시 가능)
aggregate 수행결과 또한 Document이기 때문에, 이 결과도 16MB를 초과할 수 없습니다. 위 오류는 결과가 16MB를 초과하여 발생한 것 입니다.

이를 해결하기 위해서 MongoDB 공식 사이트를 검색해보니,
Aggregate 명령어 수행시 allowDiskUse 옵션이 생겼습니다.(2.6.X 버전 부터)

MongoDB 업그레이드 작업을 진행 한 후, allowDiskUse 옵션을 테스트를 해 보았습니다.

먼저 테스트용 Dummy data(100만건)를 입력하고, 집계를 수행하였습니다.

1. 테스트 데이터 입력

for(var i=0; i < 1000000 ; i++) {
db.tempCol.save({
     JSON 타입의 데이터
});
}

2. Document Size 16MB 초과 오류 재현 

100만건을 적용 후 집계를 해 보니. 아래와 같은 오류가 발생합니다.

org.springframework.dao.InvalidDataAccessApiUsageException: Command execution failed:  Error [exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.], Command = { "aggregate" : "tempCol" , "pipeline" : ...}; nested exception is com.mongodb.CommandResult$CommandFailure: command failed [command failed [aggregate] { "serverUsed" : "127.0.0.1:27017" , "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in." , "code" : 16945 , "ok" : 0.0}


3. allowDiskUse 옵션 적용

allowDiskUse 옵션을 추가하여 테스트 진행...

mongos> db.tempCol.aggregate(...)
assert: command failed: {
        "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
        "code" : 16945,
        "ok" : 0
} : aggregate failed
Error: command failed: {
        "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
        "code" : 16945,
        "ok" : 0
} : aggregate failed
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandWorked (src/mongo/shell/assert.js:244:5)
    at DBCollection.aggregate (src/mongo/shell/collection.js:1149:12)
    at (shell):1:12
2015-01-29T11:42:31.592+0900 Error: command failed: {
        "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.",
        "code" : 16945,
        "ok" : 0
} : aggregate failed at src/mongo/shell/assert.js:13
mongos> db.tempCol.aggregate(..., {allowDiskUse: true})

allowDiskUse:true 옵션을 적용하니, 집계는 정상적으로 집계가 되어 결과가 출력됨을 확인할 수 있습니다.


spring-data API를 통해 적용하기 위해서는 GA버전인 1.6.2.RELEASE 버전을 적용하면 옵션 적용이 가능합니다.
아래 처럼 allowDiskUse 옵션을 적용할 수 있습니다.

aggregation.withOptions(aggregation.newAggregationOptions().allowDiskUse(true).build());



아래와 같은 오류를 접하는 경우가 있을 수 있습니다.


Could not instantiate bean class [org.springframework.data.mongodb.core.MongoTemplate]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/objenesis/ObjenesisStd

ObjenesisStd 클래스는 spring-core 4.0.X 버전에 존재하는 클래스로 spring 버전이 맞지 않아서 발생하는 이슈입니다.


https://github.com/spring-projects/spring-data-commons/wiki/Release-Train-Evans

구글링을 해보니 위 URL에서 아래와 같이 언급을 하고 있습니다.


Core themes

  • Upgrade to Spring 4.0 as dependency baseline (previously Spring 3.2).


spring-data-common 자체의 spring baseline 버전이 4.0.X 로 올라갔습니다.

따라서 spring-core 버전을 4.0.X.RELEASE 으로 맞춰주면 정상적으로 수행이 됩니다.



'BigData > MongoDB' 카테고리의 다른 글

MongoDB Having 쿼리 적용하기  (0) 2015.03.05
MongoDB paddingFactor 옵션  (0) 2015.03.05
MongoDB 인덱스 관리  (0) 2015.03.05
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함