MongoDB Replica Set + Sharding

## 目的
+ keyFileの作成　
https://qiita.com/yank_tkz/items/15c91a9011fd3dfc1a2b

+ Mongo Config Serverの冗長化
+ Sharding設定を行う

## 各種バージョン

OS: CentOS 7.3
MongoDB: version v3.4.7

## 構成

### ■ App1 (config1)、 APP2 (config2)、 APP3 (config3)
+ Mongo Config Server (Port:27001)
+ Mongos (Port:27000)

### ■ MongoDB1 (shard1)
+ MongoDB (Port:27020)

### ■ MongoDB2 (shard2)
+ MongoDB (Port:27020)

### ■ Arbiter (arbiter)
+ MongoDB (Port:27021)　

**config1, config2, shard1, shard2に関しては、全てのホストで[/etc/hosts]に記載する必要がある**

**hosts登録はReplica SetとMongosを結びつけるために必須**

_____

## MongoDBのコンフィグ

### 対象
+ MongoDB1
+ MongoDB2

```
vi /etc/mongodb/conf/shard.conf
```

```
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/shard.log

storage:
  dbPath: /var/lib/mongo/data/shard
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/shard.pid

net:
   bindIp: shard1 #　MongoDB2の場合はshard2
   port: 27020

replication:
   replSetName: replset1

sharding:
   clusterRole: shardsvr

# ※ Replica Set&ユーザー作成前は無効にしておく。
#security:
#   authorization: enabled
#   keyFile: /etc/mongodb/key/mongodb-keyfile
```

**ディレクトリがないとMongoDBは起動出来ないので注意**

## MongoDB Arbiterのコンフィグ

### 対象
+ Arbiter

```
vi /etc/mongodb/conf/arbiter.conf
```

```
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/arbiter.log

storage:
  dbPath: /var/lib/mongo/data/arbiter
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/arbiter.pid

net:
   bindIp: arbiter
   port: 27021

replication:
   replSetName: replset1

sharding:
   clusterRole: shardsvr

# ※ Replica Set&ユーザー作成前は無効にしておく。
#security:
#   authorization: enabled
#   keyFile: /etc/mongodb/key/mongodb-keyfile
```

## MongoDB Server起動

+ MongoDB1 (shard1)
+ MongoDB2 (shard2)

```
/usr/bin/mongod -f /etc/mongodb/conf/shard.conf
```

+ Arbiter (arbiter)

```
/usr/bin/mongod -f /etc/mongodb/conf/arbiter.conf
```

### ■ 実行結果
```
about to fork child process, waiting until server is ready for connections.
forked process: 2529
child process started successfully, parent exiting
```

## Replica Set 作成

```
$ mongo shard1:27020
> var config = {"_id" : "replset1",
                 "members" : [
                     {
                         "_id" : 0,
                         "host" : "shard1:27020"
                     },
                     {
                          "_id" : 1,
                          "host" : "shard2:27020"
                     },
                     {
                          "_id" : 2,
                          "host" : "shard2:27021",
                          "arbiterOnly" : true
                     }
                             ]
               }

> rs.initiate(config);
replset1:PRIMARY>
```

### ■ Replica Set(Config Server)確認
```
myconfig:PRIMARY>rs.conf();
```

## ユーザー作成
```
$ mongo shard1:27020
myconfig:PRIMARY> use admin;
myconfig:PRIMARY> db.createUser(
                      {
                          user:"root",
                          pwd:"mongodb",
                      roles:[
                      {
                         "role" : "root",
                         "db" : "admin"
                      }
                      ]
                      }
                );
```

## MongoDB Server停止

```
/usr/bin/mongod -f /etc/mongodb/conf/shard.conf
```
**Replica Set&ユーザー作成後、一度各サーバのMongoDB Server(Arbiterも)のプロセスを停止し、コンフィグのコメントアウトを外した後に再び起動する**

## ログイン確認
```
$ mongo shard1:27020/admin -u root -p
MongoDB shell version v3.4.7
Enter password:
```

**パスワード間違いや認証設定ミスの場合は以下のような結果になります**

```
$ mongo shard1:27001/admin -u root -p
MongoDB shell version v3.4.7
Enter password:
connecting to: mongodb://shard1:27001/admin
MongoDB server version: 3.4.7
2017-09-06T14:26:28.886+0900 E QUERY    [thread1] Error: Authentication failed. :
DB.prototype._authOrThrow@src/mongo/shell/db.js:1461:20
@(auth):6:1
@(auth):1:2
exception: login failed
```

## MongoDB Config Serverのコンフィグ

### 対象

+ App1
+ App2
+ App3

```
vi /etc/mongodb/conf/config.conf
```

```
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/config.log

storage:
  dbPath: /var/lib/mongo/data/config1
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/config.pid

net:
   bindIp: config1 # APP2の場合はconfig2、 APP3の場合はconfig3
   port: 27001

replication:
   replSetName: myconfig

sharding:
   clusterRole: configsvr

#security:
#   authorization: enabled
#   keyFile: /etc/mongodb/key/mongodb-keyfile
```

## Replica Set(Config Server)作成

```
$ mongo config1:27001
> var config = {"_id" : "myconfig",
                 "members" : [
                     {
                         "_id" : 0,
                         "host" : "config1:27001"
                     },
                     {
                          "_id" : 1,
                          "host" : "config2:27001"
                     },
                     {
                          "_id" : 2,
                          "host" : "config3:27001"
                     }
                             ]
               }

> rs.initiate(config);
myconfig:PRIMARY>
```

## Replica Set(Config Server)確認
```
myconfig:PRIMARY>rs.conf();
```

## ユーザー作成(Config Server)

```
$ mongo config1:27001
myconfig:PRIMARY> use admin;
myconfig:PRIMARY> db.createUser(
                      {
                          user:"root",
                          pwd:"mongodb",
                      roles:[
                      {
                         "role" : "root",
                         "db" : "admin"
                      }
                      ]
                      }
                );
```

## MongoDB Config Server停止

```
/usr/bin/mongod --shutdown -f /etc/mongodb/conf/config.conf
```
**Replica Set&ユーザー作成後、一度各サーバのConfig Serverのプロセスを停止し、コンフィグのコメントアウトを外した後に再び起動する**


## ログイン(Config Server)確認
```
$ mongo shard1:27001/admin -u root -p
MongoDB shell version v3.4.7
Enter password:
```

## Mongosのコンフィグ

```
vi /etc/mongodb/conf/mongos.conf
```

```
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongos.log

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongos.pid

net:
   bindIp: localhost
   port: 27000

sharding:
    configDB:  myconfig/config1:27001,config2:27001,config3:27001

security:
   authorization: enabled
   keyFile: /etc/mongodb/key/mongodb-keyfile

```

## Mongos起動

```
/usr/bin/mongos -f /etc/mongodb/conf/mongos.conf
```


## Sharding設定

Mongosにログインして以下のコマンドを実行する
**ユーザーはMongoDB Serverのものを使用する**

```
$ mongo localhost:27000/admin -u root -p
MongoDB shell version v3.4.7
Enter password:
```



```
> db.runCommand({"addShard":"replset1/shard1:27020,shard2:27020,shard2:27021",name:"replset"})
```

## Sharding確認

```
> db.printShardingStatus()
```

[test]という名前のDBのみシャーディング有効化

```
>  db.runCommand( { enablesharding : "test" });
```