DB/MongoDB

mongodb - BSON 사이즈 제한

linuxism 2013. 6. 18. 10:37

in mongodb v2.4 

BSON Document Size

The maximum BSON document size is 16 megabytes.

The maximum document size helps ensure that a single document cannot use excessive amount of RAM or, during transmission, excessive amount of bandwidth. To store documents larger than the maximum size, MongoDB provides the GridFS API. Seemongofiles and the documentation for your driver for more information about GridFS.











MongoDB 도큐먼트의 BSON 크기 확인하기

2013/05/16 23:54 by Outsider in Database/NoSQL

간단한 개인 프로젝트를 하면서 MongoDB를 사용했는데 데이터를 조회하던 중 다음과 같은 connection closed due to parseError 오류가 발생한다.

1
2
3
4
5
6
7
8
Thu May 16 2013 19:53:18 GMT+0900 (KST) - error: Error: connection closed due to parseError
  at [object Object].Server.connect (/example/node_modules/mongodb/lib/mongodb/connection/server.js:645:45)
  at [object Object].EventEmitter.emit (events.js:126:20)
  at [object Object]._connect (/example/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:181:15)
  at [object Object].EventEmitter.emit (events.js:99:17)
  at Socket.exports.Connection.createDataHandler (/example/node_modules/mongodb/lib/mongodb/connection/connection.js:357:20)
  at Socket.EventEmitter.emit (events.js:96:17)
  at TCP.onread (net.js:397:14)


오류 메시지만 보면 파싱오류가 발생한 것데 왜 파싱오류가 발생했는지는 추측하기가 쉽지 않다. 이건 소스를 보면 확인할 수 있는데 해당 부분인 connection.js의 소스는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) {
  var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
    sizeOfMessage: sizeOfMessage,
    bytesRead: self.bytesRead,
    stubBuffer: self.stubBuffer}};
  if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
  // We got a parse Error fire it off then keep going
  self.emit("parseError", errorObject, self);
  return;
}


메시지가 없거나 최대 BSON 사이즈보다 작은 경우에 오류가 발생한건데 이 경우에는 BSON 사이즈가 최대 크기를 넘어선 경우이다. MongoDB는 BSON(Binary JSON)이라는 데이터형식을 사용하는데 현재 MongoDB의 최대 사이즈는 16MB이다.  과거에는 4MB였는데 1.7.4버전부터인가 16MB로 올라갔고 차후에는 32MB로 올릴 예정인 것으로 알고 있다. 이 값은 참고로 수정할 수 없는 값이므로 MongoDB의 제약사항 중 하나고 MongoDB에서 하나의 도규먼트(RDB라면 하나의 Row)의 최대 크기가 16MB라는 의미이다. 임시적인 프로젝트라서 귀차니즘에 하나의 컬렉션에 데이터를 임베딩해서 넣으면서 16MB가 넘을 일은 없을꺼라고 생각했지만 아마도 넘은듯 하다.(사실 정말 16MB가 넘은지 좀 의심스럽기는 하지만 데이터가 많아서 정확히 확인하지는 못했다.)


BSON 사이즈 확인
MongoDB 쉘에서는 BSON의 크기를 확인할 수 있는 Object.bsonsize()라는 함수를 제공하고 있고 있다.

1
2
3
4
> Object.bsonsize({})
5
> Object.bsonsize({name:'outsider', url:'http://blog.outsider.ne.kr'})
60


bsonsize()에 객체를 넘겨보면 BSON의 크기를 계산해 볼 수 있다. 위와 같이 객체를 직접 넣는대신 query를 넣어서 확인할 수도 있다.

1
2
> Object.bsonsize(db.test.findOne())
988923


위와 같이 findOne() 쿼리를 사용해서 디비에 담긴 특정 도큐먼트의 크기를 확인해 볼 수 있는데 여기서 주의할 점은 findOne()만 되고 find()로는 제대로 확인이 되지 않는다. 여기서 나오는 크기는 바이트크기이므로 988923은 988KB정도가 되는 것이다. BSON 사이즈제한이 의심되는 도큐먼트가 있다면 이 함수를 사용해서 확인해 볼 수 있다.



출처 - http://blog.outsider.ne.kr/941