読者です 読者をやめる 読者になる 読者になる

中年engineerの独り言 - crumbjp

LinuxとApacheの憂鬱

今更ながら簡単Sharding構築

mongodb

Sharding構築手順とポイント

構成

                    mongos
                +-----------------+
                | 192.168.159.50  |
                +-----------------+

                    ConfigDB
 +-----------------+  +-----------------+  +-----------------+ 
 | 192.168.159.3   |  | 192.168.159.4   |  | 192.168.159.5   |       
 +-----------------+  +-----------------+  +-----------------+  

                     Shard1
 +-----------------+  +-----------------+  +-----------------+ 
 | 192.168.159.100 |  | 192.168.159.101 |  | 192.168.159.102 |       
 +-----------------+  +-----------------+  +-----------------+  

手順

  1. shardを構成するmongodを立てる
    • 必要ならreplicasetを設定
  2. configDBを構成するmongodを立てる
    • 1 or 3 node
  3. mongosを立てる
  4. mongosにsharding関連コマンドを発行

shardを構成するmongodを立てる

特に難しい事は何もない。
ただ一点、--shardsvr オプションを付ける事。
また通常の構成と異なり、27018ポートを使うのが普通。

設定ファイルと起動例

== /usr/local/mongo/conf/mongod.conf ==
replSet=RSname
port=27018
dbpath=/usr/local/mongo/data
pidfilepath=/usr/local/mongo/logs/mongod.pid
logpath=/usr/local/mongo/logs/mongod.log
logappend=true
quiet=true
fork=true
directoryperdb=true
maxConns=20000
slowms=1000
nohttpinterface = true
notablescan = true
nssize = 4
noauth = true

shardsvr = true

普通、大量のコレクションを扱う事は無いのでnssizeは小さくて良い。

$ /usr/local/mongo/bin/mongod -f /usr/local/mongo/conf/mongod.conf
必要ならreplicasetを設定

上記設定ファイルでreplSet指定した名前を_idとするオブジェクトを食わす。
members配列の中身は適当に。。

$ /usr/local/mongo/bin/mongo 192.168.159.100:27018 <<<'
config = { _id: "RSname", members:[
 {_id: 0, host: "192.168.159.100:27018", priority:2},
 {_id: 1, host: "192.168.159.101:27018", priority:1},
 {_id: 2, host: "192.168.159.102:27018", priority:0},
]}
rs.initiate(config)'

暫く待てば完了する。

$ /usr/local/mongo/bin/mongo 192.168.159.100:27018 <<<'rs.status()'

で確認。

configDBを構成するmongodを立てる

本番運用ならば、必ず3ノード構成にする。

    • configsvrオプションを指定する。

普通、ポート番号は27019。

3ノード構成とはいっても、configDBは自律的には何もしない。(ので何も設定しない)
その分、レプリケーション関連は全部mongosが頑張る。

面倒な話は全部mongosの個所でする。


設定ファイルと起動例

== /usr/local/mongo/conf/mongodc.conf ==
port=27019
dbpath=/usr/local/mongo/datac
pidfilepath=/usr/local/mongo/logs/mongodc.pid
logpath=/usr/local/mongo/logs/mongodc.log
logappend=true
quiet=true
fork=true
directoryperdb=true
maxConns=20000
slowms=1000
nohttpinterface = true
notablescan = true
nssize = 4

configsvr = true
$ /usr/local/mongo/bin/mongod -f /usr/local/mongo/conf/mongodc.conf

mongosを立てる

Sharding構成で一番ハマる個所

一度指定したconfigdbの値は絶対変更できない。
configdbのあるノードが燃えて無くなった場合でも差し替え出来る様に必ずIP指定ではなく名前指定にしておく事。


チャンクサイズを最適化したければ指定しておく。


設定ファイルと起動例

== /usr/local/mongo/conf/mongos.conf ==
configdb=conf1.mongodb.jp:27019,conf2.mongodb.jp:27019,conf3.mongodb.jp:27019
# これはダメ!
# configdb=192.168.159.3:27019,192.168.159.4:27019,192.168.159.5:27019
port=27017
pidfilepath=/usr/local/mongo/logs/mongos.pid
logpath=/usr/local/mongo/logs/mongos.log
logappend=true
quiet=true
fork=true
# chunkSize = ??
$ /usr/local/mongo/bin/mongos -f /usr/local/mongo/conf/mongos.conf

mongosにsharding関連コマンドを発行

1. シャーディングクラスタを構成するシャード追加

  • レプリカセットを登録する場合は、<レプリカセット名>/<サーバ>:<ポート>を指定する。
    少なくとも1ノードを指定すればレプリカセット構成ノード全て引いてくれる。
  • スタンドアローンノードを登録する場合は<サーバ>:<ポート>で良い。
 $ /usr/local/mongo/bin/mongo 192.168.159.50:27017 <<<'sh.addShard("RSname/192.168.159.100:27018")' 

2. シャーディング対象とするDBを指定

 $ /usr/local/mongo/bin/mongo 192.168.159.50:27017 <<<'sh.enableSharding("MyDatabase")'

3. シャーディング対象とするコレクションを指定

 $ /usr/local/mongo/bin/mongo 192.168.159.50:27017 <<<'sh.shardCollection("MyDatabase.MyCollection",{MyShardKey:1})'
 # hash-based の場合
 $ /usr/local/mongo/bin/mongo 192.168.159.50:27017 <<<'sh.shardCollection("MyDatabase.MyCollection",{MyShardKey:"hashed"})'

4. シャーディングの状態を確認

 $ /usr/local/mongo/bin/mongo 192.168.159.50:27017 <<<'printShardingStatus()'

補足

sh.??? とかの関数は、runCommandの簡易&劣化版I/Fなので、細かい事やる場合はrunCommandを使う。
http://docs.mongodb.org/manual/reference/command/addShard/
などなど、、

PHPから叩いてみる

<?php
$m = new Mongo('mongodb://192.168.159.50:27017');
$db = $m->selectDB('admin');
$r = $db->command(array('enableSharding'=>'MyDatabase'));
var_dump($r);
$r = $db->command(array('shardCollection'=>'MyDatabase.MyCollection','key'=>array('MyShardKey'=>1)));
var_dump($r);