당신의 확장 가능한 백엔드는 시한폭탄인가요?
많은 개발자들은 확장이란 단순히 서버를 더 추가하는 것이라고 생각합니다. 더 많은 사용자를 처리하기 위해 클라우드 네이티브 도구와 분산 데이터베이스를 사용하죠. 하지만 이는 종종 새로운 문제를 야기합니다. 당신은 요새를 짓고 있는 것이 아니라, 사상누각(house of cards)을 짓고 있는 것일지도 모릅니다.
계획 없는 수평적 확장(Horizontal Scaling)은 단지 장애 범위(failure domains)를 넓힐 뿐입니다. 시스템에 결함 허용(fault tolerance) 기능이 없다면, 작은 오류 하나가 전체 시스템을 무너뜨릴 수 있습니다.
진정한 시스템을 구축하려면 다음 두 가지 영역에 집중해야 합니다:
- 결함 허용 (Fault Tolerance) 인스턴스를 더 많이 추가한다고 해서 상관관계가 있는 장애(correlated failures)를 방지할 수 있는 것은 아닙니다. 장애가 확산되지 않도록 격리해야 합니다.
- 여러 가용 영역(Availability Zones)을 사용하세요.
- 큰 인스턴스 두 개를 사용하는 대신, 작은 서비스 인스턴스들을 분산시키세요.
- Raft 또는 Paxos와 같은 쿼럼 기반 합의(quorum-based consensus) 알고리즘을 사용하세요. 이는 두 리전이 모두 자신을 리더라고 생각하는 스플릿 브레인(split-brain) 시나리오를 방지합니다.
- 네트워크 분할(network split) 발생 시 결함이 있는 리전을 차단할 수 있도록 펜싱(fencing) 메커니즘을 사용하세요.
- 데이터 일관성 (Data Consistency) 최종 일관성(Eventual consistency)은 속도 측면에서는 훌륭하지만, 중요한 비즈니스 로직에는 치명적입니다. 결제나 계좌 잔액 관리와 같은 작업에는 강력한 일관성(strong consistency)이 필요합니다.
- 시스템 속도를 저하시키는 분산 트랜잭션에 의존하지 마세요.
- 트랜잭셔널 아웃박스 패턴(Transactional Outbox Pattern)을 사용하세요.
- 메인 데이터와 "아웃박스" 작업을 하나의 로컬 데이터베이스 트랜잭션으로 작성하세요.
- 릴레이어(relayer)를 사용하여 해당 작업을 메시지 큐로 전송하세요.
- 다운스트림 서비스가 중복 메시지를 안전하게 처리할 수 있도록 멱등성(idempotent)을 보장하세요.
진정한 확장성은 회복 탄력성(resilience)에 관한 것입니다. 이러한 원칙을 무시한다면, 당신은 그저 장애가 발생하기 더 좋은 거대한 놀이터를 만들고 있을 뿐입니다. 오늘부터 최악의 시나리오를 고려하여 설계하세요.
출처: https://dev.to/prabashanadev/is-your-scalable-backend-a-ticking-time-bomb-6o7