Search

EC2기반 Tableau Server 마이그레이션과 트러블슈팅

1. 배경

ISMS 인증 대응을 위해 데이터 인프라를 public subnet에서 private subnet으로 이전하는 작업이 진행되었다. Tableau Server도 같은 흐름에서 네트워크 구성을 바꿔야 했다.
일반적인 EC2 마이그레이션처럼 AMI를 생성해서 복제하는 방식은 Tableau Server에서는 적합하지 않다. Tableau는 분산 환경에서 여러 노드의 데이터와 설정을 .tsbak 형식의 단일 백업 파일로 관리하며, 복구 시에도 이 백업 파일을 사용해야 모든 노드의 데이터가 일관되게 복원된다. 따라서 신규 환경에 Tableau Server를 새로 설치하고, 기존 환경에서 생성한 백업 파일을 복구하는 방식으로 마이그레이션을 진행했다.
추가로, 기존 환경은 Ubuntu 18.04와 Tableau 2023.1 버전으로 운영 중이었는데, 이번 이전을 계기로 Ubuntu 24.04와 Tableau 2025.3으로 업그레이드까지 함께 진행했다.

2. 아키텍처

graph TB
    subgraph Before["Before -- Public Subnet"]
        direction TB
        U1[사용자] --> R53A[Route53]
        R53A --> ALBA[Public ALB]
        ALBA --> NA1["Node A -- Main<br/(no-flows)"]
        ALBA --> NB1["Node B -- Prep<br/>Prep Conductor (all-jobs)"]
        
        ENV1["Tableau 2023.1.5"]
    end
Mermaid
복사
graph TB
    subgraph After["After -- Private Subnet"]
        direction TB
        U2[사용자] --> VPN[VPN]
        VPN --> R53B[Route53]
        R53B --> ALBB[Internal ALB]
        ALBB --> NA2["Node A -- Main<br/>(no-flows)"]
        ALBB --> NB2["Node B -- Prep<br/>Prep Conductor (all-jobs)"]
        
        ENV2["Tableau 2025.3.1"]
    end
Mermaid
복사
핵심 변경은 네트워크 경로다. 기존에는 public subnet에서 Public ALB를 통해 접근했지만, 신규 환경에서는 VPN을 통해 private subnet의 Internal ALB로 접근한다. 외부에서 직접 접근이 불가능해지고, DNS 레코드만 전환하면 즉시 신규 환경으로 넘어갈 수 있어서 사용자 체감 중단은 수 초 수준이었다.

2.1 노드 역할 분리

노드 구성 자체는 이전과 동일하게 유지했다. Prep 흐름이 무거웠기 때문에 Node A와 Node B의 역할을 분리해서 운영하고 있었고, 이 구조를 그대로 가져갔다.
Node A: no-flows -- 대시보드 조회, Extract 갱신 같은 대화형 워크로드만 처리
Node B: all-jobs -- Backgrounder & Prep Conductor를 배치해 흐름 실행
이렇게 분리하면 Prep 흐름이 돌아가는 동안에도 대시보드 조회 성능에 영향을 주지 않는다.

2.2 타임라인 요약

단계
소요 시간
비고
백업 생성 (.tsbak)
약 6시간 30분
디스크 사용량 2TB, 백업 파일 850GB
신규 Node A 설치 + 초기화 Node B 합류 + 역할 분리
약 1시간
Tableau 설치, TSM 초기화, 라이선스Bootstrap 기반 클러스터 합류
설정/데이터 복구
약 7시간
settings import → backup restore
백업과 복구가 전체 시간의 대부분을 차지한다. 850GB 규모라 어쩔 수 없는 부분인데, 이 시간 동안 기존 서버는 계속 운영 중이므로 사용자에게 영향은 없었다.

3. 실행에서 주의할 포인트

설치 자체는 Tableau 공식 문서를 따라가면 된다. 여기서는 공식 문서대로 했는데도 헷갈리거나 주의가 필요했던 부분만 짚는다.

3.1 백업

tsm maintenance backup 명령 하나로 백업이 생성되지만, 문제는 시간과 디스크 공간이다. 우리 환경에서 디스크 사용량이 2TB였고, 생성된 .tsbak 파일은 850GB였다. 백업 생성에만 6시간 30분이 걸렸다.
백업 중에는 Tableau 내부적으로 임시 파일이 생성되므로, 백업 파일 크기의 2배 이상 여유 공간이 필요하다. 사전에 du -sh /var/opt/tableau/ 등으로 현재 사용량을 확인하고 충분한 공간을 확보해둬야 한다.

3.2 Bootstrap 기반 노드 합류

Tableau 2노드 구성에서 두 번째 노드를 클러스터에 합류시키려면 Bootstrap 파일이 필요하다. Node A에서 생성한 bootstrap.json을 Node B로 전달하고, Node B의 TSM 초기화 시 이 파일을 지정하면 된다.
# Node A에서 bootstrap 생성 tsm topology nodes get-bootstrap-file --file /home/tableau/bootstrap/bootstrap.json # Node B에서 bootstrap으로 초기화 sudo /opt/tableau/tableau_server/packages/scripts.<version>/initialize-tsm \ -b /path/to/bootstrap.json --accepteula
Bash
복사
주의할점: Node B에서 TSM을 먼저 단독으로 설치하면 안 된다. 처음에 이걸 모르고 Node B에서 TSM을 따로 설치했다가, 다시 지우고 Bootstrap으로 초기화했더니 제대로 동작하지 않아 전부 삭제하고 재설치해야 했다. Node B는 반드시 Bootstrap 파일로 초기화해야 한다.

3.3 복구 순서

설정 파일(settings.json)과 데이터 백업(.tsbak)을 모두 복구해야 하는데, 순서가 중요하다.
# 1. 설정 먼저 tsm settings import -f settings.json tsm pending-changes apply # 2. 데이터 복구는 그 다음 tsm maintenance restore -f backup.tsbak
Bash
복사
settings import를 먼저 해야 서버 설정이 반영된 상태에서 데이터가 복구된다. 순서를 뒤집으면 설정 불일치로 복구 후 프로세스가 비정상 동작할 수 있다.

3.4 라이선스 키 관리

Tableau 라이선스 키는 활성화 횟수가 3회로 제한되어 있다. 신규 환경에서 활성화하려면 기존 환경에서 반드시 비활성화를 먼저 해야 한다. 재설치 과정에서 비활성화 없이 인스턴스를 삭제하면 활성화 횟수가 차감된 채로 남아서 나중에 활성화가 거부될 수 있다.

4. 복구 후 문제

4.1 gp2→gp3 전환 시 처리량

증상: 이전 후 일부 Prep 흐름의 실행 시간이 기존 대비 2배 이상 증가했다.
원인: EBS 볼륨 타입이 gp2에서 gp3로 바뀌면서 디스크 처리량이 떨어짐
gp2는 볼륨 크기에 비례해 IOPS와 처리량이 자동으로 올라간다. 반면 gp3는 기본 처리량이 125MB/s로 고정되어 있고 더 필요하면 명시적으로 올려야 한다.
백업 복구 직후에는 Tableau가 내부적으로 대량의 파일 재구성과 인덱싱 작업을 수행한다. 이때 디스크 I/O가 집중적으로 발생하는데 낮은 처리량으로는 병목이 생긴다.
해결: gp3 처리량을 125MB/s → 250MB/s로 상향

4.2 JVM 힙 폭발

증상: 복구 후 Flow Editor, Flow Processor, Non-Interactive Microservice Container에서 OutOfMemoryError가 반복 발생했다.
Tableau Server의 많은 내부 프로세스가 JVM 위에서 돌아가며 각 힙 메모리가 따로 설정되어있다. 이번에 OOM이 발생한 힙 메모리는 8GB인데, 힙덤프를 떠서 분석해보니 이 이상으로 메모리를 할당하려다 죽은 케이스 였다. 복잡한 계산식과 CASE 문이 많은 Prep 흐름을 처리하면서 CompiledFuncallExpression, CompiledCaseExpression 객체가 수천만 개 생성되어 힙을 잡아먹고 있었다.
해결:
총 메모리는 여유가 조금 있어서 OOM 힙 메모리를 각자 조금씩 상향시켰다.
# Flow Editor: 8GB → 16GB tsm configuration set -k floweditor.vmopts -v "-Xmx16G" # Flow Processor: 8GB → 12GB tsm configuration set -k flowprocessor.vmopts -v "-Xmx12g" # VizQL Server, VizDataService, DataServer: 각각 16GB로 상향 tsm configuration set -k vizqlserver.vmopts -v "-Xmx16g" tsm configuration set -k vizdataservice.vmopts -v "-Xmx16g" tsm configuration set -k dataserver.vmopts -v "-Xmx16g" tsm pending-changes apply
Bash
복사
메모리 상향은 당장의 대응이고, 근본적으로는 CASE 문이 수십 개 중첩된 흐름 구조를 단순화하는 작업이 필요하다. 하지만 현실적으로 수백 개의 기존 흐름을 즉시 리팩토링하기는 어려우므로, 메모리를 먼저 올리고 점진적으로 흐름을 개선하는 방향으로 진행하고 있다.

4.3 Catalog 인덱싱 폭탄

증상
Non-Interactive Microservice Container가 OOM으로 반복 재시작되면서 노드 상태가 DEGRADED로 떨어졌다.
JVM 힙 문제를 해결한 뒤에도 Non-Interactive Container만 계속 죽었다. 다시 힙덤프를 분석해보니 이번에는 Tableau Catalog의 메타데이터 인덱싱이 원인이었다.
Tableau Catalog는 데이터 소스, 워크북, 테이블 간의 lineage를 추적하는 기능인데, 백업 복구 후에는 전체 메타데이터를 새로 인덱싱하는 백필 작업이 자동으로 시작된다. 우리 환경에서는 이 백필 큐에 30,000건 이상이 쌓여 있었고, 인덱싱 과정에서 ConcurrentHashMap수억 개의 객체가 올라가면서 메모리를 소진했다.
컨테이너가 OOM으로 죽으면 큐는 그대로 남아 있고, 재시작하면 다시 인덱싱을 시도하다 또 죽는 악순환이 반복됐다.
대응 시도 및 한계
큐 해소를 위해 Non-Interactive Container 수를 2개로 늘려 병렬 처리를 시도했다. 그러나 인덱싱 작업이 동시에 실행되면서 CPU 사용률이 수 시간 동안 100%에 고정된 상태가 지속되었고 처리 속도는 거의 개선되지 않았다.
해당 노드는 r7.8xlarge 인스턴스를 사용하고 있었음에도 부하를 감당하지 못했다. 이는 단순 리소스 부족 문제가 아니라, 대량 메타데이터 백필 인덱싱이 JVM 메모리와 CPU를 동시에 소모하는 구조적 부하임을 보여준다.
결국 시스템 안정성을 우선하기 위해 Tableau Catalog 기능을 비활성화했고, 이후 CPU 사용률이 정상화되면서 노드 상태도 안정적으로 회복되었다.
Catalog 비활성화 영향 및 고려사항
Catalog를 비활성화하면 Tableau가 제공하는 메타데이터 기반 기능 일부를 사용할 수 없게 된다.
영향 범위
데이터 lineage 조회 불가
컬럼 수준 영향도 분석사용 불가
데이터 품질 경고 및 인증 연계 기능 제한
대시보드 조회, Extract 갱신, Prep 흐름 실행 등 분석 및 시각화 기능 자체에는 영향이 없다.
우리 환경에서는 Tableau Catalog 기능 활용도가 낮아 운영 안정성을 우선해 비활성화를 선택했다.
향후 재활성화 전략
대규모 환경에서 Catalog 백필 인덱싱은 초기 부하가 매우 크므로 다음과 같은 방식이 안전하다.
시스템 안정화 이후 단계적으로 활성화
Non-Interactive Microservice Container를 별도 노드로 분리
충분한 JVM 힙 메모리 및 CPU 리소스 확보
백필 큐 상태 모니터링 후 점진적 처리
Catalog는 거버넌스 성숙도가 높아질수록 필요성이 커지는 기능이므로, 향후 메타데이터 활용 요구가 증가하면 전용 리소스를 분리하는 구조로 재도입을 검토할 수 있다.

4.4 한글 계정 접속 불가

증상: Tableau 뷰어 계정 중 아이디가 한글인 경우 로그인이 되지 않았다. 기존 환경에서는 문제없이 동작하던 한글 아이디가 신규 환경에서는 인식되지 않아 해당 계정을 영문 아이디로 재발급해 해결했다.
아이디가 한글일 거라고는 생각을 못 해서 원인을 찾는 데 시간이 걸렸다. 서버 이전 후 몇몇 사용자만 접속이 안 된다고 해서 설마 하고 확인해보니 전부 한글 아이디였다.

5. 결과 및 교훈

5.1 마이그레이션 성과

사용자 체감 중단 시간: 수 초 수준 (DNS 전환 시간)
데이터 손실: 없음
노드 역할 분리: 정상 적용
접속 경로: Private subnet으로 완전 이전

5.2 다음에 같은 작업을 한다면 - 체크리스트

복구 후 인덱싱 부하를 고려해야 한다
백업 복구 직후에는 내부적으로 파일 재구성과 인덱싱 작업이 발생
이때 디스크 I/O와 메모리 사용량이 급증하므로, 충분한 리소스를 확보해야 함
EC2 뿐 아니라 EBS 설정도 확인
gp2 → gp3 전환 시 기본 처리량이 125MB/s로 제한
사전에 처리량을 체크하고 메트릭을 보면서 적절하게 조절 필요
JVM 힙 메모리는 여유 있게 설정
복잡한 계산식과 흐름이 많으면 힙 메모리 부족으로 프로세스가 재시작될 수 있음
힙덤프 분석을 통해 메모리 누수 원인을 파악, 필요 시 메모리를 상향
카탈로그 인덱싱은 점진적 활성화
대규모 환경에서 일어나는 백필은 시스템을 압도함
시스템이 안정된 이후 점진적으로 활성화하는 것이 안전하며 향후 카탈로그가 필요해지면 Non-Interactive Container를 별도의 더 큰 인스턴스로 분리하거나 컨테이너 수를 증설하는 방식을 검토할 수 있음