백엔드 아키텍처 설계시 고려사항
우리가 백엔드 아키텍처를 설계한다고 했을 때 고려해야 할 사항들과 각 상황별로 어떻게 대처하는 것이 좋을까에 대해 대해서 정리했습니다.
하나의 애플리케이션을 운용하기 위해서는 단일 서버라고 한다면, 애플리케이션과 연동되는 DNS, 웹서버, 데이터베이스로 구성할 수 있습니다.
어떤 데이터베이스를 써야 할까요?
데이터베이스의 선택은 서비스에 따라 달라질 것이고, CAP 이론에 따라 가용성, 일관성, 부분 결함을 고려해야 합니다. 가장 중요시하는 성질이 무엇인가에 따라 우리는 데이터베이스를 선택할 수 있습니다. 일관성보다 가용성과 신속함이 우선시 된다면 NoSQL을 사용할 수도 있을 것이고, 일반적으로 우리가 사용하는 RDBMS는 일관성 측면을 좀 더 중시하는 프로그램에서 적합합니다. 경험상 모두가 같은 정보를 확인해야만 하는 경우에서 일관성이 중요하기 때문에 RDBMS를 사용했고, 모든 노드의 데이터가 동일하지 않지만 대용량, 데이터베이스 부하를 줄여야만 하는 경우에는 변동 사항이 별로 없는 경우의 환경의 데이터베이스는 NoSQL을 사용했습니다.
- 가용성: 모든 노드가 정상적인 응답을 해야 하는 경우
- 일관성: 모든 노드가 동일한 데이터를 가지고 있는 경우
- 부분결함 또는 분할 내구성: 네트워크 특성으로 노드 간 통신 장애가 있더라도 동작해야 함
분할 내구성과 가용성은 어떻게 다른가?
분할내구성은 분산 시스템에서 어떤 노드가 실패하더라도 시스템이 계속해서 작동하도록 하는 것을 의미합니다. 이는 시스템의 일부가 실패하더라도 다른 노드가 해당 기능을 계속 수행할 수 있어야 함을 의미합니다. 반면에, 가용성은 시스템이 항상 사용 가능한 상태여야 함을 의미합니다. 즉, 사용자가 시스템에 접속하고 서비스를 이용할 수 있어야 합니다. 따라서, 가용성은 시스템 전체적으로 작동하는 데 필요한 모든 서비스와 기능에 대한 가용성을 의미합니다.
분할내구성은 시스템의 일부가 실패하더라도 시스템이 계속해서 작동할 수 있도록 하는 것을 의미하고, 가용성은 시스템 전체적으로 항상 사용 가능한 상태여야 함을 의미합니다.
하지만, CAP Theorem, 오해와 진실 이라는 글에서는 분할 내구성에 대한 정의가 글마다 다르게 사용되고 있으며, 네트워크 장애가 있을 수 있는지에 대한 사항은 완벽한 프로그램이 없으므로 선택될 수 밖에 없는 사항이라는 점에서 PACELC를 설명하고 있습니다. 장애 상황에서는 A,C가 상충하며 둘 중 하나를 선택해야 하고, 정상 상황에서는 가용성이 아닌 지연(latency)과 일관성 중에 선택해야 하는 것으로 나누고 있습니다. CAP 자체가 분산시스템만의 상황이 아닌 네트워크 상태도 고려해야 한다는 점에서 RDMBS를 CA로 적용하기에는 명확하지 않다는 점을 고려해야 합니다.
서비스 규모의 확장성도 고려해보자
서비스 규모가 커지면 서버를 확장해야 하는 부분도 고려한 설계를 해야 합니다. 수평적 확장은 서버를 추가하는 것, 수직적 확장은 서버의 CPU, Memory를 증설하는 것을 의미합니다.
수평적 확장을 하는 경우에는 서버를 추가하기 때문에 특정 페이지에 접근 고객을 분리하거나 고객별 분리 등 다양한 방법으로 관리가 가능하고, Slave server처럼 서버의 문제가 생겼을 때, Master 서버로서 대체할 수 있는 방안이 되기도 합니다. 수직적 확장은 수평적 확장보다 오히려 비용이 많이 들 수 있으며, 하나의 서버가 더 많은 양을 담당하기 때문에 서버에 문제가 생기면 큰 서비스 장애로 이어질 수 있습니다. 그리고 수직적 확장이 2배가 된 것이 성능 2배 향상으로 이어진다고 볼 수 없다는 단점이 있습니다.
- 대용량 서비스에서는 데이터베이스는 주로 읽기 비중이 높기 때문에 주 데이터베이스 서버와 부 데이터베이스 서버들도 분산해 읽기 연산만을 다루는 데이터베이스 서버를 두어 관리합니다.
- 캐시를 이용합니다. 직접적인 데이터베이스 접근이 없이 자주 사용되는 데이터를 미리 캐싱해놓으면 빠르고 부하를 줄일 수 있다는 장점이 있습니다. 하지만, 캐시와 DB 간의 일관성 문제가 발생할 수 있다는 단점이 있습니다.
CDN의 활용
CDN은 Contents Delivery Network의 약자로, 지리적으로 가까운 프록시 서버로부터 웹 페이지, 이미지, 비디오 등의 콘텐츠를 캐싱하고 사용자 요청에 따라 신속하게 처리될 수 있도록 합니다. CDN 밴더 서비스를 제공하는 업체는 AWS CloudFront, Akamai Technologies, Cloudflare 등이 있습니다.
- AWS CloudFront를 사용하는 방법을 예로 들면, 먼저 AWS CloudFront 콘솔에서 전달 콘텐츠 유형과 콘텐츠 원본을 설정합니다. 기본 캐시 동작을 구성하여 CloudFront가 콘텐츠 요청을 처리하는 방법을 지정하고, SSL 인증서, 가격 등급 및 오류 페이지와 같은 배포 설정을 사용자 정의합니다. 배포가 생성되면 CloudFront에서 제공하는 도메인 이름을 사용하여 콘텐츠에 액세스할 수 있습니다.
트랜잭션과 DB 락 설정
백엔드 설계시 트랜잭션 단위를 어떻게 가지고 갈 것인지는 매우 중요합니다. 불필요하게 트랜잭션 단위가 커지면, 의도치 않은 데드락 현상이 생길수도 있고, 트랜잭션 소요 시간이 길어져 같은 트랜잭션 요청이 과도하게 몰리는 경우 성능이 저하될 수 있습니다. 또 트랜잭션 단위가 작아서 하나의 비지니스 흐름에 여러 트랜잭션이 있어 중간 장애가 발생하면 비즈니스 일부분은 수행된 채로 rollback 처리되는 문제가 발생할 수 있습니다.
데이테베이스 락 설정도 중요합니다. 비관적 락을 사용하면 경쟁상황이 없는 경우에도 불필요하게 락이 생성되기 때문에 성능이 저하될 수 있습니다. 반대로 낙관적 락은 트랜잭션 커밋시 격리 위반을 체크하기 때문에 rollback 처리로 경쟁상황에서 성능이 떨어질 수 있습니다. 따라서 경쟁여부, 락이 걸리는 범위(row, page), 속도 등을 판단해서 적절한 락 설정이 필요합니다.
분산락을 이용하는 방법도 있습니다. 분산락은 여러 서버에서 공유 데이터의 접근을 하나의 컴퓨터만 할 수 있도록 제어하는 방법입니다. 단순히 조회가 많은 애플리케이션이라면, 분산락을 이용해서 접근처리를 하고 RDBMS는 낙관적 락을 이용하는 방법으로 성능 부하를 줄일 수 있습니다.
- 원티드 백엔드 온보딩 챌린지 7월
- CAP Theorem, 오해와 진실
- 레디스를 활용한 분산 락과 안전하고 빠른 락의 구현