MongoDB 2.4.5 의 single instance 상황에서 겪은 현상.


MongoDB가 가장 많이 가루가 되도록 까이는 부분인, DB 단위 lock이 upsert와 remove가 혼재될 경우 거의 사용불가 상태에 이름.

upsert가 초당 평균 600~700건이 일어나는 상황에서 대규모 remove를 할 경우, (그러니까 엄청나게 넣으면서 엄청나게 빼는 상황)

서로 lock을 잡아먹으면서 dead lock이 아닌가 의심될 정도로 아무것도 처리가 안됨. (page faults까지 엄청나게 증가하는 총체적 난국)


이럴 때 만약 remove 속도가 그렇게 중요한 상황이 아니라면, 

range remove가 아니라 atomic하게 하나의 document씩 remove 하면 가용성이 보장됨.


<?PHP

// upsert는 계속 초당 600~700건씩 들어온다고 가정하고,

// 30일전 데이터를 전부 삭제한다면


// 이 방법은 혼돈의 카오스 상황을 야기함.

$MongoClient->DB_NAME->COL_NAME->remove({date:{$lte:30일전_날짜}})


// 아래 방법으로 가용성이 보장됨.

// find 하면서 _id가 RAM에 올라와서 remove 자체도 그렇게 느리지 않음.

// 1. 삭제할 document를 find()

// _id 기준으로 삭제할 예정이므로 _id만 query함

$cursor = $MongoClient->DB_NAME->COL_NAME->find({date:{$lte:30일전_날짜}}, {_id:1});

foreach ($cursor as $v) {

    $_id = $v['_id'];

    // 하나씩 삭제

    $MongoClient->DB_NAME->COL_NAME->remove({_id: $_id}, {'w'=>0});

}





[주의] replicaSet이나 sharded에선 아직 안해봤음.










Posted by bloodguy
,