April 21, 2021
단일 DB서버만으로 성능의 한계에 도달했을 때 비용을 크게 들이지 않고 처리량을 늘리는 방법으로 스케일 아웃을 사용할 수 있다.
스케일 아웃은 일반적인 서버 머신을 여러 대 사용해 응용프로그램으로부터의 부하를 분산하고 서버 수에 따라 처리량을 늘리는 구조다. RDB를 사용하며 부하를 분산해 물리적인 처리 능력의 한계를 높이는 방법이다.
그러나 실제로 처리 능력이 늘어날지는 처리 내용과 구조에 따라 다르다. 이 장에서는 두 가지 대표적인 스케일 아웃을 위한 아키텍처인 복제와 샤드에 대한 설명이다.
리플리케이션은 어떤 RDB 서버에 포함된 데이터를 다른 DB 서버에 복제하는 기술이다. 복제(리플리케이션)의 원본이 되는 DB 서버를 마스터, 복제 대상의 DB 서버를 슬레이브라고 한다.
복제에 걸리는 오버헤드가 적은 구성이라면 한 개의 마스터에서 여러 대의 슬레이브로 매우 짧은 시간에 복제할 수 있다. 즉, 마스터와 슬레이브가 1:N의 관계가 된다.
이 성질을 사용해 참조의 부하를 여러 대의 DB 서버에 분산할 수 있다.
갱신 형 처리는 모두 마스터에서 수행한다. 참조형 처리라도 트랜잭션이 필요한 참조 처리는 마스터에서 수행해야 한다.
응용프로그램이 어떤 슬레이브에 질의할 것인지는 몇가지 방식이 있다.
응용프로그램 서버와 슬레이브가 같다면 응용프로그램이 질의하는 슬레이브는 항상 같은 서버상에서 동작하는 슬레이브가 된다. 응용프로그램 서버와 슬레이브가 다른 서버일 때는 라운드 로빈이나 랜덤으로 연결 대상 슬레이브를 바꾸는 방법이 사용된다.
슬레이브가 마스터 데이터의 완전한 복사본을 갖는다는 것은
슬레이브의 데이터를 마스터와 같은 논리적인 정합성을 유지하면서 참조할 수 있다는 의미다.
슬레이브에 질의하는 경우 마스터에서 사용하는 것처럼 쿼리를 작성할 수 있다.
이와 같은 1:N의 리플리케이션은 오버헤드가 큰 동기 리플리케이션을 사용할 수 없으므로 비동기 리플리케이션이 사용된다. 따라서 슬레이브의 데이터가 마스터보다 조금 이전 데이터일 수 있다.
그렇다고 해도 리플리케이션에서 큰 시간 차이는 거의 발생하지 않고 마스터에서 실행되는 트랜잭션의 사이즈를 작게 유지할 수 있다면 마스터와 슬레이브의 시간차는 1초 미만인 경우가 대부분이다.
사용자가 검색 결과를 확인하는 용도로만 사용한다면 이러한 약간의 시간차는 문제가 되지 않는다.
리플리케이션에 의한 스케일 아웃은 이처럼 작은 시간차가 허용될 때만 사용할 수 있으므로 주의해야 한다.
리플리케이션은 참조 처리를 분산할 수 있지만, 갱신 처리는 모두 한 개의 마스터에 집중되고 각 슬레이브는 마스터와 같은 양의 갱신을 수행해야 하므로 갱신 처리가 병목이 되기 쉽다.
샤딩은 행별로 데이터의 저장 위치를 변경하는 구조다. 파티셔닝의 수평 분할과 비슷하지만, 데이터의 저장 대상이 각 DB 서버가 된다는 점이다. 전형적인 예로 DB 서버의 인스턴스는 다른 서버에서 동작한다.
각 샤드의 스키마 구조는 같고, 다른 것은 데이터의 내용뿐이다. 응용프로그램은 사용자 ID나 지욕 등에 따라서 데이터의 저장 대상이 되는 샤드를 판단한다.
어떤 샤드에 데이터를 저장해야 하는지 판단하는 로직은 응용프로그램 쪽에서 구현해야 한다.
→ 샤딩을 수행하면 응용프로그램의 로직이 조금 복잡해진다.
응용프로그램의 복잡성에 대한 대가라고 해도 갱신 처리 성능의 물리적인 한계를 넘고자 할 때는 샤딩을 추천한다.
또한, 참조 처리 성능도 확장하고 싶을 때는 샤딩과 리플리케이션을 조합하는 것이 일반적이다.
샤딩을 할 때 가장 큰 문제점은 샤드를 넘나드는 쿼리를 실행할 수 없다는 점이다. 다른 샤드에 존재하는 데이터가 필요할 때는 응용프로그램에서 각 샤드에 질의를 수행해야 한다.
각각 질의하고 끝이라면 그다지 문제가 되지 않지만, 데이터를 결합(Join)하고 싶을 때는 대응할 수 없다. DB 서버가 조인할 수 있는 것은 그 DB 서버 내부의 데이터뿐이다.
→ 물리적으로 다른 DB 서버에 저장된 데이터는 조인할 수 없다.
데이터에 따라 저장 대상 샤드가 다르지만, 각 샤드 자체는 모순이 없고 논리적으로 정합성이 확보된 DB여야 하며샤드 내의 데이터에 모순이 생겨서는 안된다.
→ 샤딩을 적용할 수 있는 것은 한 개의 파티션키로 응용프로그램이 사용하는 테이블의 데이터를 완전하게 나눈 경우에 한다.
스키마의 구조가 복잡할 때는 데이터를 나누기 어려우므로 샤딩을 사용할 수 없는 경우가 많다. 다만 마스터 테이블 같은 것이라면 모든 샤드에 같은 데이터를 복사해 대응 할 수 있다.
샤딩을 사용한다면 샤드는 각각 같은 구조의 스키마를 가지만, 이것이 자동으로 동기화되지 않는다. 스키마 구조를 변경하면 DB 관리자가 모든 샤드에 대해 적용해야 한다. 이처럼 관리를 위한 오버헤드가 늘어나는 것도 샤드의 단점이라고 할 수 있다.
캐시는 구현에 의한 데이터 구조다. 논리 데이터에 대한 쿼리는 가져올 데이터가 너무 많거나 데이터 구조가 복잡하여 빠르게 엑세스 할 수 있는 데이터가 필요할 때, 이러한 실행을 빠르게 수행하기 위해서 활용한다.
캐시와 인덱스 모두 대상 데이터에 빠르게 엑세스 하기 위해 논리 데이터와는 별도로 구조화된 데이터를 추가한다. RDB에서 사용할 수 있는 인덱스보다 복잡한 데이터 구조를 필요로 할 때는 캐시라는 개념이 도움이 된다.