ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AWS에 MongoDB ReplicaSet 구축 (PSA구조)
    개발 2022. 4. 18. 18:23

    이번 글에서는 3개의 Linux 인스턴스에 MongoDB ReplicaSet을 PSA(Primary Secondary Arbiter)구조로 구축해 보겠다.

     

    각 인스턴스에 MongoDB를 설치해준다.

    https://not-robot.tistory.com/2

     

    AWS에 MongoDB 설치

    AWS의 Linux 인스턴스에 yum으로 MongoDB를 설치해 보려 한다. sudo vi /etc/yum.repos.d/mongodb-org-5.0.repo [mongodb-org-5.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/amazon/2/mongo..

    not-robot.tistory.com

     

    sudo vi /etc/mongod.conf
    
    net:
      port: 27017
      bindIp: 127.0.0.1,해당 인스턴스의 IP # 띄어쓰기가 없어야 한다.
    replication:
      replSetName: MyFirstRepl # 설정할 replicaSet 이름

    세 개의 인스턴스 모두 위와 같이 파일을 수정해준 후

    sudo systemctl restart mongod

    재가동을 해준다. 해당 작업에서 문제가 생길 경우 오탈자가 없는지 확인한다.

    mongo

    로 접속하면 아무런 변화가 없다.

     

    세 개의 인스턴스 중 한 군데의 DB에서만  rs.initiate() 명령어를 입력한다.

    rs.initiate()
    
    {
    	"info2" : "no configuration specified. Using a default configuration for the set",
    	"me" : "인스턴스IP:27017",
    	"ok" : 1,
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1649923485, 1),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    			"keyId" : NumberLong(0)
    		}
    	},
    	"operationTime" : Timestamp(1649923485, 1)
    }
    MyFirstRepl:SECONDARY>
    MyFirstRepl:PRIMARY>

    위와 같이 MyFirstRepl:PRIMARY>로 변한 것을 볼 수 있다.

     

    rs.conf() 명령어를 입력하면 replicaSet의 설정을 볼 수 있다.

    MyFirstRepl:PRIMARY> rs.conf()
    {
    	"_id" : "MyFirstRepl",
    	"version" : 1,
    	"term" : 1,
    	"members" : [
    		{
    			"_id" : 0,
    			"host" : "Primary인스턴스IP:27017",
    			"arbiterOnly" : false,
    			"buildIndexes" : true,
    			"hidden" : false,
    			"priority" : 1,
    			"tags" : {
    
    			},
    			"secondaryDelaySecs" : NumberLong(0),
    			"votes" : 1
    		}
    	],
    	"protocolVersion" : NumberLong(1),
    	"writeConcernMajorityJournalDefault" : true,
    	"settings" : {
    		"chainingAllowed" : true,
    		"heartbeatIntervalMillis" : 2000,
    		"heartbeatTimeoutSecs" : 10,
    		"electionTimeoutMillis" : 10000,
    		"catchUpTimeoutMillis" : -1,
    		"catchUpTakeoverDelayMillis" : 30000,
    		"getLastErrorModes" : {
    
    		},
    		"getLastErrorDefaults" : {
    			"w" : 1,
    			"wtimeout" : 0
    		},
    		"replicaSetId" : ObjectId("6257bfcd35dd89ff7aec89bb")
    	}
    }

     

     

    이제 Secondary를 추가해보겠다. rs.add("인스턴스IP:27017") 를 입력한다.

    rs.add("Secondary 인스턴스 IP:27107")
    
    {
    	"ok" : 1,
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1649923565, 2),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    }

    정상적으로 추가된 모습은 위와 같다.

    해당 부분에서 아무 동작이 없을 시 인스턴스 보안 그룹에 MongoDB 포트가 열려있는지 확인한다.

     

    마지막으로 Arbiter를 추가한다. rs.addArb("인스턴스IP:27017")를 입력한다.

    rs.addArb("10.11.100.166:27017")
    {
    	"ok" : 1,
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1650273243, 1),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    			"keyId" : NumberLong(0)
    		}
    	},
    	"operationTime" : Timestamp(1650273243, 1)
    }

    정상적으로 추가된 모습은 위와 같다.

     

     

     

     

    1. 멤버 추가 시 에러

    {
    	"ok" : 0,
    	"errmsg" : "Either all host names in a replica set configuration must be localhost references, or none must be; found 1 out of 2",
    	"code" : 103,
    	"codeName" : "NewReplicaSetConfigurationIncompatible",
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1649920348, 1),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    			"keyId" : NumberLong(0)
    		}
    	},
    	"operationTime" : Timestamp(1649920348, 1)
    }

    이 경우, rs.status() 혹은 rs.conf() 명령어를 입력 후 localhost(127.0.0.1)로 들어간 members가 있는지 확인한다.

    rs.conf()
    
    {
    	"_id" : "TestRepl",
    	"version" : 1,
    	"term" : 1,
    	"members" : [
    		{
    			"_id" : 0,
    			"host" : "127.0.0.1:27017",
    			"arbiterOnly" : false,
    			"buildIndexes" : true,
    			"hidden" : false,
    			"priority" : 1,
    			"tags" : {
    
    			},
    			"secondaryDelaySecs" : NumberLong(0),
    			"votes" : 1
    		}
    	]
        .
        .
        .
    }

    위와 같이 들어가 있을 경우, mongo 접속을 나와서

    sudo vi /etc/mongod.conf
    
    net:
      port: 27017
      bindIp: 127.0.0.1,해당 인스턴스의 IP # 띄어쓰기가 없어야 한다.
    replication:
      replSetName: MyFirstRepl

    bindIP 부분을 꼭 수정해주어야 한다. 재가동 후 mongo에 접속해서 아래와 같은 명령어를 입력한다.

    cfg = rs.conf()
    cfg.members[0].host = "인스턴스IP:27017" #localhost로 되어있는 멤버 index
    rs.reconfig(cfg)
    
    {
    	"ok" : 1,
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1649924520, 1),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    			"keyId" : NumberLong(0)
    		}
    	},
    	"operationTime" : Timestamp(1649924520, 1)
    }

    여기까지 되면 다시 위로 올라가서 멤버를 추가해주면 된다.

     

    2. Arbiter 추가 시 에러

    rs.addArb("Arbiter Mongo IP:27017")
    
     {
    	"ok" : 0,
    	"errmsg" : "Reconfig attempted to install a config that would change the implicit default write concern. Use the setDefaultRWConcern command to set a cluster-wide write concern and try the reconfig again.",
    	"code" : 103,
    	"codeName" : "NewReplicaSetConfigurationIncompatible",
    	"$clusterTime" : {
    		"clusterTime" : Timestamp(1650273043, 1),
    		"signature" : {
    			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
    			"keyId" : NumberLong(0)
    		}
    	},
    	"operationTime" : Timestamp(1650273043, 1)
    }

    Arbiter 추가 시 한참 결과가 나오지 않다가 위와 같이 에러가 나는 경우가 있다.

    db.adminCommand({
        setDefaultRWConcern : 1,
        defaultWriteConcern: { w: 1 },
    })

    위의 명령어를 실행 후 다시 시도하면 정상적으로 추가가 된다.

Designed by Tistory.