-
트리노에 고가용성을 더해줄 Trino GatewayProgramming 2025. 8. 13. 18:45
개요
- 트리노 게이트웨이는 로드 벨런서, 프록시 서버, 멀티 클러스터를 위한 다양한 설정이 가능한 라우터 역할을 함
- lyft가 개발한 후 오픈소스화한 프로젝트 현재는 Trino 레포지토리 하위에 존재
Pain point
- 코디네이터의 HA가 불가능하기 때문에 Trino의 코디네이터는 SPOF라서 장애 상황에 취약함(코디네이터 장애시 모든 실행중인 쿼리 중단)
- 코디네이터의 큐가 한정되어있어서 워커의 자원이 충분하더라도 모든 쿼리의 파싱과 분석, 최적화가 하나의 코디네이터에서 처리되기 때문에 쿼리 수가 증가하면 코디네이터의 CPU/메모리 부하가 급증하여 대기시간이 증가함
- 업데이트시에 클러스터가 중지됨. 롤링업데이트가 되더라도 기존에 워커에서 작업중인 쿼리가 초기화됨
Advantages
- 고가용성 확보
- 특정 워크로드나 특정 쿼리 및 데이터소스를 라우팅해서 용도별, 팀별로 클러스터 구성가능 보안 및 쿼리 안정성 확보
- 사용자 중단없이 무중단 업그레이드 가능
- 클러스터 상태 모니터링 가능
Use cases
- SKT
- HA(High Availability)의 용도로 사용
오픈소스 Trino를 활용한 전사 데이터 분석 시스템 구축기
Trino를 활용한 전사 데이터 분석 시스템 구축기
techtopic.skplanet.com
- Naver
- 하나의 URL로 두개의 클러스터를 접속하며, 무중단 배포를 해야했음
- 한번에 많은 양의 쿼리가 요청이 오면 리소스 기아문제로 퍼포먼스가 안좋아짐 기존에는 클러스터 큐상태를 고려해서 리소스 그룹으로 CPU, 메모리, 동시성에 리미트를 걸어둠
- 이후에 헤더키를 통해서 클러스터에 분배
- 게이트웨이를 이용해 쿼리 특성별로 클러스터 자동 전환(스케줄 쿼리, 애드훅 쿼리, 숏텀 클러스터) ->라우팅 용도로 사용
Helm 설치
helm install tg --values ./trino-gateway-values.yaml trino/trino-gateway --namespace=presto
Values
- 백엔드로 사용할 postgresql or mysql 정보 입력(사전에 gateway 또는 임의의 데이터베이스 생성이 선행되어야함)
dataStore: # -- The connection details for the backend database for Trino Gateway and Trino query history jdbcUrl: jdbc:postgresql://localhost:5432/gateway user: user_name password: passwoard driver: org.postgresql.Driver
동일 환경에서 Trino를 두 개 이상 배포할 때 생기는 JWT 토큰 인증문제 - TroubleShoting
ERROR http-worker-143 io.trino.server.InternalAuthenticationManager Internal authentication failed io.jsonwebtoken.security.SignatureException: JWT signature does not match locally computed signature. JWT validity cannot be asserted and should not be trusted.
- 환경이 같으면 같은 클러스터로 인식해서 내부 인증 토큰 불일치로 생기는 문제로 두 클러스터가 서로 다른 JWT 토큰을 사용하려고할때 동일한 서명 키를 공유하지 않으면 인증에 실패함
Solution1
node.properties: | node.environment=standby node.data-dir=/data/trino
- 클러스터의 environment의 이름을 서로 다르게 지어줘서 아예 다른 인증키를 사용하도록함
Solution2
# 두 클러스터 모두 동일한 값으로 설정 internal-communication.shared-secret=<your-shared-secret-here>
- 두 클러스터에 해당 옵션 추가로 인증키 공유하도록 설정
로드밸런싱
select 1; select 2; select 3; select 4; select 5; select 6; select 7; select 8; select 9; select 10;
- 위 sql문을 차례로 실행시켰을때 각 sql 라인별로 클러스터에 다르게 요청되는 것을 트리노 게이트웨이 히스토리에서 확인할 수 있다.
Routing-rules
- airflow나 superset, 앱 서비스 등 다양한 요청에 대해서 원하는 클러스터로 라우팅되도록 설정해줄 수 있음
- 쿼리의 성격별이나 장애상황에 더이상 특정 클러스터에 큐가 쌓이지 않도록 분배하는 등 다양하게 활용 가능
- 아래 테스트는 dbeaver에서 들어오는 쿼리를 trino-main 클러스터에만 실행하도록 라우팅룰을 설정하는 예제
configmap
apiVersion: v1 data: routing-rules.yaml: | name: "dbeaver" description: "if query from dbeaver, route to dbeaver group" actions: - 'result.put("routingGroup", "dbeaver")' condition: 'request.getHeader("x-trino-source") contains "DBeaver"' kind: ConfigMap metadata: name: routing-rules
values
# Routing Rules 활성화 routingRules: rulesEngineEnabled: true rulesType: FILE rulesConfigPath: "/etc/routing-rules/routing-rules.yaml" rulesRefreshPeriod: "1m" ... volumes: - name: routing-rules configMap: name: routing-rules items: - key: routing-rules.yaml path: routing-rules.yaml volumeMounts: - name: routing-rules mountPath: "/etc/routing-rules/routing-rules.yaml" subPath: routing-rules.yaml readOnly: true
- configmap을 볼륨마운트해서 사용
라우팅룰이 적용된 모습을 게이트웨이 대시보드에서 확인할 수 있다 - 클러스터의 라우팅 그룹을 변경
Routing rule에 의해 특정 클러스터에만 쿼리가 라우팅된 모습을 확인할 수 있다 ETC
Resource Group
- 쿼리 리소스 관리 및 제한
# 리소스 그룹 생성 curl -X POST http://localhost:8080/trino/resourcegroup/create \ -d '{ "name": "resourcegroup1", "softMemoryLimit": "100%", "maxQueued": 100, "softConcurrencyLimit": 100, "hardConcurrencyLimit": 100 }'
Selector
- 쿼리를 어떤 리소스 그룹에 할당할지 결정하는 규칙 시스템
# Selector 생성 - airflow 사용자의 INSERT 쿼리를 특정 그룹으로 라우팅 curl -X POST http://localhost:8080/trino/selector/create \ -d '{ "priority": 1, "userRegex": "airflow_user", "sourceRegex": "airflow", "queryType": "insert", "resourceGroupId": 1 }'
'Programming' 카테고리의 다른 글
스파크에서 지원하는 압축 알고리즘 비교 (0) 2024.06.26 당신의 인덱스는 안녕하신가요?(커버링 인덱스) (0) 2024.03.31 SparkSQL에서 증분 테이블 처리하기 (0) 2024.02.25 PrestoSQL to Trino Migration 할 때 주의할 점 (0) 2023.12.22 kafka retention 용량 설정 값 이해하기 (0) 2023.05.01