[인프라] 최적의 서버 확장 전략: 스케일 아웃 & 스케일 업

dakcoh·2024년 8월 15일


이번 포스트에서는 서버를 확장할 때 고려할 수 있는 전략으로
스케일 업, 스케일 아웃에 대해 자세히 다뤄보려고 합니다.

각각의 전략이 무엇인지, 언제 사용하면 좋은지 그리고 실전에서 어떻게 적용할 수 있는지 코드 예시와 함께 공부해보겠습니다.

스케일 업 (Scale-Up)

스케일 업은 서버 한 대의 성능을 높이는 방식입니다.
즉, CPU나 메모리(RAM)를 업그레이드해서 서버가 더 많은 요청을 처리를 할 수 있습니다.

간단하게 하드웨어 성능을 개선하면 되기 때문에 적용이 쉬운 편이지만, 물리적인 한계에 도달하면 더 이상 확장이 불가능하다는 천장이 존재합니다.

언제 스케일 업을 사용해야 할까?

1. 단일 애플리케이션에서 성능 병목이 발생할 때
2. 데이터베이스 서버캐시 서버처럼 복잡한 로드밸런싱이 어려운 경우
3. 성능 향상이 즉시 필요할 때 (빠른 성능 개선이 가능)

스케일 업의 장점

  • 적용이 쉽고 빠름: 서버 자체만 업그레이드하면 되기 때문에 복잡한 설정이 필요 없습니다.
  • 애플리케이션 수정 필요 없음: 코드나 아키텍처를 수정하지 않고도 서버 성능을 높일 수 있습니다.

스케일 업의 단점

  • 비용 급증: 고성능 하드웨어는 매우 비쌀 수가 있습니다.
  • 물리적 한계: 하드웨어 성능에는 한계가 있기 때문에 결국 무한 확장은 불가능합니다.

스케일 업 예제: JVM 메모리 설정

Java 애플리케이션의 메모리 관리를 최적화하기 위해 JVM 힙 크기를 조정할 수 있습니다.
이를 통해 서버의 메모리 용량이 늘어났을 때 더 효율적으로 리소스를 활용할 수 있습니다.

# 메모리 설정 예시
java -Xms1024m -Xmx4096m -jar app.jar

위 코드에서 -Xms는 초기 힙 크기, -Xmx는 최대 힙 크기를 설정하는 옵션입니다.
여기서는 1GB의 초기 힙 메모리와 4GB의 최대 힙 메모리를 설정하여 서버 메모리 리소스를 효율적으로 사용할 수 있도록 했습니다.

Scale-Up 주의사항
JVM 메모리 설정은 무조건 많이 할당한다고 좋은 게 아닙니다.
충분한 메모리 모니터링 후 적절한 크기로 설정하는 것이 성능에 더 긍정적입니다.


스케일 아웃 (Scale-Out)

스케일 아웃은 서버 대수를 늘리는 방법입니다.
즉, 여러 대의 서버가 동일한 애플리케이션을 실행하여 트래픽을 분산시켜주는 전략입니다.

이 방법은 특히 무한에 가까운 확장성을 제공하기 때문에, 대규모 트래픽을 처리해야 하는 서비스에 적합합니다.

한 서버에 모든 요청이 집중되지 않도록, 여러 서버가 동일한 애플리케이션을 실행하고 로드밸런싱을 통해 트래픽을 분산시켜 줍니다.

언제 스케일 아웃을 사용해야 할까?

1. 트래픽이 계속해서 증가하는 경우
2. 다중 서버를 이용해 안정성을 강화하고자 할 때
3. 장기적인 확장성을 고려할 때 (성능의 물리적 한계가 없기 때문에 확장 가능성이 크다)

스케일 아웃의 장점

  • 이론상 무한한 확장성: 여러 대의 서버를 병렬로 추가할 수 있어 트래픽 증가에 유연하게 대응할 수 있습니다.
  • 고가용성: 한 서버가 다운되더라도 나머지 서버가 서비스를 유지하므로 안정성이 높습니다.

스케일 아웃의 단점

  • 복잡한 아키텍처 필요: 여러 서버에서 동일한 데이터를 공유해야 하는 경우, 데이터 동기화나 세션 관리 문제가 생길 수 있습니다.
  • 네트워크 설정 및 유지보수: 서버 간 통신을 관리해야 하기 때문에 네트워크 설정이 복잡해질 수 있습니다.

스케일 아웃 예제: Spring Cloud와 로드밸런싱

스케일 아웃에서 중요한 점은 애플리케이션 간의 세션 관리데이터 동기화입니다.

이를 해결하는 일반적인 방법으로는 세션을 외부에 저장하는 방식과, 로드밸런서를 사용한 트래픽 분산이 있습니다.

예시 1: 세션을 Redis에 저장하여 스케일 아웃 구현

서버 간의 세션을 공유하기 위해서는 Redis와 같은 외부 세션 저장소를 사용할 수 있습니다. 이렇게 하면, 각 서버가 독립적으로 세션을 저장하지 않고도 세션 상태를 유지할 수 있어요.

이번엔 Redis는 간략하게 알아보고, 다음에 자세히 알아보도록 합시다.

1. Spring Boot에서 Redis 세션 저장소 설정

<!-- build.gradle 또는 pom.xml에 Redis 의존성 추가 -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

2. Redis 설정

# application.yml
spring:
  session:
    store-type: redis
  redis:
    host: localhost
    port: 6379

3. Redis 세션을 사용하는 간단한 컨트롤러

@RestController
@RequestMapping("/session")
public class SessionController {

    @GetMapping("/set")
    public String setSession(HttpSession session) {
        session.setAttribute("user", "dakcoh");
        return "Session data set!";
    }

    @GetMapping("/get")
    public String getSession(HttpSession session) {
        return "Hello, " + session.getAttribute("user");
    }
}

Redis는 매우 빠른 속도로 세션을 처리할 수 있습니다.
떄문에 여러 대의 서버가 동일한 세션 상태를 유지해야 하는 환경에 매우 적합합니다.

예시 2: 로드밸런서를 사용한 트래픽 분산

스케일 아웃 시 로드밸런싱을 통해 트래픽을 여러 서버에 고르게 분배하는 것이 핵심입니다.

스프링 클라우드에서는 RestTemplate@LoadBalanced 애너테이션을 사용해 클라이언트 측 로드밸런싱을 쉽게 구현할 수 있습니다.

1. 스프링 클라우드에서 로드밸런싱 설정

# application.yml
spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: true

2. 클라이언트 로드밸런싱 사용

@RestController
public class MyController {

    @Autowired
    @LoadBalanced
    private RestTemplate restTemplate;

    @GetMapping("/invoke")
    public String invokeService() {
        return restTemplate.getForObject("http://my-service/endpoint", String.class);
    }
}

위 코드는 my-service라는 이름의 서비스에 요청을 보낼 때, 여러 서버 중 하나로 분배해주는 로드밸런싱 로직을 구현한 예시입니다.

클라우드 환경에서는
AWS Elastic Load Balancer(ELB)나 GCP Load Balancer 같은 서비스를 사용하면, 서버 추가 및 관리가 더 쉬워집니다.
또한 클라우드 로드밸런서와 함께 오토스케일링(Auto Scaling)을 설정하면 트래픽 증가에 따라 서버 인스턴스가 자동으로 추가되며 스케일 아웃이 유연하게 가능합니다.


스케일 업 vs 스케일 아웃: 선택 기준

스케일 업이 적합한 상황

  • 애플리케이션이 CPU, 메모리 등 단일 하드웨어 리소스에 크게 의존하는 경우
  • 데이터베이스 서버처럼 스케일 아웃이 복잡한 환경에서 성능 향상이 필요할 때
  • 단기적인 성능 향상이 필요한 경우

스케일 아웃이 적합한 상황

  • 트래픽이 지속적으로 증가하고, 수평 확장이 필요한 경우
  • 고가용성을 유지해야 하는 시스템에서 서버 다운타임을 줄이고자 할 때
  • 복잡한 연산보다는 다수의 클라이언트 요청을 처리하는 API 서비스

마무리

서버 확장 전략에서 스케일 업과 스케일 아웃은 각각의 강점과 한계를 가지고 있습니다.

Java 애플리케이션에서 스케일 업은 성능 병목을 하드웨어 업그레이드로 빠르게 해결할 수 있는 반면, 스케일 아웃은 더 큰 확장성과 고가용성을 제공합니다.

다음은 스케일 아웃을 통한 트래픽 분산대용량 데이터 처리에 대해서 공부해보려고 합니다.
또, 스케일 아웃을 공부하며 로드밸런싱에 대해 같이 진행해보겠습니다.

감사합니다.


관련글 > [인프라] 로드밸런싱: NGINX와 Spring을 활용한 서버 확장 전략

profile
포기하기 금지

0개의 댓글