- BigData/[01] MongoDB

Shorten field name

n3015m 2013. 7. 4. 09:22
NoSQL을 처음 사용하다 보니 이것 저것 익숙하지 않는게 너무 많다. 아래는 MongoDB 한국공식 카페에 문의해서 얻은 정보이다.

그동안 RDBMS에만 너무 익숙해서 그런지 Field도 Document에 저장된다고 하니 전혀 생각하지 못했던 문제인데 잼있네요. Field가 미치는 용량에 대해서도 고민을 해보게 되네요.

MongoDB를 이용해서 각종 보안장비의 로그를 분석이 가능할지 테스트를 하고 있는데,

import에서 문제가 있어 질문을 올립니다.

방화벽 등의 접속 이력을 CSV로 변환하여 mongoimport를 이용하여 DB에 적재를 하였습니다.
한달 동안 발생한 로그의 Text변환된 용량은 100G 정도인데, 10G정도 적재하고 용량을 확인해 보니,

벌써 100G가 넘어가고 있더라구요. (Show dbs; 에서 용량을 확인했습니다.)

분석해야할 로그는 한달에 1Terabyte가 넘어가는데, 10배정도 증가한다면 10Terabyte의 적재용량이
필요하게 되니.. 혼란스럽네요.

일단 테스트 환경이라 Sharding 4대의 PC에 1개씩 올려서 구성했습니다.
O/S는 win7 64bit입니다.

PC1 : Shard1, config server, mongos
PC2 : Shard2 
PC3 : Shard3
PC4 : Shard4

평문 로그를 넣을때 10배씩 증가하면 스토리지 문제가 발생하는데 이게 정상인지..
설정을 잘못한건지 모르겠네요.
 

깨을러
해당 DB에 대해서 db.getSiblingDB(dbname).stats() 한번 보여주시겠어요? 
참고로, MongoDB에서는 key name도 document에 포함되기 때문에 key 를 너무 길게 주지 않는게 좋습니다. 



회신

IP만 X.X.X로 가린 내역입니다. 댓글에 한번에 안들어가네요. ㅡㅡ.

mongos> db.getSiblingDB('internetfwlog').stats();
{
        "raw" : {
                "x.x.x.87:10001" : {
                        "db" : "internetfwlog",
                        "collections" : 3,
                        "objects" : 84542949,
                        "avgObjSize" : 297.570877874156,
                        "dataSize" : 25157519552,
                        "storageSize" : 28623273824,
                        "numExtents" : 36,
                        "indexes" : 1,
                        "indexSize" : 2714898032,
                        "fileSize" : 36423335936,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "ok" : 1
                }, 
                "x.x.x.88:10002" : {
                        "db" : "internetfwlog",
                        "collections" : 3,
                        "objects" : 79687132,
                        "avgObjSize" : 298.2095203024749,
                        "dataSize" : 23763461408,
                        "storageSize" : 26476846960,
                        "numExtents" : 35,
                        "indexes" : 1,
                        "indexSize" : 2557387392,
                        "fileSize" : 34276900864,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "ok" : 1
                },
                "x.x.x.89:10003" : {
                        "db" : "internetfwlog",
                        "collections" : 3,
                        "objects" : 78990871,
                        "avgObjSize" : 297.8793958101817,
                        "dataSize" : 23529752928,
                        "storageSize" : 26476846960,
                        "numExtents" : 35,
                        "indexes" : 1,
                        "indexSize" : 2570935024,
                        "fileSize" : 34276900864,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "ok" : 1
                },  
               "x.x.x.90:10004" : {
                        "db" : "internetfwlog",
                        "collections" : 3,
                        "objects" : 82908992,
                        "avgObjSize" : 298.92318903117285,
                        "dataSize" : 24783420288,
                        "storageSize" : 28623273824,
                        "numExtents" : 36,
                        "indexes" : 1,
                        "indexSize" : 2661271648,
                        "fileSize" : 36423335936,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "ok" : 1
                }
        },
        "objects" : 326129944,
        "avgObjSize" : 297.49856238898445,
        "dataSize" : 97234154176,
        "storageSize" : 110200241568,
        "numExtents" : 142,
        "indexes" : 4,
        "indexSize" : 10504492096,
        "fileSize" : 141400473600,
        "ok" : 1
}



깨을러   
수치로만 봤을때는 실제로 3억 2천만건에 데이터 크기가 97G, 색인이 10G 정도 되네요.
collection에 findOne() 하나만 보여주실 수 있나요?
혹시 import 하실때 --drop 안하셔서 중복으로 여러번 쌓였다거나
위에 제가 말씀드린 것처럼 key가 너무 길어서 실제 데이터의 몇배가 되는거 아닌지 확인해 보셔야 할 것 같습니다.


회신
mongos> db.denylog.findOne();
{
        "_id" : ObjectId("51d23bb45df660c240d45ece"),
        "start_time" : "2013-04-30 22:15:47",
        "end_time" : "2013-04-30 22:15:47",
        "rule_id" : 329,
        "src_ip" : "xxx.xx.xx.107",
        "src_port" : 1739,
        "dest_ip" : "xxx.xxx.xxx.199",
        "dest_port" : 80,
        "protocol" : "TCP",
        "zone" : "EXT",
        "send_packet" : 1,
        "send_byte" : 66,
        "tcp_flag" : "F",
        "etc" : ""
}
mongos>

방화벽 로그를 CSV 변환 하면 일별로 1.8G입니다.
7~8일정도 import를 순차적으로 했습니다. Collection을 새로 생성하고 한거라서.. 중복 될만한 입력은 없을거 같습니다. 

실제로 입력된 데이터의 건수는 3억건의 맞습니다.

mongos> db.denylog.count();
325990551 

깨을러
MongoDB에서는 일반 RDB처럼 scheme이 있는게 아니라서 모든 document마다 column(field) name까지 disk를 잡아먹습니다.

위에 보여주신 findOne() 결과 보니까 대략 300bytes 정도 되는데요.
(정확히 bson으로 차지하고 있는 크기는 Object.bsonsize(db.denylog.findOne()) 로 확인해 보시면 됩니다.)
그중에서 태그만 대충 뽑아보니 160여 bytes네요.
(게시판이 긁지 못하게 설정되어 있어서 일일이 쳤네요.. ls -al)

위의 정보(avgObjSize와 실제 findOne()결과)로 평균 300bytes 잡고,
325,990,551 * 300 = 97,797,165,300 잡히네요.
_id가 32bytes던가 24bytes던가 잡히니까 _id_1 색인이 대략 10G 정도 되고요.

수치와 계산상으로는 맞는것 같습니다.

따라서 huge volume collection 설계하실 때는 가능한한 shorten field name을 쓰시는게 좋습니다.
st, et, rid, sip, sp, dip, dp 등등으로요. 대소문자 구분하니까 더 짧게 한 글자로 쓰셔도 될 것 같습니다.