DBAtlas · データベース運用アトラス

MongoDB レプリカセット + シャーディングの構築

症状

目標: MongoDB の自動フェイルオーバー付きレプリカセットを構築し、水平スケーリングのためにシャードクラスタに拡張する。

1. 同じ replSet 名で mongod プロセスを起動する

各レプリカセットメンバーを同じ --replSet 名と到達可能な --bind_ip で起動する。本番では keyFile または TLS による内部認証が推奨される。明確な過半数のため、投票メンバーは奇数にする。

MongoDB

mongod --replSet rs0 --port 27017 --dbpath /data/n1 --bind_ip localhost,10.0.0.11
mongod --replSet rs0 --port 27017 --dbpath /data/n2 --bind_ip localhost,10.0.0.12
mongod --replSet rs0 --port 27017 --dbpath /data/n3 --bind_ip localhost,10.0.0.13

2. レプリカセットを初期化する

mongosh で 1 つのメンバーに接続し、rs.initiate() を呼び出してすべてのメンバーを定義する。これにより最初の選出が起動され、プライマリが選ばれる。rs.status() で PRIMARY/SECONDARY のロールを確認する。

MongoDB

rs.initiate({
  _id: 'rs0',
  members: [
    { _id: 0, host: '10.0.0.11:27017' },
    { _id: 1, host: '10.0.0.12:27017' },
    { _id: 2, host: '10.0.0.13:27017' }
  ]
})
rs.status()

3. メンバーを追加し、優先度と必要なら arbiter を設定する

後からメンバーを rs.add() で追加する。priority はどのメンバーがプライマリになりやすいかを決める (0 = プライマリにならない)。arbiter は投票のみを行いデータを持たない。データノードが偶数の場合のタイブレーカーとして使われるが、データの安全性のためには実メンバーが好ましい。arbiter ベースのトポロジー (特に PSA) では、データノードがダウンすると majority の write concern を満たせず書き込みが待機する。5.0+ では arbiter を追加する前に、setDefaultRWConcern でクラスタ全体のデフォルト write concern を明示的に設定する必要がある場合がある。

MongoDB

rs.add({ host: '10.0.0.14:27017', priority: 0.5 })
// Arbiter only if really needed (a data-bearing member is preferred):
rs.addArb('10.0.0.15:27017')
// change priority:
cfg = rs.conf(); cfg.members[0].priority = 2; rs.reconfig(cfg)

4. シャーディング用に config サーバーのレプリカセットを構築する

シャードクラスタのメタデータは config サーバーのレプリカセット (--configsvr) に保持される。それ自体もレプリカセットとして初期化され、高可用性のため 3 メンバーが推奨される。

MongoDB

mongod --configsvr --replSet cfgrs --port 27019 --dbpath /data/cfg1 --bind_ip localhost,10.0.0.21
-- mongosh (on the config server):
rs.initiate({ _id: 'cfgrs', configsvr: true, members: [
  { _id: 0, host: '10.0.0.21:27019' },
  { _id: 1, host: '10.0.0.22:27019' },
  { _id: 2, host: '10.0.0.23:27019' } ] })

5. シャードのレプリカセットと mongos ルーターを起動する

各シャードは --shardsvr で起動された独立したレプリカセットである (データの永続性はシャード内のレプリケーションによる)。mongos ルーターは config サーバーを指定して起動し、アプリケーションは mongos に接続する。

MongoDB

mongod --shardsvr --replSet shard1rs --port 27018 --dbpath /data/s1 --bind_ip localhost,10.0.0.31
# initiate shard1rs with rs.initiate, then mongos:
mongos --configdb cfgrs/10.0.0.21:27019,10.0.0.22:27019,10.0.0.23:27019 --port 27017 --bind_ip localhost,10.0.0.40

6. シャードを追加し、コレクションをシャーディングする

mongos に接続し、sh.addShard() で各シャードのレプリカセットを追加する。データベースでシャーディングを有効にし、sh.shardCollection() でシャードキーによりコレクションを分散する。キーの選択は重要である: 高いカーディナリティと均等な分布を持つべきである。sh.status() でチャンクの分布を監視する。

MongoDB

sh.addShard('shard1rs/10.0.0.31:27018')
sh.addShard('shard2rs/10.0.0.32:27018')
sh.enableSharding('appdb')
sh.shardCollection('appdb.events', { customer_id: 'hashed' })
sh.status()
DBAtlas で開く →