개요
현재 회사에서 BI 툴로 Redash를 주로 사용하고 있습니다. 기존에는 Redash 서버가 EC2 인스턴스 하나에 docker-compose를 통하여 배포되었고 이로 인해 몇 가지 불편한 점들이 발생하였습니다. 그래서 이번에 EKS 클러스터가 구축되면서 해당 Redash 서버를 EKS 기반으로 마이그레이션 하기로 결정하였고 이를 진행하는 과정과 어떤 문제가 있었는지에 대해서 설명하겠습니다.
기존 Redash 문제점
먼저, Redash의 구성에 대해 간략히 설명해 보겠습니다.
위 그림은 Redash의 아키텍처로 Nginx를 Webserver로 사용하고 Backend로 Redash Server 가 존재하며 대시보드나 쿼리, 유저 정보 등을 저장하는 DB로 PostgreSQL을 사용합니다. 그리고 Redash 상에서 실행되는 Job 들을 관리하는 Scheduler 가 존재하고 해당 Job 들에 대한 Queue로 Redis를 사용합니다. 그리고 각 Job 별로 Worker 들을 분리해서 사용하는 구조입니다.
기존에는 위 구조가 그대로 하나의 인스턴스 위에 docker container로 모두 띄워져 있는 상태였으며 만약 리소스가 무거운 Job 이 실행될 경우, 서버 전체에 영향을 주어 다른 사용자들의 경험을 해치는 경우가 발생하였습니다. 예를 들어, 특정 대시보드에서 무거운 Query 가 존재하면 해당 대시보드에서 Query를 실행하게 된다면 인스턴스 자체에 부하가 와 서버 전체에 영향을 끼치게 됩니다. 또한, 이로 인해 서버가 다운될 수도 있어 서버의 인스턴스 사양을 늘리거나 재부팅을 해주는 경우가 종종 있었습니다.
물론 여러 인스턴스를 띄워서 클러스터를 만들면 됐지만, 이러한 작업은 번거롭고 관리 포인트가 늘어나서 진행하지 않고 있었고 인스턴스 사양을 늘리는 것으로 해결이 되어 중요도가 낮았습니다. 그러나 이번에 EKS 클러스터가 구축되었고 Redash 가 Helm Chart를 제공하고 있다는 점에서 EKS에 간단하게 배포하면서 EKS 환경에서의 이점을 누릴 수 있다고 생각해 이관하게 되었습니다.
EKS로 마이그레이션
그럼 본격적으로 EC2 기반에서 EKS 기반으로 마이그레이션 해보겠습니다.
배포
먼저, Redash는 공식 Helm Chart를 제공하고 있지 않아 커뮤니티 버전의 Helm Chart 를 활용했습니다.
위 버전을 택한 이유는 기존 Redash 서버가 redash/redash:10.1.0.b50633을 사용하고 있어 해당 버전에 맞춘 Chart를 사용하였습니다. (최신 버전의 Chart 는 Contribute 버전을 사용하고 있어, DB의 Schema 자체도 조금씩 달라져 데이터 마이그레이션 시 호환이 안됨.)
위 Chart 를 Helm을 통해 배포하면, Database에 스키마를 생성하고 Redash 구성 Pod 들을 실행합니다. 설정을 건들지 않고 사용할 시 postrgre와 Redis 도 같이 Pod 가 생성되는데 이때 외부 서버를 사용하도록 할 수 있습니다. 필자는 다음의 서버를 사용했습니다.
- Amazon RDS PostrgeSQL 16
- Amazon ElastiCache Redis OSS 캐시
# 외부 PostgreSQL 서버 Connection 정보
externalPostgreSQLSecret:
name: YOUR_SECRET_NAME
key: EXTERNAL_POSTGRESQL_URL
# 내부 Pod PostgreSQL 비활성화
postgresql:
enabled: false
# 외부 Elasticache 서버 Connection 정보
externalRedisSecret:
name: YOUR_SECRET_NAME
key: EXTERNAL_REDIS_URL
# 내부 Redis 비활성화
redis:
enabled: false
데이터 마이그레이션
이제 새로운 Redash 서버가 준비되었으니, 기존 서버의 데이터를 이관하면 됩니다.
Redash Schema 구조
먼저, Redash의 DB에서 사용하는 Schema를 살펴보겠습니다.
기존 PostgreSQL은 9.6 버전, 새로 이관하는 PostgreSQL은 16 버전을 사용하고 있습니다. 또한, 기존에는 postgres라는 사용자로 postgres 라는 데이터베이스에 테이블들을 생성하였는데 관리 차원에서 postgres는 admin 계정이기 때문에 사용자로 redash를 생성하고 redash 데이터베이스에 테이블을 생성하도록 변경하였습니다.
그래서 새로운 데이터베이스로 데이터를 이관하기 위해 다음과 같은 순서로 진행하였습니다.
- 새로운 데이터베이스의 환경 설정
-- 데이터베이스 생성
CREATE DATABASE redash;
-- Role 생성
CREATE ROLE redash;
-- 특정 Role 에게 특정 데이터베이스 연결 기능 제공
GRANT CONNECT ON DATABASE redash TO redash;
-- 특정 Role 역할이 있는 User 에게 특정 데이터베이스에 관한 모든 권한 부여
GRANT ALL PRIVILEGES ON DATABASE redash TO redash;
-- 비밀번호 설정
ALTER ROLE redash WITH PASSWORD 'PASSWORD';
-- 로그인 가능 하도록 ALTER
ALTER ROLE redash WITH LOGIN ;
-- https://stackoverflow.com/questions/74110708/postgres-15-permission-denied-for-schema-public
ALTER DATABASE redash OWNER TO redash;
- RDS 파라미터 그룹 설정 변경
- foreign key 제약 조건 무효화 설정 : session_replication_role 값을 replica로 변경
- 다음 코드로 변경되었는지 확인 가능
SELECT name, setting, boot_val, reset_val, unit
FROM pg_settings
WHERE name='session_replication_role';
- 기존 PostgreSQL container의 데이터 pg_dump를 통해 데이터 dump
- (선택 사항) events, changes 테이블의 경우, 변경 사항이나 발생한 이벤트 등을 기록하는 테이블로 기능 적인 측면에서 없어도 문제가 없습니다.
- (선택 사항) query_results 테이블의 경우, Redash는 Query를 실행하고 난 후 해당 결과를 query_results 테이블의 하나의 Column 에 저장하고 해당 결과를 Redash 서버가 가져와서 보여 주는 형태로 동작하고 있습니다. 그렇기 때문에 없어도 다시 Query 를 실행하면 자동으로 Table에 넣기 때문에 문제는 없지만 이관 후 Query 별로 Refresh를 다시 해주어야 하는 번거로움이 발생합니다.
docker exec -t redash_postgres_1 pg_dump -U postgres -a -T public.query_results -T public.events -T public.changes > ~/postgres.sql
- 해당 dump 데이터 S3로 전송
export S3_BUCKET="da-redash-backup"
export LOCAL_DIR="/home/ubuntu"
export FILE_TO_UPLOAD="postgres.sql"
aws s3 cp "$LOCAL_DIR/$FILE_TO_UPLOAD" "s3://$S3_BUCKET/$FILE_TO_UPLOAD"
- dump 한 .sql 파일을 다운로드한 후, psql을 통해 복원
- 확인 후, session_replication_role 값 origin으로 변경
psql -U redash -h ${REDASH_SERVER_HOST} -p 5432 -d redash -f postgres.sql
위 과정을 마치면 성공적으로 Redash를 마이그레이션 할 수 있습니다.