AWS Redshift with Spring JPA on Docker #1
<개요>
- 기존에 사용하던 Aurora DB의 성능 문제로 AWS Redshift 로 제품군 변경
- EBS 를 사용하던 부분을 ECS로 변경하기 위해서 Docker 작업
<내용>
- ANSI SQL을 주로 사용하였다면 쿼리상의 큰 변화는 없다.
- MySQL driver를 pom.xml 에서 제거하고 Redshift driver를 추가한다.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.amazon.redshift</groupId>
<artifactId>redshift-jdbc42-no-awssdk</artifactId>
<version>1.2.10.1009</version>
</dependency>
- application.yml 파일에서도 DB url을 변경한다.
spring:
profiles: dev
datasource:
driver-class-name: com.amazon.redshift.jdbc42.Driver
url: jdbc:redshift://localhost:5439/dev
username:
password:
- docker file을 작성한다.[Dockerfile]
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- maven package를 수행하고 다음과 같이 Docker 이미지를 build한다.
docker build -t {service-name} .
- docker 를 실행한다.
docker run -p 8200:8200 {service-name}
<오류상황>
- Local에서는 잘 동작하던 Application이 Docker 이미지에서는 잘 되지 않는 현상이 발생한다.
- 오류로그를 보면 다음과 같다.
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.3.7.Final.jar!/:5.3.7.Final]
... 41 common frames omitted
hibernate dialect 가 설정되지 않았다는 내용이다.
일반적으로는 명시하지 않아도 추천되어서 hibernate가 자동으로 지정하는데 docker내에서는 오류가 발생하는 것을 확인할 수 있다.
(자세한 원인파악이 필요하다. 우선은 해당 dialect를 명시하여 오류를 수정한다.)
- AWS Redshift는 PostgreSQL 8.0.2. 을 기반으로 수행되기 때문에 다음과 같이 Spring JPA를 세팅한다.
jpa:
database-platform: org.hibernate.dialect.PostgreSQL9Dialect
generate-ddl: false
hibernate:
ddl-auto: none
<해결>
- docker 상에서도 정상적으로 서비스가 동작하는 것을 확인할 수 있다.
- 다음에는 AWS ECS 에서 해당 서비스를 기동한다.
<참고>
PostgreSQL을 기반으로 만들어졌으나 지원하지 않는 기능들이 있으니 확인해야 한다.
<AWS Redshift에서 제공하지 않는 PostgreSQL features>
- Table partitioning (range and list partitioning)
- Tablespaces
- Constraints
- Unique
- Foreign key
- Primary key
- Check constraints
- Exclusion constraints
<AWS Redshift에서 제공하지 않는 PostgreSQL data types>
- Arrays
- BIT, BIT VARYING
- BYTEA
- Composite Types
- Date/Time Types
- INTERVAL
- TIME
- Enumerated Types
- Geometric Types
- HSTORE
- JSON
- Network Address Types
- Numeric Types
- SERIAL, BIGSERIAL, SMALLSERIAL
- MONEY
- Object Identifier Types
- Pseudo-Types
- Range Types
- Special Character Types
- "char" – A single-byte internal type (where the data type named char is enclosed in quotation marks).
- name – An internal type for object names.
- Text Search Types
- TXID_SNAPSHOT
- UUID
- XML
https://docs.aws.amazon.com/redshift/latest/dg/c_redshift-and-postgres-sql.html