우테코 레벨2의 미션을 수행하면서 로컬 DB로 H2를 사용하게 되었는데, 신기한 점이 있어 기록해보고자 한다.
H2는 DB를 작동시키지 않아도 사용이 가능했던 것이다.
위 코드는 실제로 DB에 접근하는 통합 테스트인데,
로컬에 H2 DB 서버를 설치하지도 실행시키지도 않은 상황에서도 정상적으로 작동한다.
어떻게 그럴 수 있는 지에 대해서 H2 DB의 3가지 모드를 살펴보면서 알아보겠다.
H2 DB의 3가지 Connection Mode
H2는 다른 DB와 다르게 3가지 연결 모드를 가지고 있다는 특징이 있다.
H2 DB는 위와 같이 3가지 모드가 있는데
그 중 Embedded Mode 와 Mixed Mode 는 H2 DB 를 설치해서 서버를 실행할 필요없이
스프링부트에서 h2db 의존성만 build.gradle에 추가해주면
그 의존성만으로 DB를 사용할 수 있었다.
나는 Embedded Mode를 사용하고 있었기 때문에 DB 설치 및 DB 서버 실행 과정을 거치지 않고 H2 DB를 사용할 수 있었던 것이다.
그럼 이 3가지 모드가 각각 어떤 특징이 있고 어떻게 동작하는지에 대해서 한 번 살펴보자
임베디드 모드 (Embedded Mode)
임베디드 모드는 JDBC를 사용하여, JVM 내에 DB를 열게 된다.
Embedded Mode를 사용하면 DB 서버를 실행시키지 않고도 데이터베이스 연결 및 사용이 가능하다.
Embedded Mode의 장단점
장점
- H2가 제공하는 모드들 중에 가장 빠르고 가장 쉬운 커넥션 모드이다.
- H2를 설치하지 않고 build.gradle에서 의존성만 추가해주어도 H2 DB를 사용할 수 있다.
단점
- Embedded Mode의 DB는 JVM(및 클래스 로더) 당, 단 하나만 열려있을 수 있다. 데이터베이스가 JVM의 내부에 직접 포함되어 있기 때문에 다른 JVM에서는 접근할 수 없는 것이다.
- 때문에 분산 환경에서는 Embedded Mode 를 사용하는 것은 좋지 않은 선택일 것이다.
적용 방법
build.gradle
dependencies {
runtimeOnly 'com.h2database:h2' // h2 의존성 추가
}
application.yml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2://path/name
username: sa
password:
서버 모드 (Server-Mode)
h2는 h2 DB의 Server를 통해 DB를 사용하는 방식이다.
위에서 소개한 In-Memory 모드와 Embedded 모드는 build.gradle에서 의존성만 추가해주면
메모리 내에서, 또는 애플리케이션 내에서 정상적으로 작동했지만
H2를 DB Server를 통해 사용하려면 DB가 완전히 외부 의존성으로 분리되므로 H2를 직접 설치하고 서버를 가동시켜주어야 접근이 가능해진다.
적용 방법
build.gradle
dependencies {
runtimeOnly 'com.h2database:h2' // h2 의존성 추가
}
application.yml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:tcp://localhost/path/name
username: sa
password:
DB의 URL에 tcp를 붙여 h2:tcp://localhost/{path}/{name} 형식으로 사용한다.
혼합 모드 (Mixed-Mode)
혼합 모드는 임베디드 모드와 서버 모드가 합쳐진 모드이다.
때문에 이름이 Mixed Mode 인 것이다.
혼합 모드를 사용하면 먼저 실행된 애플리케이션은 '임베디드' 모드로 DB와 연결되지만,
다른 프로세스 또는 JVM에서 실행중인 애플리케이션이 동일한 데이터에 동시에 엑세스 할 수 있도록 'DB 서버'를 실행시킬 수 있다.
즉, 애플리케이션이 DB서버의 호스팅을 담당하는 것이다.
혼합 모드 DB 서버는 'Server API 사용'을 통해 애플리케이션 내에서 또는 종료 또는 시작시킬 수 있으며,
'Automatic Mixed Mode'를 사용하면 자동으로 시작 또는 종료시킬 수 있다.
Automatic Mixed Mode
Automatic Mixed Mode를 사용하면, DB에 연결하려고 하는 모든 클라이언트는
로컬이던 리모트이던 상관없이 완전히 동일한 DB URL을 사용해서 연결을 수행할 수 있다.
적용 방법
build.gradle
dependencies {
runtimeOnly 'com.h2database:h2' // h2 의존성 추가
}
application.yml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:~/${dbName};AUTO_SERVER=TRUE
username: sa
password:
데이터베이스 URL 끝에 AUTO_SERVER=TRUE 옵션을 추가해주면 된다.
이렇게만 설정해주면 다른 애플리케이션에서도
DB Connection URL에 `jdbc:h2:~/${dbName};AUTO_SERVER=TRUE` 을 사용하여 같은 DB에 접근할 수 있다.
dbName.lock.db 파일
Mixed Mode로 실행시키면, url로 설정한 경로에 dbName.lock.db 라는 파일이 생성된다.
dbName.lock.db 파일을 살펴보면 DB서버의 Private IP와 Port를 확인할 수 있다.
'lsof -i :PORT' 명령으로 터미널에서 조회하면 정상적으로 작동중인 DB 프로세스를 확인할 수 있다.
다른 애플리케이션에서 접속해보기
Mixed Mode를 사용하면 정말 로컬이 아닌 Remote에서도 접근이 되는 지 확인해보았다.
실제로 다른 애플리케이션 환경에서 동일한 URL을 사용하여 연결을 확인했고, 연결에 성공하는 것을 확인할 수 있었다.
Mixed Mode의 장단점
장점
- 서버 모드처럼 사용가능하지만, 로컬에서 사용할 때는 임베디드 모드와 동일한 연결 속도를 얻을 수 있다.
- 혼합 모드를 사용하면 로컬에서의 연결은 임베디드 모드를 사용했을 때처럼 빠르다.
단점
- 혼합 모드를 사용하면 로컬이 아닌 다른 연결은 로컬 연결에 비해 조금 느리다.
Reference
'BackEnd > DB' 카테고리의 다른 글
H2 DB - 인메모리(In-Memory) 모드 (0) | 2024.06.20 |
---|---|
[몽고DB, 스프링부트] Springboot, MongoDB 연동 (0) | 2023.01.22 |
[MySQL] MySQL 워크벤치 설치 및 RDS 연결 (3) | 2022.04.14 |
[데이터베이스] ERD cloud 사용법 - 무료 ERD 모델링 도구 (8) | 2022.01.10 |