ニシキヘビってかわいいよね、実際みたことないけど。

無職がいよかん国でプログラミングとかの備忘録を書いてます。 一日一食たまごかけごはん。

MongoDB コレクションごとの圧縮方法を変更しなおす

某動画サイトの動画情報を定期的に集める簡単なWebクローラーを作って、 クローリングしたWebページのスクラップ前(ダウンロードしたままのXMLとかHTMLとか)データをそのままと、 情報をスクラップしてjsonにしたものをMongoDBに保存している。

2回目のクロール終了時の容量がこれ

> show dbs
...
crawl_data  0.625GB
...

このままではあっという間にディスク容量を使い切る。 ギリギリまで削りたいなら、クロール直後で未加工のデータはファイルシステムに保存して、スクラップした後tar.xz圧縮でもいいのだが、 MongoDBにそのまま保存していれば、すこしスクラップ内容を変えた時にもさっと呼び出せたり、データの保存先の統一ができたりで楽。

本ケースではsnappyにる圧縮/伸長速度の速さは過剰であるためと、 ディスク容量を富豪的に使えない貧乏性の自身のため、zlib圧縮に切り替える。

まずは全データのダンプ、適当なディレクトリに移動して

mongodump -d crawl_data

続いて、クロールデータを保存しているDBの削除。端末からmongoコマンドでCUIを起動して、利用データベース変更後、db.dropDatabase()を実行する。

> use crawl_data
switched to db crawl_data
> db.dropDatabase()
{ "dropped" : "crawl_data", "ok" : 1 }

次に、圧縮形式を指定してCollectionを作成する。storageEngine.wiredTiger.configStringの値に、 WiredTigerに与えるオプションを<name>=<value>の形式で渡す。

他にもMongoDBが対応しているオプションならいろいろ渡せる模様。 詳細はWiredTiger: WT_SESSION Struct Reference。 lz4やzstdという、snappyやzlibの上位互換のような選択肢もある模様。

> use crawl_data
switched to db crawl_data
> db.createCollection('raw', {storageEngine: {wiredTiger: {configString: 'block_compressor=zlib'}}})
{ "ok" : 1 }

ちゃんと作れているか確認

> db.printCollectionStats()
raw
{
    "ns" : "crawl_data.raw",
    "size" : 0,
    "count" : 0,
    "storageSize" : 4096,
    "capped" : false,
    "wiredTiger" : {
        "metadata" : {
            "formatVersion" : 1
        },
        "creationString" : "access_pattern_hint=none,allocation_size=4KB,app_metadata=(formatVersion=1),block_allocation=best,block_compressor=zlib,cache_resident=false,check
# 以下略

いろいろ出力されるが、wiredTiger.metadata.creationStringの値に反映されていればOK。 今回であれば、block_compressor=zlibになっている。

他のコレクションでも作成と確認を同様に行う。

できたらダンプしたデータをレストアする。mongodumpを実行したディレクトリに移動して

mongorestore -d crawl_data ./dump/crawl_data/

容量はどのくらい減ったかな

>show dbs
...
crawl_data  0.367GB
...

半分ぐらい? ごっそり減ってる!

お疲れ様でしてー