MSA 환경에서 데이터베이스 중앙 관리하기 [Flyway]


개요

Spring JPA는 Entity 정의를 기반으로 데이터베이스 테이블 구조를 자동으로 생성하거나 변경할 수 있다.
단일 서비스, 단일 데이터베이스 환경에서는 이 방식이 개발 속도를 높여주는 장점이 있는 것도 사실이다.

하지만 MSA 환경에서는 상황이 달라진다. MSA에서는 여러 서비스에 걸쳐 Entity가 나뉘어 있고,
경우에 따라서는 같은 테이블을 여러 서비스가 참조해야 하는 상황도 있을 수 있다.

이때 테이블 구조의 주도권을 각 서비스의 Spring JPA가 쥐고 있는 구조는 여러 면에서 좋지 않다고 느꼈다.

예를 들어 테이블 명세를 변경해야 할 경우, 특정 서비스의 Entity를 수정해야 하고 동일한 테이블을 사용하는 다른 서비스의 Entity도 함께 수정해야 하며 어떤 서비스가 실제로 테이블 변경의 기준이 되는지 모호해진다.

결국 DB 스키마 변경이 코드 변경에 종속되고, 서비스 간 결합도가 불필요하게 높아지는 문제가 생긴다.
특히 운영 환경에서는 어떤 서비스가 언제 어떤 이유로 테이블을 바꿨는지를 추적하기도 어려워진다.

그래서 Flyway를 사용해서 데이터베이스 테이블을 애플리케이션 코드가 아닌, 중앙에서 명확하게 관리하는 방식을 선택했다.


Flyway를 사용하면 DB 스키마 변경을 SQL 기반으로 명확히 정의할 수 있고 모든 변경 이력이 버전 단위로 기록된다.

현재 운영 중인 서비스에서는 Prisma를 사용하고 있는데, 마이그레이션을 중심으로 스키마를 관리하는 개념이 Flyway와 매우 유사했다.
그래서 개념적으로도 낯설지 않았고, Spring 기반 MSA 환경에서도 충분히 잘 맞는 도구라고 판단했다.

결과적으로 MSA 환경에서 DB 스키마의 주도권을 코드에서 분리하고, 변경 이력을 안전하게 관리할 수 있게 해주는 Spring 진영에서 사용하기에 매우 적합한 도구라고 생각한다.


프로젝트 코드


Flyway Configuration

데이터베이스 연결 정보나 로그 데이터를 저장할 테이블 등 여러 설정을 할 수 있다.

Plaintext
# flyway.conf

flyway.url=jdbc:postgresql://localhost:5432/...
flyway.user=...
flyway.password=...

flyway.locations=filesystem:sql

flyway.table=flyway_schema_history

flyway.validateMigrationNaming=true
flyway.baselineOnMigrate=true

Flyway Convention


Flyway는 파일 이름을 기준으로 버전과 적용 순서를 판단한다.
기본 형식은 다음과 같다.

Plaintext
V<version>__<description>.sql

[Exmaples]
V1__init.sql
V2__create_user_table.sql
V3__add_index_to_order.sql

Flyway는 버전을 기준으로 아직 적용되지 않은 마이그레이션만 순차적으로 실행하며, 이미 적용된 버전은 다시 실행하지 않는다.


Flyway Info

아래 커맨드로 현재 데이터베이스의 마이그레이션 상태를 확인할 수 있다.

Zsh
flyway info

아래와 같은 결과를 볼 수 있다.

변경 사항이 생긴 뒤에는 어떤 파일이 적용될 지 볼 수 있다.


Flyway Migrate

아래 커맨드로 아직 적용되지 않은 마이그레이션을 버전 순서대로 데이터베이스에 적용한다.

Zsh
flyway migrate

Migrate 완료 시 아래와 같이 결과를 볼 수 있다.

Migration 관련 정보는 flyway_schema_history 테이블에 자동으로 저장된다.


이제 데이터베이스의 컨트롤을 Flyway에서 하므로 Entity에서는 어떤 테이블 변경도 일어나면 안 된다.

따라서 application.yml에서 ddl-auto = validate로 설정하여 Entity 정의와 실제 DB 테이블 구조가 일치하는지만 확인하고, 다르면 애플리케이션 실행을 실패시킨다.

YAML
spring:
  jpa:
    hibernate:
      ddl-auto: validate

마무리

이번 글에서는 Flyway를 사용해 데이터베이스 스키마를 코드처럼 버전화하고 중앙에서 관리하는 방법을 정리해보았다.

Spring JPA의 자동 스키마 관리 기능은 분명 편리하지만, MSA 환경에서는 오히려 테이블의 주도권이 애플리케이션 코드로 분산되면서 관리 복잡도와 서비스 간 결합도를 높이는 원인이 될 수 있다.


Flyway를 도입하면 데이터베이스 스키마를 애플리케이션 코드와 분리하여 중앙에서 일관되게 관리할 수 있고, 각 서비스는 스키마 변경에 상관 없이 자신의 역할에만 집중할 수 있다.


또한 마이그레이션 파일을 통해 모든 변경 이력이 명확하게 기록되며, 파일 기반의 Versioning을 통해 데이터베이스 상태를 직관적으로 추적할 수 있다.

결과적으로 Flyway는 MSA 환경에서 데이터베이스를 보다 안정적이고 예측 가능하게 관리할 수 있도록 도와주는 편리한 도구라고 생각한다.

답글 남기기

Dalmeng's Footprints에서 더 알아보기

지금 구독하여 계속 읽고 전체 아카이브에 액세스하세요.

계속 읽기