'카우치디비'에 해당되는 글 1건

  1. 2010.01.01 CouchDB
카테고리 없음2010. 1. 1. 17:55
몽고디비(MongoDB)로 마음이 쏠렸었는데, 너무 겉핥기로만 지나쳤다는 미안함이 있어, CouchDB도 테스트 해봤습니다.

드라이버
--------
그루비쪽에서 보면, 몽고나 카우치나 거기서 거기더군요. 테스트에는 jcouchdb를 드라이버로 사용했습니다. 그루비에 내장된 REST 로 시도해보았는데, jcouchdb에 비해 너무 느리더군요. groovyx.net.http.RESTClient 는 구현이 제대로 안된 것 같습니다.

jcouchdb는 자바용 드라이버이지만, 그루비에서도 이런 식으로 사용할 수 있었습니다.
[code groovy]
def db = new org.jcouchdb.db.Database("xxx.xxx.xxx.xx", 5987, "dbname");
def doc = [name:'박제권' ....]
db.createDocument(doc);
[/code]

테스트
------
테스트는 게시문 20만건, 사용자디비 6만건, 댓글 100만건 정도를 INSERT 해보았습니다.
서버는 몇군데서 돌아가면서 해봤는데, 체감결과는 비슷했습니다. 메모리가 많으면 더 잘도는 것 같긴합니다만, 워낙 느려서...

다음은 기록해둘만한 사항들입니다.



버전
----
데비안에서 couchdb의 안정버전은 아직도 0.8 입니다.  문제는 0.10 버전이 조금 빨라지기도 했고, VIEW 쪽 접근 URL도 다르다는  점입니다. (view 의 url 이 달라지니까... 나중에 0.10 이 안정버전이 되면 어플리케이션 코드를 손대야 하는...)

데비안4 나 5 모두 couchdb 0.10 을 설치하려면 testing으로 올려야합니다.
ubuntu 9.10 / fedora 11 에서는 문제없이 0.10을 설치해줬습니다.

컴파일하는 것도 한가지 방법인데... erlang, openssl 까지 의존 목록에 들어있더군요. 따라서....귀찮습니다.

(저는 안정버전에 집착하는 편인데, 좀 문제네요.)


벌크 인서트
----------
처음에 며칠동안은 테스트 데이터 한 건식 루프를 돌면서 insert 해보았는데요. 최장 8시간까지 걸리더군요. 댓글의 경우는 그나마 데이터가 적어서인지 빨리되는데, 게시물같은 경우는 초당 10개가 안되기도 합니다.

상황에 따라 정확한 시간은 달라질 수 있습니다만, 동일 환경에서 mongodb에서는 13분 걸리더군요. 그냥 두 DB가 성격이 다른 거니까, 속도를 비교하는 것은 무리인 듯 합니다.

더 조사해보니, 벌크인서트(bulk insert)라는 것이 있어서 이걸 써봤습니다.

[code groovy]
def array = [];
rawdata.each {r->
   def doc = [name:r->name, ....]
   array.add(doc);
   if((i%500) != 0) {
     db.buldCreateDocuments(array);
     array = [];
   }
}
[/code]
와 같은 방식으로 사용할 수 있습니다.

이 API를 이용하니까, 전체 데이터 로딩속도가 엄청나게 빨라졌습니다. (30분정도)


뷰 == 미리 정의해야 하나
-----------------------
다음 문제는 뷰(View)였습니다. 카우치에서 가장 독특해보이는 녀석이 자바스크립트로 만들어진 뷰인데요. 여기에 map/reduce라는 개념까지 들어가면 공부하기 힘들어보입니다.

저는 테스트 데이터를 입력하면서 회원/게시물/댓글 에 대해서 doc_type 이라는 필드를 만들고, 각각 member/article/comment 라는 값을 주었습니다.

[code groovy]
articles_data.each { r->
  def doc = [doc_type :'article', name:r->name, ....]
  db.createDocument(doc);
}
comments_data.each { r->
  def doc = [doc_type :'comment', name:r->name, ....]
  db.createDocument(doc);
}
[/code]
그리고, 각 타입의 문서가 몇개나 있는지 세어보는 view를 만들었습니다. 앞의 함수가 map 이고, 뒤의 함수가 reduce 입니다.

[code groovy]
function(doc) {
  emit(doc.doc_type, 1);
}

function(key, values) {
    return sum(values);
}
[/code]
아래는 결과입니다.

[code groovy]
"article"    : 245328
"member"  : 68076
"comments":1157777
[/code]

이 녀석이 카우치 디비에서 가장 감동적인 장면인 것 같아서 캡쳐해봤습니다. (테스트 도중이라 값이 다른 부분이 있습니다)


맵/리듀스를 이리저리 쓰다보면 기존의 SQL과는 또다른 재미있는 데이터 인출기법이란 점이, 꽤 ... 재미있습니다. 하지만, 문제는 저 함수가 호출될 때마다, 인덱스가 수정된다는 점이었습니다.

카우치는 데이터와 인덱스를 분리해서 관리합니다. 데이터를 저장할 때는 인덱스 처리를 하지 않습니다. 대신 VIEW 엔진이 동작할 때, 관련된 인덱스를 수정하게 됩니다.

이게 묘한 부작용을 일으키는데요.

update나 insert 가 많이 이루어진 후에 view를 호출하면 인덱스하는데 시간이 너무 오래걸린다는 점입니다. 테스트를 포기할 정도로 오래걸린 경우도 많았습니다.


나중에 찾아낸 해결책은 벌크-인서트를 수행하면서, 중간 중간에 view 엔진을 호출해주는 겁니다. 그렇게 하면 어느정도 참고 기다릴만합니다. 하지만 좀.. 뻘짓하는 느낌이었습니다.

인덱스 수정이 완료된 이후에는 VIEW를 수행하는데 걸리는 시간이 굉장히 짧아집니다. 그리고, 테스트에서 처럼 몇만개씩이 아닌, 천개정도의 데이터를 추가하고, VIEW를 돌려봤는데요. 응답을 얻기까지 얼마 안걸리더군요. 1~4초 내외인데, 오래걸린다는 느낌은 없었습니다.


유니크 키
---------
이건 좀 문젠데요. 카우치는 유니크키(unique key)를 지원하지 않습니다. (몽고는 지원) 편법은 있는 것 같지만, 어쨌든, 시스템이 자동생성하는 키( 필드명 : _id ) 를 제외하고는 유니크 키를 지원하지 않습니다.

즉, 회원 아이디라던가, 하는 것을 유니크 키로 지정해서, 동일한 아이디의 회원이 만들어지지 않도록 디비를 설정하는 것이 안됩니다.

요기 맨아래에 설명이 있는데... 노드가 하나일 때는 _id 필드에 원하는 필드를 넣으면 되긴하는데, multi-master 환경에서는 충돌할 수도 있다, 라고 적혀있습니다.



데이터 사이즈
------------
MySQL : 1.9G
MongoDB: 2.1G
CouchDB non-bulk: 18G
CouchDB bulk: 3.5G

데이터의 형태에 따라 차이가 날 것 같습니다만, 비율은 저정도 인것 같습니다. 특이한 점은 카우치는 MVCC때문인 것 같습니다만, 벌크일때와 아닐때 차이가 납니다. (compact db 라는 명령이 따로 있습니다.)



결론
----
몽고디비랑 카우치디비를 일대일로 비교하기는 힘듭니다. 초당 insert 가 너무 느리긴 합니다만, 카우치는 원래 컴퓨터를 추가하고 연결만 하면 자동으로 클라우드로 동작하는 것이 목표인 데이터베이스입니다. 느리면 서버를 추가하면 되죠.

몽고디비는 처음부터 속도를 중시하는 쪽이구요. (몽고도.. master-master 지원하지만 fail-over를 위한 것이라고 하네요. 그래도 그냥 잘 쓴다는 사람도 있긴합니다만..)

카우치디비는 일단 재미삼아 공부하기 적당하구요. 서비스 환경에 적용한 케이스도 꽤 있고, 그리 나쁜 선택은 아닌 것 같습니다. 하지만, 문제를 공부를 해야한다는 점입니다.

몽고디비는 지금 돌아보니 mysql 의 document-db 버전인 것 같다는 인상입니다. sql을 알던 사람이 적응하기 쉽고, 드라이버나 예제들도 따라하기 좋습니다. 공부하는데 드는 시간이 비교적 짧습니다.

아마도, 테스트 과제 따위에서는 카우치, 당장 서비스 할 것에는 몽고, 가 어떨까 합니다. 저는 한동안 두가지 모두 병행해서 사용해보려고 합니다. 카우치쪽이 다음버전에서 어떤 점이 좋아질지 궁금하기 때문입니다. (어쩌면 속도?)

이상입니다.
Posted by jintopark

 

 
«이전  1  다음»