샤딩이란
데이터를 여러 서버에 분산해서 저장하고 처리할 수 있도록 하는 기술이다.
MongoDB 에서 샤딩을 적용하려면 샤드 클러스터를 구축해야 하는데,
이를 위해 파티션된 데이터의 범위와 샤드 위치 정보 등의 메타 정보를 저장하기 위한 컨피그 서버가 필요하다.
응용 프로그램이 필요한 데이터를 조회하거나 저장하려면 mongos 라고 불리는 라우터서버가 필요하다.
라우터는 쿼리 수행에 있어 프록시 역할을 하는데,
컨피그 서버의 메타 정보를 참조하여 필요한 데이터가 저장된 샤드로 쿼리를 전달하고 그 결과를 다시 응용 프로그램으로 반환하는 역할을 한다.
샤딩의 필요성
인터넷이 발달하고 인터넷이 가능한 단말기가 기하급수적으로 늘어나면서 서버에서는 더욱 많은 요청을 처리해야한다.
웹 서버는 특별한 설정이 필요한 상태를 가지지 않기 때문에 손쉽게 서버를 추가하거나 삭제가능하지만,
데이터베이스 서버는 모든 데이터를 영구적으로 가지고 있어야 하므로 단순히 서버만 투입한다고 해서 확장되지는 않는다.
데이터베이스 서버를 확장하려면 데이터베이스의 데이터가 여러 서버로 분산될 수 있게 미리 응용 프로그램을 설계하고 개발해야 하는데, 이를 샤딩이라고 한다.
물론 처리량을 더 받기 위해 서버의 성능을 높이는 방법(스케일 업)도 있으나 이 방법은 한계에 상당이 빨리 이르게 된다.
샤딩을 위해서는 응용 프로그램의 코드를 상당히 많이 변경해야 하므로 서비스가 한번 시작되면 중단하지 않고 샤딩방식으로 변경하기는 매우 어렵다. 즉 처음에 설계 시 샤딩을 고려해서 개발을 진행할지를 거쳐야 한다.
샤딩의 종류
샤딩은 어떤 형태로 파티션할지에 따라서 수평샤딩 또는 수직샤딩으로 구분할 수 있다.
샤딩 종류 | 설명 |
수직 샤딩 | 기능별로 컬렉션을 그룹핑하여 그룹별로 샤드를 할당하는 방식을 의미한다. 샤드 간 부하의 불균형이 자주 발생한다. |
수평 사딩 | 하나의 컬렉션에 저장된 도큐먼트들을 영역별로 파티셔닝해서 1/N 씩 각 샤드가 나눠 가진다. 파티셔닝의 기준이 되는 필드 선정이 매우 중요하며, 이 파티션 키에 따라서 각 샤드의 부하가 균등해질수도 아닐수도 있다. |
MongoDB 샤딩 아키텍처
샤드 클러스터의 가장 중요한 3가지 구성은 샤드 서버와 컨피그 서버 그리고 라우터이다.
하나의 샤드 클러스터에 샤드 서버는 레플리카 셋 형태로 1개 이상 존재할 수 있으며, 라우터 서버도 1개 이상 존재할 수 있다.
하지만 컨피그 서버는 하나의 샤드 클러스터에 단 하나의 레플리카 셋만 존재할 수 있다.
샤드 클러스터 컴포넌트
라우터 : 영구적인 데이터를 가지지 않으며 사용자의 쿼리 요청을 어떤 샤드로 전달할지 정하고 각 샤드로부터 받은 쿼리 결과 데이터를 병합해서 사용자에게 되돌려 준다.
또 각 샤드가 균등하게 데이터를 가지고 있는지 모니터링하면서 데이터의 밸런싱 작업도 담당한다.
컨피그 서버 : 샤드 서버에 저장된 사용자 데이터가 어떻게 분산되어 있는지에 관한 메타 저보를 저장한다.
샤드 서버 : 실제 사용자의 데이터를 저장한다.
샤드 클러스터의 쿼리 수행 절차
컨피그 서버는 샤드 클러스터에서 사용자가 생성한 데이터베이스와 컬렉션들의 목록을 관리한다.
그러나 모든 목록을 관리하는 것은 아니고 샤딩이 활성화된 데이터베이스, 컬렉션의 정보만 관리한다.
샤딩이 되지 않는 객체들은 컨피그 서버가 아니라 각 샤드 서버가 로컬로 관리한다.
그리고 각 컬렉션이 여러 샤드 서버로 분산될 수 있게 분산하기 위한 정보를 관리한다.
이렇게 큰 컬렉션을 여러 조각으로 파티션하고 그 조각을 여러 샤드 서버에 분산해서 저장한다.
이런 각 데이터 조각을 MongoDB 에서는 청크라고 표현한다.
사용자 쿼리 요청 시 라우터 과정
1. 샤용자 쿼리가 참조하는 컬렉션의 청크 메타 정보를 컨피그 서버로부터 가져와서 라우터의 메모리에 캐시
2. 사용자 쿼리의 조건에서 샤딩 키 조건을 찾음
2-1. 쿼리 조건에 샤딩 키가 있으면 해당 샤딩 키가 포함된 청크 정보를 라우터의 캐시에서 검색하여 해당 샤드 서버로만 사용자 쿼리를 요청
2-2. 쿼리 조건에 샤딩 키가 없으면 모든 샤드 서버로 사용자의 쿼리 요청
3. 쿼리를 전송한 대상 샤드 서버로부터 쿼리 결과가 도착하면 결과를 병합하여 사용자에게 쿼리 결과를 반환
이 때 1번 과정은 라우터가 청크 메타 정보를 가지고 있지 않거나, 라우터가 가진 청크 메타 정보가 오래되어서 맞지 않을 때에만 수행된다.
컨피그 서버
컨피그 서버는 샤딩된 클러스터를 운영하는데 있어 필요한 모든 정보를 저장한다.
컨피그 서버의 데이터는 컨피그 서버로 직접 로그인해서 확인할 수도 있지만, 라우터(mongos) 를 이용해서 클러스터에 로그인한 다음 config 데이터베이스로 이동하면 필요한 데이터를 조회할 수 있다.
즉 라우터(mongos) 의 config 데이터베이스는 샤드 서버가 아니라 컨피그 서버로 접속해서 결과를 가져오며
이 외는 모든 사용자 데이터베이스와 컬렉션은 샤드 서버로 쿼리를 요청한다.
컨피그 서버는 버전에 따라 조금씩 차이가 있찌만 대부분 아래 컬렉션을 가지고 있다.
config DB 컬렉션 | 설명 |
databases | 샤드 클러스터가 가지고 있는 데이터베이스 목록을 관리 |
collections | 샤드 클러스터가 가지고 있는 컬렉션의 목록을 관리 |
chunks | 샤딩된 컬렉션의 모든 청크 정보를 관리 |
shards | 샤드 클러스터에 등록된 모든 샤드 서버의 정보를 레플리카 셋 단위로 관리 |
mongos | 현재 컨피그 서버와 한 번이라도 연결했던 모든 mongos 의 목록을 저장 |
settings | 청크의 밸런싱과 관련된 작업의 설정이 저장 |
version | 컨피그 서버가 가지고 있는 샤드 클러스터의 메타 데이터 전체에 대한 버전 정보가 저장 |
lockpings | 어떤 멤버가 언제 연결 상태를 확인했는지를 저장 |
locks | 많은 샤드 서버, 라우터 멤버들이 서로의 작업을 동기화하면서 처리하는데 이 때 같은 작업을 동시에 시작하면서 충돌이 발생할 수 있다. 따라서 각 멤버들은 컨피그 서버의 locks 컬렉션을 이용해서 이런 작업들을 동기화해서 처리하게 된다. 이런 충돌을 막으려면 반드시 컨피그 서버의 lcosk 컬렉션에서 잠금을 획득한 후에 진행한다. * 3.4 버전부터는 동시에 여러 개의 청크를 하번에 이동시킬 수 있게 병렬 청크 이동 기능이 추가 |
changelog | 컨피그 서버의 메타 정보 변경을 유발한 이벤트에 관해 정보성 이력을 관리 |
컨피그 서버의 복제 방식
컨피그 서버는 샤딩이 활성화된 유저 데이커베이스와 컬렉션의 정보 그리고 각 컬렉션이 가지는 수많은 청크에 대한 메타 정보를 가지고 있다.
클러스터 메타 정보는 사용자 데이터의 일관성을 유지하기 위한 매우 중요한 정보로 반드시 3대 이상으로 복제할 것을 권장한다.
3.2 이전 버전까지는 컨피그 서버가 미러링 된 형태의 데이터 복제 방식을 사용했다.
그러나 3.2 버전부터는 사용자 데이터와 동일하게 레플리카 셋으로 배포하는 방법을 제공하고 설치 시 기본적으로 레플리카 셋 형태의 컨피그 서버를 사용한다.
미러링 된 형태의 컨피그 서버 방식을 SCCC ( Sync Cluster Connection Config ), 레플리카 셋 형태의 컨피그 서버 방식을 CSRS ( Config Servers as Replica Sets ) 라고 한다.
SCCC
미러링 방식으로 컨피그 서버의 데이터를 동기하 하는 방식이다.
미러링 방식이란 서로 전혀 관계 없이 작동하는 컨피그 서버 3대를 각각 따로 설치하고 응용 프로그램에서 3대의 컨피그 서버에 모두 접속하여 각 서버의 데이터를 동기화하는 방식을 말한다.
여기에서 응용 프로그램은 컨피그 서버의 클라이언트인 MongoDB 서버와 라우터서버를 의미한다.
SCCC 방식에서는 라우터 서버가 청크 정보를 변경하고자 할 때, 3개의 컨피그 서버에 접속하여 청크 정보를 변경(UPDATE)하는 문장을 각각 실행하고, 모두 성공적으로 완료되면 커밋을 수행하는 분산 트랜잭션을 실행하는 방식으로 처리된다.
하지만 이런 분산 트랜잭션 처리 방식은 컨피그 서버의 데이터가 복잡해지고, 변경 쿼리가 복잡해질수록 구현이 어려워짐과 동시에 동기화 문제들을 자주 유발시키는 원인이 된다.
이러한 이유로 3.4 버전부터는 SCCC 방식의 컨피그 서버 구성은 완전히 없어졌다.
CSRS
3.4 버전부터 일반 사용자 데이터를 저장하는 샤드 서버처럼 레플리카 셋으로 구현할 수 있도록 개선되었다.
레플리카 셋으로 컨피그 서버를 구축해야 하는 경우 아래 조건을 만족해야 한다.
- 컨피그 서버는 반드시 WiredTiger 엔진을 사용해야 한다.
- 레플리카 셋은 아비터를 가질 수 없다.
- 레플리카 셋은 지연된 멤버를 가질 수 없다.
- 최소 3개 이상의 멤버로 구성하는걸 매우 권장한다.
레플리카 셋 방식으로 구축된 컨피그 서버는 클라이언트가 더 이상 모든 멤버에게 직접 접속하여 쿼리를 실행하지 않는다.
클라이언트는 컨피그 서버의 프라이머리 멤버로 접속하여 쿼리를 실행하는데 Read / Write Concern 레벨을 majority 로 설정하여 실행한다.
이는 레플리카 셋의 프라이머리 멤버가 일시적인 장애로 복구됐을 때 롤백되는 데이터가 발생하지 않기 위해서이다.
컨피그 서버 가용성과 쿼리 실행
컨피그 서버로 투입할 수 있는 멤버의 수는 컨피그 서버의 구성 방식에 따라 달라진다.
미러링 서버의 컨피그 서버의 수는 반드시 1대 또는 3대만 허용되는데 소스 코드 상에 고정된 상숫값이다.
레플리카 셋 방식의 컨피그 서버에서의 수는 일반적인 레플리카 셋 구성에 필요한 멤버의 수와 같다.
레플리카 셋 방식의 컨피그 서버에서는 모든 메타 정보 조회 및 변경 쿼리의 경우 Concern 이 majority 인데 이는 전체 레플리카 셋 멤버의 과반수에 접근할 수 있어야만 쿼리를 수행할 수 있다는 것을 의미한다.
그래서 컨피그 서버가 2대일때는 멤버 중 하나만 연결되지 않아도 메타 정보 조회와 삭제를 할 수없다.
다만 컨피그 서버가 항상 필요한 것은 아니다.
모든 사용자 쿼리는 라우트(mongos) 를 통해 처리되는데, 라우터 서버는 처음 기동될 때 컨피그 서버의 메타 정보를 일괄적으로 로드해서 자신의 캐시 메모리에 적재해둔다.
그리고 새로운 멤버나 컬렉션이 추가/삭제, 청크의 분리 이동 시점에만 라우터 서버가 컨피그 서버에 데이터 변경 쿼리를 실행한다.
그러나 이 때 컬렉션이 샤딩되지 않는 경우 실제 청크 변화가 없기에 컨피그 서버의 메타 데이터 변경을 필요로 하지 않는다.
컨피그 서버의 데이터를 변경하는 경우
- 청크 마이그레이션 실행 시
- 청크 스플릿 실행 시
컨피그 서버의 데이터를 조회하는 경우
- 라우터 서버가 새로 시작되는 경우
- 컨피그 서버의 메타 데이터가 변경된 경우
- 사용자 인증 처리 시
MongoDB 3.0 버전 이후로 샤딩된 MongoDB 서버에서 사용자의 인증 정보는 컨피그 서버에 저장되며,
이 정보를 읽을 수가 없으면 라우터는 MongoDB 서버로 새로운 커넥션을 생성할 수 없다.
즉 컨피그 서버가 응답이 없으면 이미 생성된 커넥션은 괜찮지만 신규 커넥션은 더 이상 열 수 없는 것이다.
이는 실제 서비스 상황에서 장애 상황이 될 수 있고, 이러한 이유로 MongoDB 3.2 버전의 메뉴얼에서는 컨피그 서버가 모두 응답 불능 상황이 되면 클러스터도 서비스 불가한 상황이 된다.
라우터
라우터 역할은 다음과 같다.
- 사용자 쿼리를 전달해야 할 샤드 서버를 결정하고 해당 샤드로 쿼리 전송
- 샤드 서버로부터 반환된 결과를 조합하여 사용자에게 결과 반환
- 샤드간 청크 밸런싱 및 청크 스플릿 수행
라우터 서버는 샤드 서버로부터 받은 결과를 병합하여 사용자에게 주기도 하지만, 각 샤드가 내려준 결과가 실제 그 샤드 서버가 가지지 말아야 할 데이터인지 판단하고 가지지 말아야 할 데이터라면 데이터를 제거하는 작업도 수행한다.
가지지 말아야 할 데이터는 청크 마이그레이션 중이거나, 청크 마이그레이션 도중 실패하거나, 사용자가 각 샤드로 접속하여 강제로 샤드키에 맞지 않는 데이터를 저장하는 경우에 발생할 수 있는데, 이런 필터링을 처리하지 않으면 중복된 데이터나 삭제된 데이터가 사용자에게 반환될 수 있다.
라우터의 쿼리 분산
사용자의 쿼리를 샤드 서버로 전달할 때, 쿼리의 조건을 기준으로 특정 샤드에 쿼리를 요청할 것인지 전체 샤드로 요청할 것인지 판단하는 것도 라우터의 중요한 역할 중 하나이다.
라우터가 사용자의 쿼리를 특정 샤드로만 요청하는 형태를 타겟 쿼리
모든 샤드서버로 요청하는 경우를 브로드캐스트 쿼리라고 한다.
소량의 도큐먼트를 아주 빈번하게 읽어가는 쿼리를 처리하는 서버에서는 타겟 쿼리가 효율적이지만,
아주 많은 도큐먼트를 한 번에 읽는 쿼리가 가끔 실행되는 서버에서는 타겟 쿼리보다 브로드캐스트 쿼리가 서버의 자원을 더 효율적으로 사용할 수 있다.
타겟 쿼리
샤드 키 조건을 가진 사용자 쿼리에 대해 라우터는 조건을 분석해서 쿼리가 원하는 데이터가 있는 샤드 서버들을 제한할 수 있다.
브로드퀘스트 쿼리
샤드 키를 쿼리 조건으로 가지지 않는 경우에는 라우터가 작업 범위를 특정 샤드로 줄일 수가 없다.
이런 경우 라우터는 쿼리를 모든 샤드로 요청해야 하고, 모든 샤드로부터 반환된 결과를 병합해서 사용자에게 반환해야 한다.
그런데 어떤 쿼리는 샤드 키를 어떻게가지든 무관하게 항상 브로드캐스트 쿼리방식으로만 처리되기도 한다.
- 다중 업데이트 : 업데이트 대상 검색 조건에 샤드 키를 포함하든 그렇지 않든 항상 브로드캐스트 쿼리로 실행된다.
- UpdateMany() , DeleteMany() : 업데이트 대상 검색 조건이 반드시 샤드 키를 모두 포함하는 경우에만 타겟 쿼리로 실행될 수 있다. 복합 필드를 샤드 키로 가지는 컬렉션에서 일부 샤드 키만 사용하는 경우 브로드캐스트로 처리된다.
라우터 배포
MongoDB 라우터는 N 개이상의 클라이언트와 연결을 맺고, 그와 동시에 샤드 서버와 연결을 맺는 서버이다.
라우터는 샤드 서버가 새로 추가되면 자동으로 그 샤드 서버와 커넥션을 연결하므로 라우터 서버와 샤드 서버 간의 커넥션 개수는 많아질 수 있다.
응용 프로그램 서버와 함께 라우터 배포
응용 프로그램 서버에 MongoDB 라우터를 같이 실행하는 방법으로, MongoDB 매뉴얼에서 권장하는 가장 일반적인 형태의 배포 방식이다.
이 형태는 각 응용 프로그램 서버에서 실행 중인 라우터는 로컬 서버에서 실행 중인 응용 프로그램 서버로부터의 연결만 처리하는 것이다.
일반적으로 MongoDB 라우터는 많은 시스템 자원을 사용하지 않도록 설계되었기 떄문에 응용 프로그램 서버가 많은 메모리와 CPU 를 사용한다고 해도 라우터가 미치는 영향은 미미하다고 볼 수 있다.
메뉴얼에서 권장하는 일반적인 형태이지만 이 배포 형태에 전혀 문제가 없지는 않다.
응용 프로그램 서버의 대수가 늘어나면 늘어날수록 MongoDB 샤드 서버 입장에서는 커넥션 개수가 ㄴ르어난다.
응용 프로그램 서버가 100대가 있고, 각 라우터가 샤드와 30개 정도의 커넥션을 가진다고 가정하면 모든 샤드 서버는 3000 개 정도의 연결을 처리해야 한다.
또한 샤드의 처리가 조금만 지연되어도 커넥션이 순식간에 1~2만개도 증가할 수 있다.
전용의 라우터 서버 배포
위의 이유로 MongoDB 라우터를 전용 서버에서 실행하고 응용 프로그램은 하나 이상의 MongoDB 라우터 서버로 접속하여 쿼리를 실행하는 방법을 고려한다.
이런 형태는 응용 프로그램 서버 수만큼 라우터가 실행되지 않으므로 샤드 서버와의 커넥션도 줄어들 것이다.
이 때 응용 프로그램은 드라이버의 연결부분에 모든 라우터 주소를 명시해야 한다.
이는 MongoDB 에서 추천하는 방식은 아니다.
이 방식에서는 라우터간에 부하를 적절하게 분산해야 하며, 문제가 발생한 라우테에 대해 요청을 중지하고 라우터가 되살아났을 때 요청을 다시 전달해야하는 등의 문제점이 있다.
최근 Atlas 서비스는 MongoDB 라우터를 샤드 서버와 컨피그 서버에 배포하고, 응용 프로그램은 클라이언트 드라이버에 이 라우터 목록을 설정해서 사용하도록 배포하고 있다.
L4 와 함께 라우터 배포
MongoDB 라우터가 많을 때에는 응용 프로그램의 MongoDB 드라이버에서 모든 MongoDB 라우터를 명시하기가 쉽지 않다. 그래서 MongoDB 라우터를 L4 스위치로 묶어서 사용하는 방법을 고려해볼 수 있다.
하지만 이 방법은 L4 가 추가되면서 네트워크 시간을 길게 만들고, 또 하나의 문제점은 Find 쿼리와 GetMore 명령이 서로 다른 MongoDB 라우터로 요청되는 경우가 발생할 수도 있다.
커서를 예로들면
쿼리가 실행되면 MongoDB 라우터로 쿼리를 전송하고, 쿼리의 결과를 커서로 반환받는다. 이 때 쿼리 결과를 반환하는 것이 아니라 쿼리 결과를 가져올 수 있는 커서를 반환하며, 내부적으로 커서는 커서 Id 로 식별된다.
그래서 쿼리 결과가 필요할 때마다 cursor.next() 함수를 호출해서 결과를 가져오다가 캐시한 결과가 더 없으면 커서 ID 를 이용해 라우터로 다시 결과를 요청한다. 이 때 서로 다른 라우터로 요청하게 되면 에러가 발생한다.
여러 개의 MongoDB 라우터를 L4 스위치로 묶어서 사용하고자 한다면 각 클라이언트 드라이버의 도큐먼트 패치 사이즈를 쿼리에서 조회하는 도큐먼트 수 만큼 크게 설정하거나 드 요청이 같은 MongoDB 라우터로 전송되도록 L4 스위치의 옵션을 조정해야 한다.
샤드 서버나 컨피그 서버와 함께 라우터 배포
MongoDB 라우터를 샤드 서버나 컨피그 서버에 배포할 수도 있다.
라우터는 자원을 많이 사용하지 않기 때문에 크게 문제가 되지는 않는다. 실제 Atlas 서비스(MongoDB 회사)는 이렇게 라우터를 MongoDB 서버가 설치된 서버에 같이 사용하도록 구성하고 있다.
한가지 고려사항은 네트워크 사용량이 적절한지 인데, MongoDB 는 도큐먼트에 많은 데이터를 저장하고 각 도큐먼트는 BSON 포맷이며 네트워크 사용량이 RDBMS 대비 높은 것이 일반적이다.
또한 다른 샤드 서버에 데이터를 조회해야 하고 클라이언트로 결과도 보내야 하기 때문에 네트워크 사용량이 2배까지 될 수도 있다.
이 때 하나의 라우터는 관리자 용도로 생성하여 주로 관리자용 쿼리 및 밸런싱을 위한 MongoDB 라우터를 분리해서 배포하는데, 컨피그 서버가 배포된 서버에 같이 배포하곤 한다. ( 저자 기준 )
* MongoDB 3.4 버전부터는 컨피그 서버가 밸런싱을 처리한다.
관리자가 대용량 덤프나 적재작업을 하는 데에터 MongoDB 라우터가 필요한데, 이를 위해 라우터를 유지하기는 비용적인 문제가 있기에 컨피그 서버의 특정 멤버에 관리자용 라우터를 동시에 할당해서 사용하는 것이 목적이다.
커넥션 풀 관리
라우터는 드라이버와 샤드 서버를 중계하는 역할을 수행하므로 클라이언트와 서버 쪽의 커넥션을 모두 가지고 있어야 한다.
하지만 클라이언트 쪽 커넥션이 서버 쪽 커넥션에 영향을 미치지 않고 독립적으로 관리되기 때문에 커넥션 풀에 유지되는 커넥션의 개수를 제어하기 쉽지 않다.
MongoDB 클라이언트
클라이언트 드라이버를 이용해서 MongoDB 샤드 서버나 라우터로 연결할 때 샤드 서버의 레플리카 셋 목록을 나열할 수도 있고, 라우터를 나열할 수도 있다.
레플리카 셋에 접속할 때 레플리카 셋의 이름이 명시되지 않으면 클라이언트 드라이버는 최초 접속 시에 주어진 서버로만 접속하게 된다.
MongoDB 라우터 - MongoDB 샤드 서버
라우터는 클라이언트와의 커넥션과는 별개로 MongoDB 샤드 서버와의 연결을 맺는다.
즉 클라이언트 연결이 많아진다고 해서, 라우터와 샤드 간의 커넥션도 그만큼 생성되는 것은 아니다.
라우터는 클라이언트로부터 요청되는 쿼리들을 처리하기 위해서 내부적으로 TaskExecutorPool 을 서버의 CPU 코어 개수만큼 준비한다. TaskExecutorPool 은 일반적인 스레드 풀과 동일한 개념으로 이해해도 된다.
그리고 TaskExecutorPool 은 샤드 서버와의 연결 정보를 가지는 커넥션 풀을 하나씩 가지며, 커넥션 풀은 내부적으로 다시 서브 커넥션 풀을 가진다.
여기서 서브 커넥션 풀은 샤드 서버당 하나씩 생성된다.
샤드 서버가 2개이므로 하나의 커넥션 풀은 2개의 서버 커넥션 풀을 가지고 있다. 이 서브 커넥션 풀을 소스 코드에서는 specific-pool 이라고 표현한다.
TaskExecutorPool 은 서버에 장착된 CPU 코어의 개수만큼 설정되는데 개수를 명시적으로 제한하고자 한다면 다음과 같이 서버 설정 파일에서 파라미터를 추가하면 된다.
setParameter :
taskExecutorPoolSize : 4
서브 커넥션 풀(SpecificPool) 은 minConnections, maxConnections hostTimeout 이라는 옵션으로 커넥션 풀의 커넥션을 얼마나 보유할지 결정하는데, 기본값은 min 이 1개 이고 hostTimeout 은 5 분으로 설정된다.
라우터는 각 서브 커넥션 풀에 커넥션이 min 값보다 많으면 자동으로 그 커넥션을 끊어버린다.
그리고 커넥션 풀에 커넥션이 min 보다 적다 하더라도 일정시간 동안 쿼리 요청이 없으면 서브 커넥션 풀 자체를 종료하도록 설계되었는데 이 시간이 hostTimeout 이다.
커넥션이 급증하는 시점은 그만큼 사용자 쿼리의 처리가 지연되고, 클라이언트에서는 쿼리나 큐 타임아웃 현상이 발생할 수 있다.
이런 현상을 막으려면 라우터와 샤드 서버간의 커넥션을 미리 준비해두는 것이 유일한 방법이다.
MongoDB 3.2.11 부터 라우터와 샤드 간의 커넥션을 조정할 수 있는 옵션을 사용자가 직접 변경할 수 있도록 기능이 개선되었다.
이 커넥션을 제어하는 옵션은 아래와 같다.
ShardingTaskExecutorPoolHostTimeoutMS
- 커넥션의 hostTimeout 옵션을 밀리초 단위로 설정하는 옵션
ShardingTaskExecutorPoolMaxSize
ShardingTaskExecutorPoolMinSize
- 서브 커넥션 풀 별로 최소, 최대 커넥션의 개수를 지정하는 옵션
ShardingTaskExecutorPoolRefreshRequirementMS
ShardingTaskExecutorPoolRefreshTimeoutMS
백업 복구 시 주의 사항
샤딩이 적용된 클러스터 멤버에서 백업된 데이터를 복구하는 경우에 주의해야 할 사항이 있다.
세컨드리 멤버에서 LVM 과 같은 스냅샷 도구를 이용해서 데이터 파일을 백업하거나
서버 자체를 셧다운하고 백업해둔 데이터 파일을 이용해서 복구하는 경우
복구된 MongoDB 서버느 ㄴ백업되기 전의 MongoDB 클러스터 컨피그 서버로 접속해서 샤딩 구성을 복구하려고 한다.
만약 기존의 멤버를 대체하기 위해 복구하는 경우라면 문제가 없으나
이미 없어진 클러스터이거나 컨피그 서버가 변경되었다면 백업된 데이터 파일을 이용해서 시작된 MongoDB 서버는 시작되지 못하고 기존 컨피그 서버의 응답을 계속 기다리게 된다.
이런경우 MongoDB 시작 옵션에 recoverShardingState 옵션을 false 로 설정하면 기존 컨피그 서버의 응답을 무한대로 대기하는 현상을 회피할 수 있다.
'Database > MongoDB' 카테고리의 다른 글
[MongoDB] 샤딩(3) (0) | 2024.07.22 |
---|---|
[MongoDB] 샤딩(2) (0) | 2024.07.05 |
[MongoDB] 복제(2) (0) | 2024.05.26 |
[MongoDB] 복제 (0) | 2024.05.20 |
[MongoDB] WiredTiger 의 내부 작동방식 (0) | 2024.05.13 |