티스토리 뷰
[Java] JVM의 체크포인트 생성과 복구를 위한 CRaC(Coordinated Restore at Checkpoint) 프로젝트
망나니개발자 2023. 12. 12. 10:00
1. JVM의 체크포인트 생성과 복구를 위한 CRaC 프로젝트
[ CRaC 프로젝트란? ]
CRaC(Coordinated Restore at Checkpoint) 프로젝트는 실행 중인 Java 인스턴스에 체크포인트(이미지 혹은 스냅샷의 생성)를 생성하고 복구하는 방법을 연구한다. 이 프로젝트의 주요 목표는 자바 프로그램에 체크포인트 생성과 복구를 알리는 새로운 표준이 되는 독립적인 API를 개발하는 것이다.
CRaC은 Azul Systems에서 개발하였으며 AWS Lambda에서 지원했던 기능으로, 현재는 OpenJDK 프로젝트이다. 이는 리눅스(Linux)에서 체크포인트/복원 기능을 구현한 CRIU 프로젝트를 기반으로 하며, 자바 애플리케이션에 맞게 몇 가지 개선 및 조정 사항이 추가되었다.이를 통해 복원 프로세스에 더 많은 제약을 부과하는데, 예를 들어 CRIU가 소켓의 상태를 저장한 다음 연결을 복원할 수 있다면, CRaC은 체크포인트 전에 모든 연결을 닫아야 한다. CRaC는 이러한 제약들을 통해 더욱 안정적인 프로세스를 만들고자 하였다.
[ CRaC 프로젝트의 필요성 ]
CRaC을 사용하면 일시 중지한 시점부터 애플리케이션을 다시 시작할 수 있고, 동일한 스냅샷을 통해 여러 인스턴스에 배포하여 유용하게 사용할 수 있다. 애플리케이션이 상태를 저장하기에 부적합한 상황(사용자 데이터 저장과 같은 작업을 수행하는 경우 등)이라면 이를 취소할 수 있다.
CRaC를 사용하면 애플리케이션이 거의 즉시 최고 성능으로 시작되어 지연 시간을 최소화하고 리소스 소비를 최적화할 수 있다. 따라서 CRaC는 다음과 같은 애플리케이션에 가장 유용할 것이다.
- 짧은 실행
- 잦은 재시작
- 낮은 CPU 제한
- 여러 복제본에 배포
애플리케이션을 이미지로부터 복원하게 되면 start-up 및 warm-up에 의한 문제를 일부 해결할 수 있다. 또한 급격한 트래픽 상승에 대처하는 능력이 훨씬 증가할 것이다. CRaC는 start-up 및 warm-up 시간을 단축하는 AOT 컴파일 등과 달리 JIT 컴파일러를 통해 더 뛰어난 퍼포먼스를 얻을 수 있도록 한다.
[ CRaC 프로젝트와 스프링 프레임워크(Spring) ]
자바 애플리케이션은 스프링 프레임워크와 결합되어 사용된다. 따라서 애플리케이션에 대한 라이프사이클을 관리하는 스프링 프레임워크에서 CRaC을 지원해주어야 한다. 스프링은 스프링 6.1 및 스프링 부트 3.2부터 CRaC을 지원하기 시작하였다. 해당 기능을 스프링 애플리케이션에 적용한다면 다음과 같은 흐름이 될 것이다.
- CRaC이 활성화 된 JDK로 애플리케이션을 실행함
- 애플리케이션이 실행되고, JVM을 웜업하는 작업 등이 수행됨
- API 호출, jcmd 명령, HTTP 엔드포인트 등의 방법으로 특정 시점에 체크포인트를 트리거함
여기서 주목할 부분은 체크포인트와 복원 시점이 스프링 애플리케이션 컨텍스트 라이프사이클의 중지 및 시작 단계와 매우 잘 일치한다는 점이다. 스프링 프레임워크의 CRaC 지원은 주로 CRaC과 스프링 라이프사이클을 매핑에 관한 것이며, 나머지는 CRaC와 관련이 없고 주로 소켓, 파일 및 풀을 적절하게 닫고 다시 생성하도록 설계된 스프링의 라이프사이클 개선에 관한 것이다. 결국 목표는 애플리케이션의 정기적인 시작 및 중지 라이프사이클 외에도 특점 시점에 중지 및 재시작 주기를 지원하는 것이다.
[ CRaC의 문제와 한계 ]
CRaC이 갖는 한계 또는 문제도 존재한다.
- 체크포인트 시점에 대한 문제
- CRaC을 아직 지원하지 않는 기술들
- 민감한 정보가 저장되는 문제
첫 번째는 CRaC을 사용하려면 체크포인트를 생성하기 위한 애플리케이션이 미리 시작된 상태로 존재해야 한다는 것이다. 해당 애플리케이션은 이미 JIT 컴파일러 등에 의한 최적화가 어느 정도 된 상태여야 한다. 따라서 체크포인트를 어느 시점에 생성하고 사용할 것인지에 대한 질문이 제기될 수 있다.
두 번째는 소켓, 파일 및 풀과 관련된 모든 기능을 종류한 후에 CRaC 라이프사이클에 따라 해당 리소스를 적절하게 다시 생성해야 한다는 점이 있다. 스프링부트는 지원되는 범위 내에서 이 작업을 자동으로 처리한다. 하지만 일부 라이브러리는 이를 아직 지원하지 않아서 모든 기술들이 이를 지원하기까지 시간이 걸릴 수 있다.
마지막으로 가장 까다로운 문제는 체크포인트 시작 중에 메모리에 로드된 모든 비밀이 스냅샷 파일에 직렬화되어 데이터베이스 비밀번호와 같은 잠재적으로 민감한 정보가 유출될 수 있다는 점이다. CRaC는 자바 힙, 네이티브 메모리, JIT 컴파일 코드, 설정 등에 대한 정보와 함께 특정 시점에 실행중인 애플리케이션의 정확한 상태를 보장하는 stateful한 접근법을 갖는다. 따라서 민감한 데이터가 포함될 수 있으므로 이러한 부분에 주의해야 한다.
이에 대한 잠재적인 해결책은 프로덕션 환경 구성 없이 체크포인트 시작을 수행하고 복원 시점에 애플리케이션 구성을 업데이트하는 것이다. 이 작업은 Spring 클라우드 컨텍스트와 @RefreshScope 어노테이션을 사용하여 수행할 수 있다. 스프링 팀은 이에 대한 기본 제공 지원 역시 탐색해볼 것이다. 또한 암호화된 볼륨에 스냅샷 파일을 생성하고 저장하는 전략을 채택하여 Kubernetes 플랫폼에 직접 저장할 수도 있다.
지금은 프로젝트 CRaC의 초기 단계이며, Spring Boot 3.2는 이를 지원하는 첫 번째 릴리스이다. 이러한 제한 사항 중 일부는 Spring의 지원과 함께 체크포인트 복원 기술이 발전함에 따라 해결될 수 있다.
참고 자료
- https://spring.io/blog/2023/10/16/runtime-efficiency-with-spring
- https://wiki.openjdk.org/display/crac/Main
- https://bell-sw.com/blog/bellsoft-releases-liberica-jdk-lts-17-and-21-with-coordinated-restore-at-checkpoint-crac-for-fast-startup/
- https://github.com/sdeleuze/spring-boot-crac-demo
'Java & Kotlin' 카테고리의 다른 글
[Java] 자바는 Call By Value(Pass By Value) 방식으로만 동작한다 (12) | 2024.01.09 |
---|---|
[Java] 언제 추상 클래스(Abstract Class) 또는 인터페이스(Interface)를 사용해야 하는가? (6) | 2023.12.19 |
[Java] 기존 자바 스레드 모델의 한계와 자바 21의 가상 스레드(Virtual Thread)의 도입 (10) | 2023.09.26 |
[Java] Java 21에 추가될 새로운 기능들(Java 21 Features) (22) | 2023.09.19 |
[Java] GraalVM이 제공하는 네이티브 이미지(Native Image) (4) | 2023.07.18 |