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 ...
半分ぐらい? ごっそり減ってる!
お疲れ様でしてー