MongoDB GridFS についてもろもろ @camelmasa
・自己紹介 ・今回何故 GridFS を調べたのか? ・ GridFS って何なのか? - ドライバー群 ・環境構築について - 検証環境 ・ ReplicaSet,Sharding での挙動 ・ mongofiles コマンド ・躓いた部分 ・もっと GridFS ! ・全体通したまとめ アジェンダ
・ @camelmasa( 道産子の 86 世代 ) ・ 旭川高専 ・ Livlis (kamado, inc.) ・元バリスタ (paul bassett etc.) 自己紹介
・ Livlis へのフィードバック ・ Lithium + MongoDB の新サービス ( 画像を沢山ストレージする系サービス ) 何故 GridFS を調べたのか?
MongoDB に巨大なファイルを格納するための仕様です。 MongoDB は、バイナリデータの格納を  BSON  でサポートしています。 しかし、  MongoDB で、 BSON オブジェクトは 4MB のサイズに制限されているが… GridFS って何なのか?
この GridFS の仕様は、大きいファイルを複数のドキュメントに透過的に分割する方法を提供します。 http://www.mongodb.org/display/DOCSJP/GridFS GridFS って何なのか?
ドライバー群 PHP, Java, Python, Ruby, Perl,earlang(github) GridFS って何なのか?
検証環境 ・ Amazon EC2 micro Instance Basic 64-bit Amazon Linux AMI 2011.02.1 Beta (1 core CPU, 613MB) 検証だけなら Large とかにすれば良かった…。 環境構築について
検証環境 ReplicaSet ReplicaSet Sharding1 Sharding2 環境構築について
Config の設定方法 通常の設定方法と変わらない! [/mongo/mongo-config.conf] configsvr=true dbpath=/mongo/db/config logpath=/mongo/log/config/mongo.log logappend=true fork=true [ 起動 ]mongod -f /mongo/mongo-config.conf 環境構築について
Mongos の設定方法 通常の設定方法と変わらない! [/mongo/mongos.conf] logpath=/mongo/log/mongos/mongos.log configdb=localhost:27019 port=27021 fork=true [ 起動 ]mongos -f /mongo/mongos.conf 環境構築について
ReplicaSet の設定方法 通常の設定方法と変わらない! [/mongo/mongo-s1r1.conf] dbpath=/mongo/db/s1_r1 port=28201 logpath=/mongo/log/s1_r1.log logappend=true rest=true replSet=s1 journal=true fork=true [ 起動 ]mongo -f /mongo/mongo-s1r1.conf 環境構築について
ReplicaSet の設定方法 通常の設定方法と変わらない! [ コマンド ] config = {_id: 's1', members: [{_id: 0, host: 'localhost:28201'},{_id: 1, host: 'localhost:28202'},{_id: 2, host: 'localhost:28203'}]} rs.initiate(config);  環境構築について
Sharding の設定方法 通常の設定方法と変わらない! [/mongo/mongo-s1r1.conf] dbpath=/mongo/db/s1_r1 port=28201 logpath=/mongo/log/s1_r1.log logappend=true rest=true replSet=s1 journal=true fork=true [ 起動 ]mongo -f /mongo/mongo-s1r1.conf 環境構築について
Sharding の設定方法 通常の設定方法と変わらない! [ コマンド ] db.runCommand( { enablesharding : "test" }); db.fs.chunks.ensureIndex({'files_id':1}); db.runCommand( { shardcollection : "test.fs.chunks", key : { files_id : 1 } } )  環境構築について
ReplicaSet の挙動 [mongos]mongofiles --host localhost:27021 put replica.set  connected to: localhost:27021 added file: { _id: ObjectId('4e3368d3c629125977fed2b7'), filename: "replica.set", chunkSize: 262144, uploadDate: new Date(1311992019116), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } Done! ReplicaSet,Sharding での挙動
ReplicaSet の挙動 [mongos] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の master] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の slave1] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の slave2] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } ReplicaSet,Sharding での挙動
ReplicaSet の挙動 [sharding2 の master] > db.fs.files.find({'filename':'replica.set'}) [sharding2 の slave1] > db.fs.files.find({'filename':'replica.set'}) [sharding2 の slave2] > db.fs.files.find({'filename':'replica.set'}) ReplicaSet,Sharding での挙動
Sharding の挙動 > db.printShardingStatus()  --- Sharding Status ---  sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "s1", "host" : "s1/localhost:28201,localhost:28202,localhost:28203" } { "_id" : "s2", "host" : "s2/localhost:28204,localhost:28205,localhost:28206" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "s2" } test.fs.chunks chunks: s1  10 s2  10 too many chunksn to print, use verbose if you want to force print { "_id" : "fs", "partitioned" : false, "primary" : "s2" } ReplicaSet,Sharding での挙動
Sharding の挙動 > db.printShardingStatus()  --- Sharding Status ---  sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "s1", "host" : "s1/localhost:28201,localhost:28202,localhost:28203" } { "_id" : "s2", "host" : "s2/localhost:28204,localhost:28205,localhost:28206" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "s2" } test.fs.chunks chunks: s1  10 s2  10 too many chunksn to print, use verbose if you want to force print { "_id" : "fs", "partitioned" : false, "primary" : "s2" } ReplicaSet,Sharding での挙動
[PUT]… ファイルの新規登録 mongofiles --host localhost:27021 put a.txt  connected to: localhost:27021 added file: { _id: ObjectId('4e3349480eed7346d277d523'), filename: "a.txt", chunkSize: 262144, uploadDate: new Date(1311983944316), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } Done! ※ 同じファイル名で登録すると削除時に一緒に削除される mongofiles コマンド
[PUT]… ファイルの上書き登録 mongofiles --host localhost:27021  -r  put a.txt  connected to: localhost:27021 added file: { _id: ObjectId('4e3349480eed7346d277d523'), filename: "a.txt", chunkSize: 262144, uploadDate: new Date(1311983944316), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } done! mongofiles コマンド
[GET]… ファイルの取得 mongofiles --host localhost:27021 get a.txt  connected to: localhost:27021 done write to: a.txt mongofiles コマンド
[LIST]… ファイルをリスト表示 mongofiles --host localhost:27021 list a.txt  1000 … ( ファイル名 ,byte 数 ) mongofiles コマンド
[SEARCH]… ファイル検索 mongofiles --host localhost:27021 search a.txt connected to: localhost:27021 a.txt  0 mongofiles --host localhost:27021 search txt connected to: localhost:27021 a.txt  0 -> 完全一致じゃなくて良い。 mongofiles コマンド
[DELETE]… ファイルの削除 mongofiles --host localhost:27021 delete a.txt connected to: localhost:27021 Done! ※ 同じファイル名は全て削除されます! mongofiles コマンド
・ ReplicaSet が設定出来ない! EC2 の root device の容量が通常 8GB しかない。 ReplicaSet の設定をすると、 8GB が直ぐ埋まります。 ファイルを vim で開く度に .swp ファイル作れないという、エラーが出て気づきました。 100GB の Volumes を追加して mount し解決。 ->100G 中 48G 程埋まる。 今回の躓いた所
・ Sharding されない! 完全に僕の勘違いでした。 sharding1,sharding2 を使って検証していたのですが、ファイルを追加しても sharding2 に偏って保存されてしまっていました。 しかし、これでもかと言う程ファイルを追加したら、 sharding された。 今回の躓いた所
ReplicaSet の挙動の確認の際、 mongofies の挙動が微妙。 ・ mongofiles –host [master server] search test.txt -> ファイルが表示される。 ・ mongofiles –host [slave server] search test.txt -> ファイルが表示されない、エラーも出ない。 しかし、 db.test.fs.files.find({'filename':'test.txt'}) のコマンドは master,slave にもあるのは確認出来る。 (db.getMongo().setSlaveOk() 実行済み ) 今回の躓いた所
・ nginx-gridfs nginx の拡張モジュール。 スクリプトを介さず、 web サーバーから gridfs のファイルのレスポンスを返す。 [github] https://github.com/mdirolf/nginx-gridfs [ 参考 ] http://mybikejp.blogspot.com/2011/01/nginxgridfs.html もっと GridFS!
・ rack-gridfs 先程の nginx-gridfs の rack 版 。 [github] https://github.com/skinandbones/rack-gridfs もっと GridFS!
GridFS を用いるのに特別な設定・使用方法等は必要無し。 通常の ReplicaSet,Sharding 設定・使用方法と変わらない! (GridFS はあくまで仕様である為、当たり前と言われれば当たり前。 ) 気軽に分散ファイルシステムが出来ると考えると嬉しいですね。 ( 運用時に潜む罠は除く ) スクリプトからの実行では無く、 web サーバーとの連携の事例が出てくるのは面白いと思います。 全体を通したまとめ
ご清聴有り難うございました。

Mongo dbのgridfsについて

  • 1.
  • 2.
    ・自己紹介 ・今回何故 GridFSを調べたのか? ・ GridFS って何なのか? - ドライバー群 ・環境構築について - 検証環境 ・ ReplicaSet,Sharding での挙動 ・ mongofiles コマンド ・躓いた部分 ・もっと GridFS ! ・全体通したまとめ アジェンダ
  • 3.
    ・ @camelmasa( 道産子の86 世代 ) ・ 旭川高専 ・ Livlis (kamado, inc.) ・元バリスタ (paul bassett etc.) 自己紹介
  • 4.
    ・ Livlis へのフィードバック・ Lithium + MongoDB の新サービス ( 画像を沢山ストレージする系サービス ) 何故 GridFS を調べたのか?
  • 5.
    MongoDB に巨大なファイルを格納するための仕様です。 MongoDBは、バイナリデータの格納を BSON でサポートしています。 しかし、 MongoDB で、 BSON オブジェクトは 4MB のサイズに制限されているが… GridFS って何なのか?
  • 6.
  • 7.
    ドライバー群 PHP, Java,Python, Ruby, Perl,earlang(github) GridFS って何なのか?
  • 8.
    検証環境 ・ AmazonEC2 micro Instance Basic 64-bit Amazon Linux AMI 2011.02.1 Beta (1 core CPU, 613MB) 検証だけなら Large とかにすれば良かった…。 環境構築について
  • 9.
    検証環境 ReplicaSet ReplicaSetSharding1 Sharding2 環境構築について
  • 10.
    Config の設定方法 通常の設定方法と変わらない![/mongo/mongo-config.conf] configsvr=true dbpath=/mongo/db/config logpath=/mongo/log/config/mongo.log logappend=true fork=true [ 起動 ]mongod -f /mongo/mongo-config.conf 環境構築について
  • 11.
    Mongos の設定方法 通常の設定方法と変わらない![/mongo/mongos.conf] logpath=/mongo/log/mongos/mongos.log configdb=localhost:27019 port=27021 fork=true [ 起動 ]mongos -f /mongo/mongos.conf 環境構築について
  • 12.
    ReplicaSet の設定方法 通常の設定方法と変わらない![/mongo/mongo-s1r1.conf] dbpath=/mongo/db/s1_r1 port=28201 logpath=/mongo/log/s1_r1.log logappend=true rest=true replSet=s1 journal=true fork=true [ 起動 ]mongo -f /mongo/mongo-s1r1.conf 環境構築について
  • 13.
    ReplicaSet の設定方法 通常の設定方法と変わらない![ コマンド ] config = {_id: 's1', members: [{_id: 0, host: 'localhost:28201'},{_id: 1, host: 'localhost:28202'},{_id: 2, host: 'localhost:28203'}]} rs.initiate(config); 環境構築について
  • 14.
    Sharding の設定方法 通常の設定方法と変わらない![/mongo/mongo-s1r1.conf] dbpath=/mongo/db/s1_r1 port=28201 logpath=/mongo/log/s1_r1.log logappend=true rest=true replSet=s1 journal=true fork=true [ 起動 ]mongo -f /mongo/mongo-s1r1.conf 環境構築について
  • 15.
    Sharding の設定方法 通常の設定方法と変わらない![ コマンド ] db.runCommand( { enablesharding : "test" }); db.fs.chunks.ensureIndex({'files_id':1}); db.runCommand( { shardcollection : "test.fs.chunks", key : { files_id : 1 } } ) 環境構築について
  • 16.
    ReplicaSet の挙動 [mongos]mongofiles--host localhost:27021 put replica.set connected to: localhost:27021 added file: { _id: ObjectId('4e3368d3c629125977fed2b7'), filename: "replica.set", chunkSize: 262144, uploadDate: new Date(1311992019116), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } Done! ReplicaSet,Sharding での挙動
  • 17.
    ReplicaSet の挙動 [mongos]> db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の master] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の slave1] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } [sharding1 の slave2] > db.fs.files.find({'filename':'replica.set'}) { "_id" : ObjectId("4e3368d3c629125977fed2b7"), "filename" : "replica.set", "chunkSize" : 262144, "uploadDate" : ISODate("2011-07-30T02:13:39.116Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0 } ReplicaSet,Sharding での挙動
  • 18.
    ReplicaSet の挙動 [sharding2の master] > db.fs.files.find({'filename':'replica.set'}) [sharding2 の slave1] > db.fs.files.find({'filename':'replica.set'}) [sharding2 の slave2] > db.fs.files.find({'filename':'replica.set'}) ReplicaSet,Sharding での挙動
  • 19.
    Sharding の挙動 >db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "s1", "host" : "s1/localhost:28201,localhost:28202,localhost:28203" } { "_id" : "s2", "host" : "s2/localhost:28204,localhost:28205,localhost:28206" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "s2" } test.fs.chunks chunks: s1 10 s2 10 too many chunksn to print, use verbose if you want to force print { "_id" : "fs", "partitioned" : false, "primary" : "s2" } ReplicaSet,Sharding での挙動
  • 20.
    Sharding の挙動 >db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "s1", "host" : "s1/localhost:28201,localhost:28202,localhost:28203" } { "_id" : "s2", "host" : "s2/localhost:28204,localhost:28205,localhost:28206" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "s2" } test.fs.chunks chunks: s1 10 s2 10 too many chunksn to print, use verbose if you want to force print { "_id" : "fs", "partitioned" : false, "primary" : "s2" } ReplicaSet,Sharding での挙動
  • 21.
    [PUT]… ファイルの新規登録 mongofiles--host localhost:27021 put a.txt connected to: localhost:27021 added file: { _id: ObjectId('4e3349480eed7346d277d523'), filename: "a.txt", chunkSize: 262144, uploadDate: new Date(1311983944316), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } Done! ※ 同じファイル名で登録すると削除時に一緒に削除される mongofiles コマンド
  • 22.
    [PUT]… ファイルの上書き登録 mongofiles--host localhost:27021 -r put a.txt connected to: localhost:27021 added file: { _id: ObjectId('4e3349480eed7346d277d523'), filename: "a.txt", chunkSize: 262144, uploadDate: new Date(1311983944316), md5: "d41d8cd98f00b204e9800998ecf8427e", length: 0 } done! mongofiles コマンド
  • 23.
    [GET]… ファイルの取得 mongofiles--host localhost:27021 get a.txt connected to: localhost:27021 done write to: a.txt mongofiles コマンド
  • 24.
    [LIST]… ファイルをリスト表示 mongofiles--host localhost:27021 list a.txt 1000 … ( ファイル名 ,byte 数 ) mongofiles コマンド
  • 25.
    [SEARCH]… ファイル検索 mongofiles--host localhost:27021 search a.txt connected to: localhost:27021 a.txt 0 mongofiles --host localhost:27021 search txt connected to: localhost:27021 a.txt 0 -> 完全一致じゃなくて良い。 mongofiles コマンド
  • 26.
    [DELETE]… ファイルの削除 mongofiles--host localhost:27021 delete a.txt connected to: localhost:27021 Done! ※ 同じファイル名は全て削除されます! mongofiles コマンド
  • 27.
    ・ ReplicaSet が設定出来ない!EC2 の root device の容量が通常 8GB しかない。 ReplicaSet の設定をすると、 8GB が直ぐ埋まります。 ファイルを vim で開く度に .swp ファイル作れないという、エラーが出て気づきました。 100GB の Volumes を追加して mount し解決。 ->100G 中 48G 程埋まる。 今回の躓いた所
  • 28.
    ・ Sharding されない!完全に僕の勘違いでした。 sharding1,sharding2 を使って検証していたのですが、ファイルを追加しても sharding2 に偏って保存されてしまっていました。 しかし、これでもかと言う程ファイルを追加したら、 sharding された。 今回の躓いた所
  • 29.
    ReplicaSet の挙動の確認の際、 mongofiesの挙動が微妙。 ・ mongofiles –host [master server] search test.txt -> ファイルが表示される。 ・ mongofiles –host [slave server] search test.txt -> ファイルが表示されない、エラーも出ない。 しかし、 db.test.fs.files.find({'filename':'test.txt'}) のコマンドは master,slave にもあるのは確認出来る。 (db.getMongo().setSlaveOk() 実行済み ) 今回の躓いた所
  • 30.
    ・ nginx-gridfs nginxの拡張モジュール。 スクリプトを介さず、 web サーバーから gridfs のファイルのレスポンスを返す。 [github] https://github.com/mdirolf/nginx-gridfs [ 参考 ] http://mybikejp.blogspot.com/2011/01/nginxgridfs.html もっと GridFS!
  • 31.
    ・ rack-gridfs 先程のnginx-gridfs の rack 版 。 [github] https://github.com/skinandbones/rack-gridfs もっと GridFS!
  • 32.
    GridFS を用いるのに特別な設定・使用方法等は必要無し。 通常のReplicaSet,Sharding 設定・使用方法と変わらない! (GridFS はあくまで仕様である為、当たり前と言われれば当たり前。 ) 気軽に分散ファイルシステムが出来ると考えると嬉しいですね。 ( 運用時に潜む罠は除く ) スクリプトからの実行では無く、 web サーバーとの連携の事例が出てくるのは面白いと思います。 全体を通したまとめ
  • 33.