0. 준비

- 설치 : https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/

- 구성 : https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

 

한곳에 설치하여 테스트하기 위해 tar 설치 (https://www.mongodb.com/download-center/community?jmp=docs)

> wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.10.tgz

> tar xzfx mongodb-linux-s390x-rhel72-4.0.10.tgz

> mv xzfx mongodb-linux-s390x-rhel72-4.0.10 mongo

> vi ~/.bashrc

export PATH=/home/user1/mongo/mongo/bin:$PATH

> # ulimit 설정 (https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings)

ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -l unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000

 

# 영구 설정

> sudo vi /etc/security/limits.conf

 * soft fsize unlimited
 * hard fsize unlimited
 * soft cpu unlimited
 * hard cpu unlimited
 * soft as unlimited
 * hard as unlimited
 * soft memlock unlimited
 * hard memlock unlimited
 * soft nofile 64000
 * hard nofile 64000
 * soft rss unlimited
 * hard rss unlimited
 * soft nproc 64000
 * hard nproc 64000

 

 

1. replica set(cluster) 구성방식

대표적인 방식 : PSA 방식(저렴하게 구성), PSS 방식

 

P : Primary(Master DB)

S : Secondary(Slave DB). 읽기 전용. shell 접속 후 rs.slaveOk() 후에 명령 실행 가능.

A : Arbiter(VM). 장애시 primary 선출을 담당하는 프로세스로 데이터를 갖지 않으므로 저사양 별도 머신에 설치. shard 구성시 router(mongos) 및 config server와 같은 머신에 설치하는 경우도 많음.

 
 
 

 

1-1. PSA 방식 구성

 

- primary / secondary / arbiter 설치

- data/log 디렉토리 생성

mkdir -p /home/user1/mongo/psa/primary_data

mkdir -p /home/user1/mongo/psa/secondary_data

mkdir -p /home/user1/mongo/psa/arbiter_data

 

- mongod.conf 작성

replSetName 이름이 동일해야 함

 

[user1@localhost psa]$ cat primary.conf

systemLog:

   destination: file

   path: "/home/user1/mongo/psa/primary.log"

   logAppend: true

   logRotate: rename

storage:

   engine: wiredTiger

   directoryPerDB: true

   wiredTiger:

      engineConfig:

         journalCompressor: snappy

      collectionConfig:

         blockCompressor: snappy

      indexConfig:

         prefixCompression: true

   dbPath: "/home/user1/mongo/psa/primary_data"

   journal:

      enabled: true

      commitIntervalMs: 300

processManagement:

   fork: true

   pidFilePath: "/home/user1/mongo/psa/primary.pid"

net:

   port: 27020

   bindIpAll: true

   maxIncomingConnections: 20000

   unixDomainSocket:

      enabled: false

replication:

    oplogSizeMB: 10240

    replSetName: "rs01"

setParameter:

    failIndexKeyTooLong: false

 

[user1@localhost psa]$ cat secondary.conf (차이 나는 부분만 적음)

   path: "/home/user1/mongo/psa/secondary.log"

   dbPath: "/home/user1/mongo/psa/secondary_data"

   pidFilePath: "/home/user1/mongo/psa/secondary.pid"

   port: 27030

   

[user1@localhost psa]$ cat arbiter.conf (차이 나는 부분만 적음)

   path: "/home/user1/mongo/psa/arbiter.log"

   dbPath: "/home/user1/mongo/psa/arbiter_data"

   pidFilePath: "/home/user1/mongo/psa/arbiter.pid"

   port: 27040

 

 

- 구동

mongod -f /home/user1/mongo/psa/primary.conf

mongod -f /home/user1/mongo/psa/secondary.conf

mongod -f /home/user1/mongo/psa/arbiter.conf

 

- 참고.종료

mongod --shutdown -f /home/user1/mongo/psa/primary.conf

mongod --shutdown -f /home/user1/mongo/psa/secondary.conf

mongod --shutdown -f /home/user1/mongo/psa/arbiter.conf

 

- 설정

 

- primary 쉘 접속하여 replica set 설정 (_id: "rs01")

접속> mongo localhost:27020/admin

명령>

rs.initiate(
   {
      _id: "rs01",
      version: 1,
      members: [
         { _id: 0, host : "192.168.56.101:27020" },
         { _id: 1, host : "192.168.56.101:27030" }
      ]
   }
)

 

직접적으로 primary 에 대한 우선순위를 지정하려면 priority 를 설정해야 한다.

(https://docs.mongodb.com/manual/reference/replica-configuration/#rsconf.members[n].priority)

ex>  { _id: 0, host : "192.168.56.101:27020", priority: 10 },

 

 

결과> primary 접속시 "rs01:PRIMARY>", secondary 접속시 "rs01:SECONDARY>" 표시됨

상태확인> rs.status()

 

- arbiter 추가

접속> mongo localhost:27020/admin

명령>

rs.addArb("192.168.56.101:27040")

혹은

rs.add( { host: "192.168.56.101:2040", arbiterOnly: true } )

 

 

상태확인> rs.status()

 

- root 계정 생성

접속> mongo localhost:27020/admin

명령>

use admin
db.createUser(
   {
     user: "user1",
     pwd: "user1",
     roles: ["root" ]
   }
)

 

 

- 확인 : 데이터 복제

primary

use user2
db.col1.insert({"test" : "ok"})

 

secondary

rs.slaveOk()

use user2
db.col1.find()

 

- 확인 : primary 다운

primary 종료시 secondary 쉘 접속하면 "rs01:PRIMARY>" 로 나옴

기존 primary 재실행시 "rs01:SECONDARY>"로 나옴

 

- 테스트 : 개발

- 콘솔 앱(.Net Core) 프로젝트

https://www.nuget.org/packages/mongodb.driver 설치

 

엔터 칠때마다 insert 수행

using System;

namespace DotNetConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            //var client = new MongoDB.Driver.MongoClient(
            //    "mongodb://192.168.56.101:27020,192.168.56.101:27030/?replicaSet=rs01");

            var settings = new MongoDB.Driver.MongoClientSettings {
                ReplicaSetName = "rs01",
                Servers = new[]
                {
                    new MongoDB.Driver.MongoServerAddress("192.168.56.101", 27020),
                    new MongoDB.Driver.MongoServerAddress("192.168.56.101", 27030),
                },
                MinConnectionPoolSize = 1
            };
            var client = new MongoDB.Driver.MongoClient(settings);

            var db = client.GetDatabase("user2");
            var col = db.GetCollection<MongoDB.Bson.BsonDocument>("col1");

            while (true)
            {
                Console.WriteLine("ENTER");
                Console.ReadLine();

                var doc = new MongoDB.Bson.BsonDocument
                {
                    { "name", "dot net core" },
                };

                col.InsertOne(doc);
            }

        }
    }
}

 

 

- 실행

insert -> primary 종료 -> insert

==> secondary가 primary가 되고 insert 수행함.

클라이언트 프로그램에선 primary/secondary/arbiter 모두에 대해 커넥션을 함

 

 

 

- 샘플 파일

 

Program.cs
다운로드
psa.tar.gz
다운로드