ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 트리노에 고가용성을 더해줄 Trino Gateway
    Programming 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
      }'

    댓글

Copyright 2023. 은유 All rights reserved.