今回は業務で扱う必要が出てきてしまったため急場しのぎですがmongoDBをやっていきます
いきなりシャーディング+レプリカセットとかいろんな概念が一気に入ってくるとわからなくなってしまいそうなので一つづつ理解していくようにしていく
また、各種ノードに関してローカルのサーバでポートを変えればいくらでもノードを立ち上げることができたので一台のVMで複数mongodを立ち上げることで試す
前提
大きく分けて下記三つの役割がある
mongos
クエリのルーティングなどを行う クライアント側のアプリケーションが接続を行うのはこのサーバ
mongod
シャードやレプリカセットを構成要素となるサーバ(ノード)
mongos,mongod(configserver)がない場合でも機能する(ローカルとか)
mongod(configserver)
各種設定やメタデータ(shardの設定やロックの情報などを管理)を扱っている
冗長化のためにレプリカセットを組んでおくのが基本
シャーディングを試す
下記と公式を参考にしました
MongoDBのSharding機能で遊ぶ - 個人的なまとめ
- コマンドについては下記
構成
- config
- 1台
- mongos
- 1台
- shard
- 3台

configサーバ
mkdir /data/mongo/config mongod --configsvr --port 27030 --dbpath=/data/mongo/config --logpath /data/mongo/config/log --fork
mongosの起動
mongos --port 27017 --configdb localhost:27030 --chunkSize 1 --logpath /data/mongo/mongos/log --fork
各シャードの起動
mkdir /data/mongo/shard1 mkdir /data/mongo/shard2 mkdir /data/mongo/shard3 mongod --port 27021 --dbpath=/data/mongo/shard1 mongod --port 27022 --dbpath=/data/mongo/shard2 mongod --port 27023 --dbpath=/data/mongo/shard3
シャードの追加
- mongos
use admin
db.runCommand({"addShard":"localhost:27021"})
db.runCommand({"addShard":"localhost:27022"})
db.runCommand({"addShard":"localhost:27023"})
- シャードの確認
どちらでも同じ出力
> db.printShardingStatus()
> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("580c68b71fc6c85737ab8492")
}
shards:
{ "_id" : "shard0000", "host" : "localhost:27021" }
{ "_id" : "shard0001", "host" : "localhost:27022" }
{ "_id" : "shard0002", "host" : "localhost:27023" }
active mongoses:
"3.2.7" : 1
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
データを入れてみる
mongo localhost:27017
> use sample # 自動でDB生成
> db.sample.insert({ category: "A", name: "aaaaaaaaaaa", age: 25 })
> db.sample.insert({ category: "B", name: "bbbbbbbbbbb", age: 35 })
> db.sample.insert({ category: "C", name: "ccccccccccc", age: 45 })
- 確認
> db.sample.find()
{ "_id" : ObjectId("580c701a8d3072138e3e8ef2"), "category" : "A", "name" : "aaaaaaaaaaa", "age" : 25 }
{ "_id" : ObjectId("580c7129526e856a60bb2113"), "category" : "B", "name" : "bbbbbbbbbbb", "age" : 35 }
{ "_id" : ObjectId("580c7151526e856a60bb2114"), "category" : "C", "name" : "ccccccccccc", "age" : 45 }
- 各シャードで確認してみる
$ mongo localhost:27021
> use sample
> db.sample.find()
{ "_id" : ObjectId("580c701a8d3072138e3e8ef2"), "category" : "A", "name" : "aaaaaaaaaaa", "age" : 25 }
{ "_id" : ObjectId("580c7129526e856a60bb2113"), "category" : "B", "name" : "bbbbbbbbbbb", "age" : 35 }
{ "_id" : ObjectId("580c7151526e856a60bb2114"), "category" : "C", "name" : "ccccccccccc", "age" : 45 }
$ mongo localhost:27022
> use sample
> db.sample.find()
$ mongo localhost:27023
> use sample
> db.sample.find()
シャード設定
DB単位,Collection単位でシャード設定しないといけない模様
新たにshsampleというDBにstats_aというcollectionを追加する
# DB,Collection二つ一遍に設定できるかと思ったら駄目だった
mongos> sh.shardCollection("shsample.stats_a",{"id": 1});
{ "ok" : 0, "errmsg" : "sharding not enabled for db shsample", "code" : 20 }
# シャード設定を追加する
mongos> use admin
switched to db admin
mongos> db.runCommand({ enablesharding: "shsample"});
{ "ok" : 1 }
# shsample に対してシャーディング設定をする( 渡すのはshard key) 複数も可能
sh.shardCollection("shsample.stats_a",{"id": 1})
- データを追加してみる
> db.stats_a.insert({ id: 1, name: "hoge" })
> db.stats_a.insert({ id: 2, name: "fuga" })
> db.stats_a.insert({ id: 3, name: "piyo" })
use shsample > db.stats_a.find()
変わってなかった。。。
そもそもchunksizeがバランシングの最小単位なので割と多めのデータを入れないといけない
今回の場合だと1Mですね(chunksize)
ファイルからデータをインポート
MongoDBのmongoimportでハマった:変なJSON形式 - 檜山正幸のキマイラ飼育記
ここを参考にログを入れてみる
テキストの1行に1個のJSONオブジェクトとのことなのでfluentdとかで出力したログファイルがちょうどよさそう
適当なログをさらってきて突っ込んでみます
$ mongoimport --port 27017 --db shsample --collection stats_a --type json --file sample.log
データを登録したので確認してみる
> sh.status()
....
databases:
{ "_id" : "sample", "primary" : "shard0000", "partitioned" : false }
{ "_id" : "test", "primary" : "shard0001", "partitioned" : false }
{ "_id" : "shsample", "primary" : "shard0002", "partitioned" : true }
shsample.stats_a
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard0000 28
shard0001 27
shard0002 153
too many chunks to print, use verbose if you want to force print
各シャードに分散されたようです
- 各シャードの件数を確認する
$ mongo localhost:27021/shsample > db.stats_a.count() 18790 $ mongo localhost:27022/shsample > db.stats_a.count() 19673 $ mongo localhost:27023/shsample > db.stats_a.count() 18937
- mongosから問い合わせる
$ mongo localhost:27017 mongos> db.stats_a.count() 57400
件数もぴったり合いました
mongodbの特性として各シャード一つ一つが独立したDBとして動作可能という特性がある模様
mongosが各シャードに対してクエリを発行してまとめているという感じでしょうか
shardingに関してはなんとなく概要がつかめた