2011-07-26 2 views
1

우리는 mysql에서 mongodb로 이동하려고합니다. , {id_src, id_dest} {1, 2} {1Mysql에서 MongoDB 2000000 행으로 전환

id_dest 그들은

데이터 exemple MySQL의

약 200 백만 행은, id_src : MySQL의 구조 id_src INT id_dest INT 고유 열쇠 3} {1,10} {2,3} {2,10} {4,3}

데이터를 다시 가져와야합니다. {id_dest, count} {3,3} {10,2} {2 , 1}

mongodb에서 mysql의 구조를 바꾸기 시작했습니다. 삽입 성능은 매우 좋았습니다 (매우 양호) : 약 1 시간 동안 200 백만 행을 삽입했습니다.

하지만 map reduce를 사용하여 그룹을 가져와야합니다. 지도 축소에는 약 1 시간이 걸렸습니다. 각 문서가 id_src의 십만를 가질 수 {id_dest, {id_src1, id_src2}}

:

그래서 나는 다른 MongoDB의 구조를 만들려고.

여기

$res=mysql_unbuffered_query("select * from ids limit 10000100"); 
while ($tab=mysql_fetch_array($res)) { 
$collection->update(array('_id'=>(int)$tab['id_dest']),array('$push' => array('src'=>(int)$tab['id_src'])),array("upsert" => true)); 
} 

그러나이 경우 성능

초 당 아주 나쁜, 단지 몇 갱신됩니다 내 insert.php 코드입니다.

내가 잘못 했나요?

+1

200h 행의 경우 1h가 "거대"인 경우 200m 행을 삽입하면 MySQL에 얼마나 오래 걸릴 수 있습니까? –

+1

"거대한"이라고 말하면서 나는 "매우 좋았다"고 말했습니다. 그러나 나의 문제는지도로 우리에게 완전하지만 받아 들일 수있는 "그룹을"얻는 시간을 줄이는 것이었다. mongodb 기능 (다중 값 필드)을 사용하는 새로운 문서 모델이 mysql 데이터 구조를 재현하는 것보다 영리하지 않은지 궁금했습니다. – benfromaix

+0

알겠습니다. 좋은 답변을 기다리 자구 : –

답변

6

먼저 Map/Reduce는 실시간 분석을 위해 설계되지 않았습니다. 또한 MongoDB는 현재 M/R의 핵심으로 제한되어 있습니다.

데이터를 가져 오기 위해 M/R을 사용하는 경우 "실시간"이 아니므로 X 분 (또는 시간)마다 업데이트됩니다.

여기에 두 가지 효율적인 방법이 있습니다

  1. 증분 M/R
  2. 실시간 카운터

옵션 # 1 :이를 위해 증분 M/R

가 옵션을 사용하면 모든 데이터에 대해 한 번 M/R을 실행합니다. 그런 다음 앞으로는 수정 된 데이터에 대해서만 M/R을 실행합니다. 현재 200M 문서가있는 경우 다음에 210M 문서가있을 수 있습니다. 즉 M/R이 더 느려집니다. 그러나 새/변경된 문서 만 실행해야하는 경우 1 시간 이내에 처리해야합니다.

here 문서의 reduce 출력 옵션을 살펴보십시오.

다시 말하면, 관련 데이터를 M/R하기 만하면 시스템은 기존 데이터에 대해 "re-reduce"를 전제로합니다. 이 방법으로 당신은 "증분"M/R을 얻습니다.

옵션 # 2 : 데이터에 대한 하나의 "개요"의 결과에 대한 두 번째 : 실시간, 당신은 두 개의 컬렉션이이 방법

에 대응한다. 데이터에 삽입 할 때 요약에 대해 증가분도 수행합니다.

Main Collection 
{src: 1, dest: 2} 
{src: 1, dest: 3} 
{src: 1, dest: 10} 
{src: 2, dest: 3} 
{src: 2, dest: 10} 
{src: 4, dest: 3} 

Summary Collection 
{dest: 3, count: 3} 
{dest: 10, count: 2} 
{dest: 2, count: 1} 

당신은 데이터 {src: 5, dest: 2}의 새로운 조각을받을 :

는이 데이터를 가정합니다. 두 업데이트를 할 것 :
db.main.insert({src: 5, dest: 2}); 
db.summary.update({dest: 2}, { $inc : { count: 1 } }, true); // upsert true 

가 여기에 새 데이터입니다 : {dest: 2, count: 2} :

Main Collection 
{src: 1, dest: 2} 
... 
{src: 4, dest: 3} 
{src: 5, dest: 2} 

Summary Collection 
{dest: 3, count: 3} 
{dest: 10, count: 2} 
{dest: 2, count: 2} 

당신은 우리가 우리의 요약을 업데이트 한 것을 알 수 있습니다.

분명히 여기에는 절충점이 있습니다. 더 많은 업데이트/삽입 (2x)이 필요하지만 실시간 카운터를 얻을 수 있습니다. 이제 MongoDB에는 트랜잭션이 없으므로 두 업데이트가 모두 수행되도록 전략을 결정해야합니다. 여기에는 할 수없는 많은 방법이 있습니다 (한 가지 방법에 대한 메시지 대기열 참조).

+0

지난 몇 시간 동안 제안한 실시간 솔루션을 구현했습니다. 나는 다만 중대한 결과를 얻는다. 요약 수집을 업데이트하는 것은 매우 빠르며 성능이 거의 저하되지 않으며 실시간 업데이트 카운터를받습니다. 감사 ! – benfromaix