LoginSignup
6
6

More than 5 years have passed since last update.

CentOS7 / MongoDBでシャーディング

Last updated at Posted at 2016-06-24

今更というネタでもありますが物理的に3台のマシンを使ってMongoDBのクラスタを組んだのでメモ
シャーディングとレプリカセットの組み合わせです

各ノードのIPアドレスとポートの例

IPアドレス

ノード名 db1 db2 db3
IPアドレス 192.168.0.11 192.168.0.12 192.168.0.13

各サービス毎の利用ポート

ノード名 db1 db2 db3
config 27018 27018 27018
mongos 27017 27017 27017
shard1 27021 27021 27021*
shard2 27022* 27022 27022
shard3 27023 27023* 27023
  • レプリカセットのshard(x)の後ろに*があるのはArbiter(実データは持たずプライマリノードの選挙権だけを持つ)の意味
  • 各ノードではconfig/shard1/shard2/shard3の4つのmongodプロセスとmongosプロセスが1つ動いてることになる
  • クライアントアプリを各ノードのローカルに配布した場合、mongodb://localhost:27017/your_database で接続できる
  • configサーバのレプリカセットにArbiterは存在できない

3台で同じ設定すんのめんどくせー

Ansibleで自動化したり、ディスクや仮想マシンのコピーができるクラウドサービスとか使うと捗ります
私もとあるイベント行ったときにもらったさくらのクラウドの無料枠でやりました

OS側の設定

MongoDBのインストール

この辺を参考にしてください(自演)

/etc/hostsの設定

IP直打ちだとノードがお亡くなりになったときに困ることも出てくるのでhostsで名前で引けるように追記して設定

/etc/hosts
192.168.0.11 db1
192.168.0.12 db2
192.168.0.13 db3

firewalldの設定

各ノード同士で接続できるようにポートをあけます
今回はスイッチの下で直接インターネットにはつながないマシンなのでガバガバ設定

firewall-cmd --permanent  --zone=public --add-port=27017/tcp
firewall-cmd --permanent  --zone=public --add-port=27018/tcp
firewall-cmd --permanent  --zone=public --add-port=27021/tcp
firewall-cmd --permanent  --zone=public --add-port=27022/tcp
firewall-cmd --permanent  --zone=public --add-port=27023/tcp
firewall-cmd --reload

データ領域用のレプリカセットを作成する

データディレクトリの作成

デフォルトの場所とはちょっと違うところに各シャード用のデータベースのディレクトリを掘っておきます
プロセスを実行するユーザ mongod をオーナーにしてください

mkdir /data
mkdir /data/log
mkdir /data/mongoc
mkdir /data/shard1
mkdir /data/shard2
mkdir /data/shard3

chown mongod:mongod /data/log
chown mongod:mongod /data/mongoc
chown mongod:mongod /data/shard1
chown mongod:mongod /data/shard2
chown mongod:mongod /data/shard3

pidファイル置き場の作成

既にあれば不要

mkdir /var/run/mongodb
chown mongod:mongod /var/run/mongodb

データ領域用の設定ファイル

せっかくのMongoDB 3.2なのでWiredTigerで作ります
1つ作ってしまえばあとはコピペでほぼ大丈夫
各パラメータ(特にcacheSizeGBあたり)はサーバスペックに合わせて調整が必要

/etc/shard1.conf
# shard1.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard1.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard1"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard1.pid  # location of pidfile

# network interfaces
net:
  port: 27021

#security:

#operationProfiling:

replication:
   replSetName: "shard1"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:
/etc/shard2.conf
# shard2.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard2.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard2"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard2.pid  # location of pidfile

# network interfaces
net:
  port: 27022

#security:

#operationProfiling:

replication:
   replSetName: "shard2"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:
/etc/shard3.conf
# shard3.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/shard3.log
  logRotate: rename

# Where and how to store data.
storage:
  dbPath: "/data/shard3"
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/shard3.pid  # location of pidfile

# network interfaces
net:
  port: 27023

#security:

#operationProfiling:

replication:
   replSetName: "shard3"

sharding:
  clusterRole: "shardsvr"

## Enterprise-Only Options

#auditLog:

#snmp:

systemdの設定

yumでインストールするとCentOS7の場合でも/etc/init.d/*なスクリプトを経由することになるようなのですが、ここはCentOS7とsystemdの流儀に従ってsystemdのサービスを定義してみます
これも1個作ってコピペしてましたがスクリプト化するのがいちばん手っ取り早いかもしれない

/lib/systemd/system/shard1.service
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard1.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard1.pid

[Install]
WantedBy=multi-user.target
/lib/systemd/system/shard2.service
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard2.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard2.pid

[Install]
WantedBy=multi-user.target
/lib/systemd/system/shard3.service
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/shard3.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/shard3.pid

[Install]
WantedBy=multi-user.target

設定が終わったら

systemctl daemon-reload

で設定ファイルの更新を反映させて起動

systemctl start shard1.service
systemctl start shard2.service
systemctl start shard3.service

データ領域のレプリカセット

各レプリカセットをMongoDB上で設定します

shard1用のレプリカセット
mongo db1:27021

shard1 > config = {
_id: 'shard1',
members: [
  {_id: 0, host: 'db1:27021'},
  {_id: 1, host: 'db2:27021'},
  {_id: 2, host: 'db3:27021', arbiterOnly: true}
]};

shard1 > rs.initiate(config)
shard2用のレプリカセット
mongo db2:27022

shard2 > config = {
_id: 'shard2',
members: [
  {_id: 0, host: 'db2:27022'},
  {_id: 1, host: 'db3:27022'},
  {_id: 2, host: 'db1:27022', arbiterOnly: true}
]};

shard2 > rs.initiate(config)
shard3用のレプリカセット
mongo db3:27023

shard3 > config = {
_id: 'shard3',
members: [
  {_id: 0, host: 'db3:27023'},
  {_id: 1, host: 'db1:27023'},
  {_id: 2, host: 'db2:27023', arbiterOnly: true}
]};

shard3 > rs.initiate(config)

データ置き場はこれで3つのパーティション、各パーティションはPrimaryとSecondary2台のディスク+Arbiterの構成になりました

configサーバの設定

configサーバ用の設定ファイルを作成して

/etc/mongoc.conf
# mongoc.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/mongoc.log

# Where and how to store data.
storage:
  dbPath: /data/mongoc
  engine: wiredTiger
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
      statisticsLogDelaySecs: 0
    collectionConfig:
      blockCompressor: "snappy"
    indexConfig:
      prefixCompression: true
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongoc.pid  # location of pidfile

# network interfaces
net:
  port: 27018

#security:

#operationProfiling:

replication:
   oplogSizeMB: 64
   replSetName: mongoc

sharding:
  clusterRole: configsvr

## Enterprise-Only Options

#auditLog:

#snmp:

サービス設定を書いて

/lib/systemd/system/mongoc.service
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/mongoc.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PIDFile=/var/run/mongodb/mongoc.pid

[Install]
WantedBy=multi-user.target

systemdに認識させてプロセスを起動

systemctl daemon-reload
systemctl start mongoc.service

次にレプリカセットを構成

configサーバ用のレプリカセット
mongo db1:27018

mongoc > config = {
_id: 'mongoc',
configsvr: true,
members: [
  {_id: 0, host: 'db1:27018'},
  {_id: 1, host: 'db2:27018'},
  {_id: 2, host: 'db3:27018'}
]};

mongoc > rs.initiate(config)

configsvr: true を指定しているのがミソ
私はこれを忘れて小一時間ハマってました

ルータ(mongos)

基本手順は同じ
ただプロセスの実行ファイル名がmongodではなくmongosになったりmongos自体は実データを持たないプロセスなのでstorageの設定が不要、代わりにconfigDBで設定を持つレプリカセットを指定するという設定ファイルの違いがある

/etc/mongos.conf
# mongos.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /data/log/mongos.log

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongos.pid  # location of pidfile

# network interfaces
net:
  port: 27017

#security:

#operationProfiling:

replication:
  localPingThresholdMs: 15

sharding:
  autoSplit: true
  configDB: mongoc/db1:27018,db2:27018,db3:27018

## Enterprise-Only Options

#auditLog:

#snmp:
/lib/systemd/system/mongos.service
[Unit]
Description=High-performance, schema-free document-oriented database

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/mongos.conf"
ExecStart=/usr/bin/mongos $OPTIONS
PIDFile=/var/run/mongodb/mongos.pid

[Install]
WantedBy=multi-user.target

そして起動

systemctl daemon-reload
systemctl start mongos.service

エラーがなければこれで構成までは終わり

データを実際にシャーディング環境に載せるには

どっかの端末でmongosに接続する
今回の設定例ならシェルから

mongo

だけでつながるはず
プロンプトが

mongos>

になってれば正解

データベースをシャーディング環境に教える

mongos> sh.enableSharding('dbname')

その上でコレクションを指定してシャーディングさせる

どのシャードに格納するかを決定させるキーを指定すること
キーは予めインデックスを作っておいてください

mongos> sh.shardCollection('collection-name', { someIndex : 1 })

自動起動にも対応するなら

systemctl enable shard1.service
systemctl enable shard2.service
systemctl enable shard3.service
systemctl enable mongoc.service
systemctl enable mongos.service
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6