1-2. PSS 구성

https://docs.mongodb.com/manual/replication/

 

 

 

- primary, secondary1, secondary2 설치

- data 디렉토리 생성

mkdir -p /home/user1/mongo/pss/m1_data

mkdir -p /home/user1/mongo/pss/m2_data

mkdir -p /home/user1/mongo/pss/m3_data

 

- mongod.conf 작성

replSetName 이름이 동일해야 함

 

[user1@localhost pss]$ cat m1.conf

systemLog:

   destination: file

   path: "/home/user1/mongo/pss/m1.log"

   logAppend: true

   logRotate: rename

storage:

   engine: wiredTiger

   directoryPerDB: true

   wiredTiger:

      engineConfig:

         journalCompressor: snappy

      collectionConfig:

         blockCompressor: snappy

      indexConfig:

         prefixCompression: true

   dbPath: "/home/user1/mongo/pss/m1_data"

   journal:

      enabled: true

      commitIntervalMs: 300

processManagement:

   fork: true

   pidFilePath: "/home/user1/mongo/pss/m1.pid"

net:

   port: 27020

   bindIpAll: true

   maxIncomingConnections: 20000

   unixDomainSocket:

      enabled: false

replication:

    oplogSizeMB: 10240

    replSetName: "rs01"

setParameter:

    failIndexKeyTooLong: false

 
[user1@localhost psa]$ cat m2.conf (차이 나는 부분만 적음)
   path: "/home/user1/mongo/pss/m2.log"
   dbPath: "/home/user1/mongo/pss/m2_data"
   pidFilePath: "/home/user1/mongo/pss/m2.pid"
   port: 27030
 
[user1@localhost psa]$ cat m3.conf (차이 나는 부분만 적음)
   path: "/home/user1/mongo/pss/m3.log"
   dbPath: "/home/user1/mongo/pss/m3_data"
   pidFilePath: "/home/user1/mongo/pss/m3.pid"
   port: 27040

 

 

- 구동

mongod -f /home/user1/mongo/pss/m1.conf

mongod -f /home/user1/mongo/pss/m2.conf

mongod -f /home/user1/mongo/pss/m3.conf

 

- 참고.종료

mongod --shutdown -f /home/user1/mongo/pss/m1.conf

mongod --shutdown -f /home/user1/mongo/pss/m2.conf

mongod --shutdown -f /home/user1/mongo/pss/m3.conf

 

- 설정

- primary 쉘 접속하여 replica set 설정

접속> 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" },
         { _id: 2, host : "192.168.56.101:27040" }
      ]
   }
)

 

직접적으로 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 },

 

- 확인

잠시후 몽고쉘(mongo) 접속 후 rs.status() 확인

 

각 mongodb 접속 후 PRIMARY, SECONDARY 확인

> mongo localhost:27020/admin

rs01:PRIMARY>

> mongo localhost:27030/admin

rs01:SECONDARY>

> mongo localhost:27040/admin

rs01:SECONDARY>

 

 

- root 계정 생성

접속> mongo localhost:27020/admin

명령>

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

 

 

- 확인 : 데이터 복제

- PRIMARY (m1)

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

 

- SECONDARY1 (m2) / SECONDARY2 (m3)

rs.slaveOk()

use user2
db.col1.find()

 

 

- 테스트 : 개발

- 콘솔 앱(.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,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),
            //            new MongoDB.Driver.MongoServerAddress("192.168.56.101", 27040),
            //        },
            //    MinConnectionPoolSize = 10
            //};
            //var client = new MongoDB.Driver.MongoClient(settings);

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

                while (true)
                {
                    try
                    {

                        Console.WriteLine("ENTER");
                        Console.ReadLine();

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

                        col.InsertOne(doc);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e);
                    }

            }

        }
    }
}

 

 

 

- 실행

insert -> primary (m1) 종료 -> insert -> secondary1 (m2) 종료 -> insert

=> 

primary 종료시 secondary1 쉘 접속하면 "rs01:PRIMARY>" 로 나옴 (secondary1이 primary가 되었음)

 

이후 secondary1 을 종료하면 secondary2가 primary가 되지 않고 그대로 secondary로 남아있음.

 

이런 상태일때 프로그램에서 쿼리를 insert를 수행하면 커넥션 에러 발생.

 

secondary2만 살아있는 경우이므로 네트워크 고립 등으로 인해 투표를 할 수 없으므로 혼자 primary로 동작하는 것을 방지하기 위해 의도된 동작임.

 

그럼 PSS 구조에 arbitary를 붙인 PSSA 면 투표가 가능하므로 마지막 secondary 2 가 primary 가 될 수 있지 않을까 하겠지만 안된다.

 

 

 

- 샘플 파일

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

 

 

 

 

 

 

- 이후

- shard 구성

router(mongos)와 config server 로 샤딩을 수행.

여러개로 구성된 replica set에 샤딩된 데이터가 저장됨.

 

router(mongos) : 클라이언트가 접속하여 쿼리하면 config server의 샤딩 정보 참조하여 해당 replica set 으로 전달 후 응답.

config server : 샤드 정보 저장/관리.