# Setup

MongoDB 버전은 4.0.6으로 Setup을 진행하였지만 다른 버전에도 호환이 가능할 것이다.

Sharding을 위해 shard를 구성해 보겠다. 간단하게 동작 예제만 보여주는 것이기 때문에 single node에서 진행하며 3개의 shard로 진행하겠다.

![Figure1. The Architecture of a Sharded Cluster](https://2046636869-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lb7Vg1sUEHzMkgFpUvH%2F-LdY3kbLjQ9H_vN_MzCY%2F-LdY7TcLsQ2rLRXBrigX%2Fshard_architecture.png?alt=media\&token=a3ec2db4-1181-4c23-afb5-16e0e3dd696c)

위 그림에서 실선으로 된 것만 설정하여 동작시킬 예정이다.

만약 다수의 노드에서 하고 싶다면 폴더를 노드라고 생각해도 무방하다. 예를 들어, shard1을 node1, shard2를 node2라고 생각해도 좋다.

* /path/to/mongodb/shard1 : the folder to store data in rs1 shard
* /path/to/mongodb/shard2 : the folder to store data in rs2 shard
* /path/to/mongodb/shard3 : the folder to store data in rs3 shard
* /path/to/mongodb/config : the folder to store config data in configRepl

Figure 1의 점선이 replication을 표현한 것이다. 이 setting 과정은 replication과 함께 진행하는 것이 일반적이며 (availability), replication은 앞서 세팅한 것과 동일하게 진행 가능하다.

하지만 우리는 이과정에서는 sharding만 연습할 것이므로 이 과정을 생략한 것이다.(***no replication)***

## configuration files

### Configure Server

{% hint style="info" %}
아래의 code block은 mongod를 구동하기 위한 configuration file이다. &#x20;

line 4, 15, 19, 20, 31은 자신의 시스템에 맞도록 수정해서 사용해야 한다.&#x20;
{% endhint %}

```
# /path/to/mongodb/config/mongod.conf

storage:
  dbPath: /path/to/mongodb/config
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

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

# network interfaces
net:
  port: 20000
  bindIp: 127.0.0.1

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

replication:
  replSetName: "configRepl"

sharding:
  clusterRole: configsvr
```

> 문서에서 공통적으로 /path/to/mongodb 를 같은 path로 수정하도록 하고, 위의 config 파일을 그 폴더에 넣어서 세팅한다.

중요한 라인의 설명은 아래와 같다.

* [ ] line 4: DB path는 말그대로 db를 저장할 폴더를 지정
* [ ] line 15: log를 기록하는 것으로 DB path와 동일한 폴더의 파일로 지정하는 것이 편함
* [ ] line 19: mongod가 사용할 포트 번호를 지정. 시스템에서 먼저 사용하고 있는 포트 이외에 번호로 사용할 것.
* [ ] line 20: mongod가 사용할 IP. 컴퓨터 IP나 localhost와 같은 지정 IP 사용.&#x20;
  * [ ] (single node이기 때문에 수정하지 않아도 됨)
* [ ] line 31: replication set 이름으로 같은 이름으로 지정해 줘야 같은 replication set으로 인식
* [ ] line 34: 이 서버의 역할을 나타냄 (수정하지 않아도 됨)

#### Shard servers

{% hint style="info" %}
아래의 내용은 각 shard 서버를 위한 config file이다.

line 4, 15, 19, 20, 31을 수정한다.
{% endhint %}

```
# /path/to/mongodb/shardX/mongod.conf

storage:
  dbPath: /path/to/mongodb/shardX
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

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

# network interfaces
net:
  port: 30000
  bindIp: 127.0.0.1

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

replication:
  replSetName: rs1

sharding:
  clusterRole: shardsvr
```

> configure server의 부분과 거의 동일하며 각 shard를 위해 /path/to/mongodb/shardX에 위의 파일을 위치시킨다.

중요 라인의 설명은 다음과 같다.

* [ ] line 4: 각 shard의 폴더 path
* [ ] line 15: 각 shard의 log 파일 path
* [ ] line 19: 각 shard의 port 번호.
* [ ] line 20: 각 shard의 IP. configuration file과 마찬가지로 시스템 IP나 지정 IP.&#x20;
  * [ ] (single node이기 때문에 수정하지 않아도 됨)
* [ ] line 31: replication 이름. 같은 replication은 같은 이름으로 지정
* [ ] line 34: shard 역할 (수정할 필요 없음)

순서대로 line 4, 15, 19, 31를 수정하도록 한다.

* shard1 :&#x20;

  * /path/to/mongodb/shard1
  * /path/to/mongodb/shard1/mongoconf.log
  * 30000
  * rs1

* shard2 :&#x20;

  * /path/to/mongodb/shard2
  * /path/to/mongodb/shard2/mongoconf.log
  * 30001
  * rs2

* shard3 :&#x20;
  * /path/to/mongodb/shard2
  * /path/to/mongodb/shard2/mongoconf.log
  * 30002
  * rs3

#### Mongos server

{% hint style="info" %}
mongod와 다르게 몇가지 내용들이 빠져 있는것을 확인 가능하다.  필요한 부분만 세팅하도록 한다.

line 6, 10, 11, 22를 수정한다.
{% endhint %}

```
# /path/to/mongodb/mongos/mongod.conf

systemLog:
  destination: file
  logAppend: true
  path: /path/to/mongodb/mongos/mongoconf.log

# network interfaces
net:
  port: 30005
  bindIp: 127.0.0.1

# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

sharding:
  configDB: "configRepl/localhost:20000"
```

* [ ] line 6: log path를 지정
* [ ] line 10: port 번호 지정
* [ ] line 11: 시스템 IP이나 지정 IP.
  * [ ] (single node이기 때문에 수정하지 않아도 됨)
* [ ] line 22: configRepl/localhost:20000은 configure server의 config와 일관성 있도록 작성

## Runing servers

{% hint style="info" %}
mongod를 시작하는 것과 같은 shell 명령이다. 주의할 점은 마지막 줄의 mongos로 시작해야 한다.&#x20;

&#x20;\--config 뒤에는 config file path이다.
{% endhint %}

```
$ mongod --config config/mongod.conf
$ mongod --config shard1/mongod.conf
$ mongod --config shard2/mongod.conf
$ mongod --config shard3/mongod.conf
$ mongos --config mongos/mongod.conf
```

## Initiation

{% hint style="info" %}
각 서버에 접근하여 명령을 작성해 준다.
{% endhint %}

```
mongo localhost:30000
> rs.initiate({ _id : "rs1", members:[ {_id:0, host:"127.0.0.1:30000"}]})
```

```
mongo localhost:30001 
> rs.initiate({ _id : "rs2", members:[ {_id:0, host:"127.0.0.1:30001"}]})
```

```
mongo localhost:30002 
> rs.initiate({ _id : "rs3", members:[ {_id:0, host:"127.0.0.1:30002"}]})
```

```
mongo localhost:30005 
> sh.addShard("rs1/127.0.0.1:30000")
> sh.addShard("rs2/127.0.0.1:30001")
> sh.addShard("rs3/127.0.0.1:30002") 
> sh.status()
```

> 마지막은 mongos에 접근하여 sh.status()로 현재 서버들의 상태를 볼수 있다.

## Test

mongos에 접근하여서 아래의 내용을 작성해 본다. 100,000개를 insert해서 각 shard에 데이터가 분산되어 있는지 확인하는 작업이다.

현재 sharding은 range와 hash 두가지를 지원하는데 우리는 hash 방법으로 데이터를 분산해 보자.

```
> sh.enableSharding("shardingTest")
> use shardingTest
> db.items.createIndex({"index": "hashed"})
> sh.shardCollection("shardingTest.items", {"index": "hashed"})
> for (var n=1; n<=100000; n++)
>  db.items.insert({index: n, name: "test"})
> db.items.count() // print 100,000
```

마지막 줄 (line 7)에서 실제로 insert가 확실히 되었는지 확인을 해보자.

다음으로는 각 mongod 서버에 접근하여 그 노드에 데이터의 개수로 잘 분산 되어 있는지 확인해 본다.

```
// connect primary shard server
> use shardingTest
> db.items.count() // print about 30,000 each server
```

mongos에서 db를 만들고 insert를 했기 때문에 약 3만개씩 분배되어 있을 것이다.&#x20;

hash로 분배되어 있기 때문에 정확한 3으로 나뉜 개수로 분배되지는 않지만 대략적으로 3만개씩 분산되어 있는것을 확인할 수 있을 것이다.
