[MongoDB] heavy write(upsert+remove) 상황에서 고가용성을 위한 팁 (heavy write, upsert, remove, availability)
DataBase 2014. 1. 29. 15:41MongoDB 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에선 아직 안해봤음.
'DataBase' 카테고리의 다른 글
[MongoDB] chunk 사이즈 체크 및 나누기 (chunk, dataSize, split) (0) | 2014.02.12 |
---|---|
[MongoDB] locks (0) | 2014.02.01 |
[MongoDB] MongoDB의 제약사항들. (MongoDB limits thresholds) (0) | 2014.01.28 |
[MongoDB] remove, update가 빈번한 collection의 storageSize 유지 전략 (reclaim, shrink storageSize) (0) | 2014.01.27 |
[MongoDB] document에 expire time 적용하기 (expire, TTL) (0) | 2013.07.25 |