ページ

2010年12月14日

MongoDBのメモリ使用量 もうちょっとまじめに計測

昨日の続きです。MapReduce使ったときにメモリをどれくらい使っているのかを、もうちょっとまじめに計測してみました。まずは、データを作るところ。

import pymongo
conn = pymongo.Connection()
db = conn.my_test
table = db.items

def insert():
    for i in range(1, 1000000):
        oid = table.save({"key": i, "value": 1000 % i})

です。割と小さめのデータを100万件放り込んでいます。これを

def map_reduce(max_key):
    # map reduce
    from pymongo.code import Code

    map_code = Code("""
function() {
  emit(this.key, this);
}
"""
)

    reduce_code = Code("""
function(key, values) {
  return {"count": values.length, title: values[0]["title"], url: values[0]["url"]};
}
""")
    result = table.map_reduce(map_code, reduce_code,
                              query = {"key": {"$lte": max_key}})
    return result

で10,100, 1000,10000, 100000, 250000, 500000, 750000, 1000000とmap reduceの対象になるレコードを増やしていって、map reduce処理後のMongoDBのメモリの使用量(RSSの値)をプロットしたものが、この図です。

250000のあたりが少し落ちているのは誤差でしょう。
左の方の10000ぐらいまではほとんど重なっていてわかりませんね。map reduceの処理には80Mぐらいのメモリが必要らしいです。
そこから先はほぼ、比例的にメモリの使用量が増えていきます。map reduceでqueryを制御しないと沢山メモリを食べてくれます。

メモリの消費量が多いのが悪いこととはいえないのですが、レンタルサーバでMongoDBがメモリを食いつぶして落っこちるのは悲しい限りです。レンタルサーバでは大体一時間に16000件のデータが登録されます。今回測定したコードだと20000件のデータでは大体、90Mか100Mぐらいのメモリ使用量でした。実際に動いているデータ構造とサンプルデータ(ちょっと小さめ)で実行すると、メモリの使用量が250Mぐらいでした。300Mぐらいであればすぐに消費してくれそうです。クエリの結果がほぼメモリにすべてのってmap reduceが実行されているのでしょう。

ということで、他のプロセスがメモリも消費することを考えると、メモリがちょっとばかしたりません。490円で動いていますが、やっぱり倍の値段を払わないとだめそうです。

MongoDBはメモリを沢山食います。RDBを使っておけば楽だったかもしれません。

でわでわ。

0 件のコメント: