2022-07-18,   심건우

지난 포스팅에서, docker-compose를 활용한 MongoDB 환경 설정 및 Python Client 예제를 진행했다.

MongoDB 설치(docker-compose) 및 Python Client 예제

이번 포스팅에선, docker-compose를 활용해서 MongoDB 클러스터 구축 예제를 진행해보겠다.

  • 참고 링크

MongoDB 구조 개념

docker-compose 이용해서 MongoDB Cluster 구조 구성하기

docker container로 mongo cluster 구성하기

Set up Sharding in MongoDB using Docker containers

클러스터 구조

image

config-server

shard 분산 정보 관리

1. docker-compose.yml 작성

version: '3'

services:

  config-server-1:
    container_name: config-server-1
    image: mongo
    command: mongod --configsvr --replSet config-rs --port 27017 --dbpath /data/db
    ports:
      - 40001:27017
    volumes:
      - ./config-server-1:/data/db

  config-server-2:
    container_name: config-server-2
    image: mongo
    command: mongod --configsvr --replSet config-rs --port 27017 --dbpath /data/db
    ports:
      - 40002:27017
    volumes:
      - ./config-server-2:/data/db

  config-server-3:
    container_name: config-server-3
    image: mongo
    command: mongod --configsvr --replSet config-rs --port 27017 --dbpath /data/db
    ports:
      - 40003:27017
    volumes:
      - ./config-server-3:/data/db

volumes:
  config-server-1: {}
  config-server-2: {}
  config-server-3: {}

2. 컨테이너 생성

docker-compose up -d

image

docker ps

image

3. 컨테이너 접속

docker exec -it [컨테이너 아이디] /bin/bash

image

4. replicat set 구성

mongo mongodb://[config-server-1 ip]:[config-server-1 port]

image

rs.initiate(
  {
    _id: "config-rs",
    configsvr: true,
    members: [
      { _id : 0, host : "[config-server-1 ip]:[config-server-1 port]" },
      { _id : 1, host : "[config-server-2 ip]:[config-server-2 port]" },
      { _id : 2, host : "[config-server-3 ip]:[config-server-3 port]" }
    ]
  }
)

image

5. 확인

rs.status()

image

image

image

image

shard-server

데이터의 실제 저장소

1. docker-compose.yml 작성

version: '3'

services:

  shard-1-server-1:
    container_name: shard-1-server-1
    image: mongo
    command: mongod --shardsvr --replSet shard-1-rs --port 27017 --dbpath /data/db
    ports:
      - 50001:27017
    volumes:
      - ./shard-1-server-1:/data/db

  shard-1-server-2:
    container_name: shard-1-server-2
    image: mongo
    command: mongod --shardsvr --replSet shard-1-rs --port 27017 --dbpath /data/db
    ports:
      - 50002:27017
    volumes:
      - ./shard-1-server-2:/data/db

  shard-1-server-3:
    container_name: shard-1-server-3
    image: mongo
    command: mongod --shardsvr --replSet shard-1-rs --port 27017 --dbpath /data/db
    ports:
      - 50003:27017
    volumes:
      - ./shard-1-server-3:/data/db

volumes:
  shard-1-server-1: {}
  shard-1-server-2: {}
  shard-1-server-3: {}

2. 컨테이너 생성

docker-compose up -d

image

docker ps

image

3. 컨테이너 접속

docker exec -it [컨테이너 아이디] /bin/bash

image

4. replicat set 구성

mongo mongodb://[shard-1-sever-1 ip]:[shard-1-server-1 port]

image

rs.initiate(
  {
    _id: "shard-1-rs",
    members: [
      { _id : 0, host : "[shard-1-server-1 ip]:[shard-1-server-1 port]" },
      { _id : 1, host : "[shard-1-server-2 ip]:[shard-1-server-2 port]" },
      { _id : 2, host : "[shard-1-server-3 ip]:[shard-1-server-3 port]" }
    ]
  }
)

image

5. 확인

rs.status()

image

image

image

image

mongos router

config-server의 설정을 참조하여, 데이터를 각 shard 에 분산 및 결과 반환

1.docker-compose.yml 작성

version: '3'

services:

  mongos:
    container_name: mongos
    image: mongo
     command: mongos --configdb config-rs/[config-server-1 ip]:[config-server-1 port],[config-server-2 ip]:[config-server-2 port],[config-server-3 ip]:[config-server-3 port] --bind_ip 0.0.0.0 --port 27017
    ports:
      - 60000:27017

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8111:8081
    environment:
      - ME_CONFIG_MONGODB_SERVER=mongos
      - ME_CONFIG_MONGODB_PORT=27017
    depends_on:
      - mongos

2. 컨테이너 생성

docker-compose up -d

image

docker ps

image

3. 컨테이너 접속

docker exec -it [mongos 컨테이너 아이디] /bin/bash

image

4.shard 클러스터 등록

mongo mongodb://[mongos server ip]:[mongos server port]

image

sh.addShard("shard-1-rs/[shard-1-server-1 ip]:[shard-1-server-1 port],[shard-1-server-2 ip]:[shard-1-server-2 port],[shard-1-server-3 ip]:[shard-1-server-3 port]")

image

3.확인

sh.status()

image

결과

1. 데이터 삽입 확인

  • python 클라이언트 데이터 삽입
# 라이브러리 import
from pymongo import MongoClient
from pprint import pprint

# client 연결
client = MongoClient(host='host ip address', 
                     port=60000)
# Database
epozen = client.epozen
# Collection
team_dt = epozen.team_dt
# Document ('_id' 지정 안 하면 알아서 고유 id 부여)
team_dt.insert_one({
#     '_id': 1,
    'name': 'member_1', # str
    'age': 26, # int
    'hobby': ['math'], # list
    'pet': {'dog': 'happy'}, # dict
    'score': 60.0 # float
})
# Document 두 개 이상 삽입
team_dt.insert_many([
    {
        'name': 'member_3',
        'age': 28,
        'hobby': ['baseball', 'music'],
        'pet': {'cat': 'mike'},
        'score': 75.5
    },
    {
        'name': 'member_4',
        'age': 29,
        'hobby': [],
        'pet': {'dog': 'alice'},
        'score': 90.0
    },
    {
        'name': 'member_5',
        'age': 30,
        'hobby': ['music'],
        'pet': {},
        'score': 100.0
    },
])

  • mongos 상태 변화 확인
rs.status()
sh.status()

image

  • mongos 보안 관련 로그 (TCP fast Open)

image

  • mongo-express 화면

image

  • 생성된 collection

image

  • 보안 관련 항목(TLS, id, pw 등) 미설정 -> replica set, balancer 미동작
  • shard와 데이터베이스는 정상 등록

정리

  • docker-compose를 활용해 MongoDB 클러스터 구성 예제를 진행해보았다.
  • 컨테이너 내부에 진입해야 하는 과정이 반복되어 약간 번거로웠다.
  • 실제 환경에 적용 시, 보안 관련 사항 관리에 어려움이 있을 것으로 예상된다.

업데이트: