Redshift 커넥터

Redshift 커넥터

Redshift 커넥터는 외부 Amazon Redshift 클러스터에서 테이블을 조회하고 생성할 수 있게 해줘요. Redshift와 Hive 같은 서로 다른 시스템 사이의 데이터를 조인하거나, 두 Redshift 클러스터 사이의 데이터를 조인하는 데 쓸 수 있어요.

출처: 문서

본문

요구 사항 (Requirements)

Redshift에 연결하려면 다음이 필요해요.

  • Trino 코디네이터와 워커에서 Redshift까지의 네트워크 접근. 기본 포트는 5439예요.

설정 (Configuration)

Redshift 커넥터를 설정하려면 etc/catalogexample.properties 같은 이름의 카탈로그 속성 파일을 만들어 Redshift 커넥터를 example 카탈로그로 마운트해요. 설정에 맞게 연결 속성을 교체하며 다음 내용으로 파일을 만들어요.

connector.name=redshift
connection-url=jdbc:redshift://example.net:5439/database
connection-user=root
connection-password=secret

connection-userconnection-password는 보통 필수이며, 연결에 사용하는 사용자 자격 증명(주로 서비스 사용자)을 결정해요. 카탈로그 속성 파일에 실제 값을 두지 않도록 시크릿을 사용할 수 있어요.

연결 보안 (Connection security)

데이터 소스에 전역적으로 신뢰되는 인증서로 TLS가 설정되어 있다면, connection-url 카탈로그 설정 속성에 파라미터를 추가해 클러스터와 데이터 소스 사이에 TLS를 활성화할 수 있어요.

예를 들어 Redshift JDBC 드라이버 2.1 버전에서는 SSL 파라미터로 TLS/SSL이 기본 활성화돼요. connection-url 설정 속성에 파라미터를 추가해 TLS를 비활성화하거나 더 구성할 수 있어요.

connection-url=jdbc:redshift://example.net:5439/database;SSL=TRUE;

TLS 구성 옵션에 대한 자세한 내용은 Redshift JDBC 드라이버 문서를 참조하세요.

데이터 소스 인증 (Data source authentication)

커넥터는 여러 방법으로 데이터 소스 연결에 자격 증명을 제공할 수 있어요.

  • 커넥터 설정 파일에 인라인으로
  • 별도 속성 파일에
  • 키 스토어 파일에
  • Trino에 연결할 때 설정하는 추가 자격 증명(extra credentials)으로

카탈로그 속성 파일에 민감한 값을 두지 않도록 시크릿을 사용할 수 있어요.

연결 자격 증명에 대한 설정 속성은 다음 표와 같아요.

속성 이름 설명
credential-provider.type 자격 증명 프로바이더의 타입. INLINE, FILE, KEYSTORE 중 하나여야 하며 기본값은 INLINE.
connection-user 연결 사용자 이름.
connection-password 연결 비밀번호.
user-credential-name 사용자 이름으로 사용할 값의 추가 자격 증명 속성 이름. JDBC 파라미터 참조의 extraCredentials 참조.
password-credential-name 비밀번호로 사용할 값의 추가 자격 증명 속성 이름.
connection-credential-file 자격 증명이 있는 속성 파일 위치. connection-userconnection-password 속성을 포함해야 해요.
keystore-file-path 자격 증명을 읽을 Java Keystore 파일 위치.
keystore-type 키스토어 파일 형식(예: JKS, PEM).
keystore-password 키 스토어용 비밀번호.
keystore-user-credential-name 사용자 이름으로 사용할 키 스토어 엔티티 이름.
keystore-user-credential-password 사용자 이름 키 스토어 엔티티용 비밀번호.
keystore-password-credential-name 비밀번호로 사용할 키 스토어 엔티티 이름.
keystore-password-credential-password 비밀번호 키 스토어 엔티티용 비밀번호.

여러 Redshift 데이터베이스 또는 클러스터 (Multiple Redshift databases or clusters)

Redshift 커넥터는 Redshift 클러스터 내의 단일 데이터베이스에만 접근할 수 있어요. 따라서 Redshift 데이터베이스가 여러 개이거나 여러 Redshift 클러스터에 연결하려면 Redshift 커넥터의 여러 인스턴스를 설정해야 해요.

카탈로그를 추가하려면 etc/catalog에 이름이 다른 속성 파일을 추가하고 .properties로 끝나게 하면 돼요. 예를 들어 속성 파일 이름을 sales.properties로 정하면 Trino는 설정된 커넥터를 사용해 sales라는 카탈로그를 만들어요.

일반 설정 속성 (General configuration properties)

커넥터에 대한 일반 카탈로그 설정 속성은 다음 표와 같아요.

속성 이름 설명
case-insensitive-name-matching 대소문자 구분 없는 스키마·테이블 이름 지원. 기본값은 false.
case-insensitive-name-matching.cache-ttl 대소문자 구분 없는 스키마·테이블 이름이 캐시되는 시간. 기본값은 1m.
case-insensitive-name-matching.config-file Trino가 다른 대소문자의 비슷한 이름을 가진 스키마·테이블을 구분할 수 있게 하는 JSON 형식의 이름 매핑 설정 파일 경로. 기본값은 null.
case-insensitive-name-matching.config-file.refresh-period Trino가 이름 매칭 설정 파일의 변경을 확인하는 빈도. 시간 값 기본값은 0s(리프레시 비활성화).
metadata.cache-ttl 테이블·컬럼 통계를 포함한 메타데이터가 캐시되는 시간. 기본값은 0s(캐싱 비활성화).
metadata.cache-missing 테이블·컬럼 통계를 포함한 메타데이터가 사용 불가능하다는 사실을 캐시. 기본값은 false.
metadata.schemas.cache-ttl 스키마 메타데이터가 캐시되는 시간. 기본값은 metadata.cache-ttl 값.
metadata.tables.cache-ttl 테이블 메타데이터가 캐시되는 시간. 기본값은 metadata.cache-ttl 값.
metadata.statistics.cache-ttl 테이블 통계가 캐시되는 시간. 기본값은 metadata.cache-ttl 값.
metadata.cache-maximum-size 메타데이터 캐시에 저장되는 최대 객체 수. 기본값은 10000.
write.batch-size 배치 실행의 최대 문장 수. 기본값에서 이 설정을 바꾸지 마세요. 기본값이 아닌 값은 성능에 악영향을 줄 수 있어요. 기본값은 1000.
dynamic-filtering.enabled JDBC 쿼리로 동적 필터를 푸시다운. 기본값은 true.
dynamic-filtering.wait-timeout Trino가 JDBC 쿼리를 시작하기 전에 조인의 빌드 측에서 동적 필터가 수집되길 기다리는 최대 시간. 큰 타임아웃을 쓰면 더 상세한 동적 필터가 나올 수 있지만, 일부 쿼리의 지연 시간이 늘어날 수도 있어요. 기본값은 20s.

쿼리 메타데이터 추가 (Appending query metadata)

선택적 파라미터 query.comment-format로 각 쿼리와 함께 데이터 소스로 보내는 SQL 코멘트를 설정할 수 있어요. 이 코멘트 형식은 어떤 문자든 포함할 수 있고 다음 메타데이터도 포함할 수 있어요.

  • $QUERY_ID: 쿼리의 식별자.
  • $USER: Trino에 쿼리를 제출하는 사용자의 이름.
  • $SOURCE: 쿼리를 제출하는 데 사용된 클라이언트 도구의 식별자(예: trino-cli).
  • $TRACE_TOKEN: 클라이언트 도구로 설정된 트레이스 토큰.

코멘트는 쿼리에 대한 더 많은 컨텍스트를 제공할 수 있어요. 이 추가 정보는 데이터 소스의 로그에서 사용할 수 있어요. Trino 클러스터의 환경 변수를 코멘트에 포함하려면 ${ENV:VARIABLE-NAME} 문법을 사용해요.

다음 예시는 Trino가 보낸 각 쿼리를 식별하는 간단한 코멘트를 설정해요.

query.comment-format=Query sent by Trino.

이 설정으로 SELECT * FROM example_table; 같은 쿼리는 코멘트가 붙어 데이터 소스로 전송돼요.

SELECT * FROM example_table; /*Query sent by Trino.*/

다음 예시는 메타데이터를 사용해 위 예시를 개선해요.

query.comment-format=Query $QUERY_ID sent by user $USER from Trino.

Jane이 쿼리 식별자 20230622_180528_00000_bkizg로 쿼리를 보냈다면, 데이터 소스로 다음 코멘트 문자열이 전송돼요.

SELECT * FROM example_table; /*Query 20230622_180528_00000_bkizg sent by user Jane from Trino.*/

참고

일부 JDBC 드라이버 설정과 로깅 구성은 코멘트가 제거되게 할 수 있어요.

도메인 압축 임계값 (Domain compaction threshold)

큰 프레디킷 목록을 데이터 소스로 푸시다운하면 성능이 저하될 수 있어요. Trino는 성능과 프레디킷 푸시다운 사이의 균형을 보장하기 위해 기본적으로 큰 프레디킷을 더 단순한 범위 프레디킷으로 압축해요. 필요하다면 데이터 소스가 큰 프레디킷을 활용할 수 있을 때 성능을 개선하기 위해 이 압축 임계값을 높일 수 있어요. 이 임계값을 높이면 큰 동적 필터의 푸시다운이 개선될 수 있어요. domain-compaction-threshold 카탈로그 설정 속성 또는 domain_compaction_threshold 카탈로그 세션 속성으로 이 임계값의 기본값 256을 조정할 수 있어요.

대소문자 구분 없는 매칭 (Case insensitive matching)

case-insensitive-name-matchingtrue로 설정되면, Trino는 소문자 이름을 원격 시스템의 실제 이름에 매핑해 유지함으로써 소문자가 아닌 스키마·테이블을 조회할 수 있어요. 하지만 두 스키마·테이블의 이름이 대소문자만 다르면(예: "customers"와 "Customers") Trino는 모호성 때문에 조회하지 못해요.

이런 경우 case-insensitive-name-matching.config-file 카탈로그 설정 속성을 사용해 이 원격 스키마·테이블을 각각의 Trino 스키마·테이블에 매핑하는 설정 파일을 지정해요. 또한 JSON 파일은 빈 배열로만 있더라도 schemastables 속성을 모두 포함해야 해요.

{
  "schemas": [
    {
      "remoteSchema": "CaseSensitiveName",
      "mapping": "case_insensitive_1"
    },
    {
      "remoteSchema": "cASEsENSITIVEnAME",
      "mapping": "case_insensitive_2"
    }],
  "tables": [
    {
      "remoteSchema": "CaseSensitiveName",
      "remoteTable": "tablex",
      "mapping": "table_1"
    },
    {
      "remoteSchema": "CaseSensitiveName",
      "remoteTable": "TABLEX",
      "mapping": "table_2"
    }]
}

mapping 속성에 정의된 테이블·스키마 중 하나에 대한 쿼리는 해당 원격 엔티티에 대해 실행돼요. 예를 들어 case_insensitive_1 스키마의 테이블에 대한 쿼리는 CaseSensitiveName 스키마로 전달되고, case_insensitive_2에 대한 쿼리는 cASEsENSITIVEnAME 스키마로 전달돼요.

테이블 매핑 수준에서 위와 같이 설정된 case_insensitive_1.table_1에 대한 쿼리는 CaseSensitiveName.tablex로 전달되고, case_insensitive_1.table_2에 대한 쿼리는 CaseSensitiveName.TABLEX로 전달돼요.

기본적으로 매핑 설정 파일이 변경되면 Trino를 재시작해야 변경 사항을 로드해요. 선택적으로 case-insensitive-name-matching.config-file.refresh-period를 설정해 Trino가 재시작 없이 속성을 리프레시하게 할 수 있어요.

case-insensitive-name-matching.config-file.refresh-period=30s

장애 허용 실행 지원 (Fault-tolerant execution support)

이 커넥터는 쿼리 처리의 장애 허용 실행을 지원해요. 읽기와 쓰기 연산 모두 어떤 재시도 정책으로도 지원돼요.

Redshift 조회 (Querying Redshift)

Redshift 커넥터는 각 Redshift 스키마마다 스키마를 제공해요. SHOW SCHEMAS를 실행해 사용 가능한 Redshift 스키마를 볼 수 있어요.

SHOW SCHEMAS FROM example;

web이라는 Redshift 스키마가 있다면 SHOW TABLES로 이 스키마의 테이블을 볼 수 있어요.

SHOW TABLES FROM example.web;

web 데이터베이스의 clicks 테이블에서 컬럼 목록을 보는 방법은 두 가지가 있어요.

DESCRIBE example.web.clicks;
SHOW COLUMNS FROM example.web.clicks;

마지막으로 web 스키마의 clicks 테이블에 접근할 수 있어요.

SELECT * FROM example.web.clicks;

카탈로그 속성 파일에 다른 이름을 사용했다면 위 예시의 example 대신 그 카탈로그 이름을 사용하세요.

타입 매핑 (Type mapping)

타입 매핑 설정 속성 (Type mapping configuration properties)

다음 속성은 연결된 데이터 소스의 데이터 타입을 Trino 데이터 타입으로 매핑하는 방법과 메타데이터를 Trino에서 어떻게 캐싱하는지 구성하는 데 쓸 수 있어요.

속성 이름 설명 기본값
unsupported-type-handling 지원되지 않는 컬럼 데이터 타입 처리 방법 구성: IGNORE는 컬럼에 접근 불가, CONVERT_TO_VARCHAR는 컬럼을 무한정 VARCHAR로 변환. 대응하는 카탈로그 세션 속성은 unsupported_type_handling. IGNORE
jdbc-types-mapped-to-varchar 무한정 VARCHAR로 변환할 데이터 타입의 쉼표 구분 목록의 강제 매핑 허용.

SQL 지원 (SQL support)

이 커넥터는 Redshift의 데이터와 메타데이터에 대한 읽기·쓰기 접근을 제공해요. 전역적으로 사용 가능한 문장과 읽기 연산 문장에 더해 이 커넥터는 다음 기능을 지원해요.

  • INSERT (트랜잭션 없는 INSERT 참고)
  • UPDATE (UPDATE 제한 참고)
  • DELETE (DELETE 제한 참고)
  • TRUNCATE
  • 스키마·테이블 관리 (RENAME TO 제한·ALTER SCHEMA 제한 참고)
  • 프로시저
  • 테이블 함수

비트랜잭션 INSERT (Non-transactional INSERT)

이 커넥터는 INSERT 문으로 행 추가를 지원해요. 기본적으로 데이터 삽입은 임시 테이블에 데이터를 쓴 뒤 수행돼요. 이 단계를 건너뛰고 대상 테이블에 직접 써서 성능을 개선할 수 있어요. insert.non-transactional-insert.enabled 카탈로그 속성 또는 대응하는 non_transactional_insert 카탈로그 세션 속성을 true로 설정해요.

이 속성이 활성화되면 삽입 연산 중 예외가 발생하는 드문 경우 데이터가 손상될 수 있다는 점에 유의하세요. 트랜잭션이 비활성화되면 롤백을 수행할 수 없어요.

UPDATE 제한 (UPDATE limitation)

상수 할당과 프레디킷이 있는 UPDATE 문만 지원돼요. 예를 들어 다음 문장은 할당된 값이 상수이므로 지원돼요.

UPDATE table SET col1 = 1 WHERE col3 = 1

산술 표현식, 함수 호출, 기타 비상수 UPDATE 문은 지원되지 않아요. 예를 들어 다음 문장은 SET 명령에 산술 표현식을 쓸 수 없으므로 지원되지 않아요.

UPDATE table SET col1 = col2 + 2 WHERE col3 = 1

테이블 행의 모든 컬럼 값을 동시에 갱신할 수는 없어요. 3개 컬럼 테이블의 경우 다음 문장은 지원되지 않아요.

UPDATE table SET col1 = 1, col2 = 2, col3 = 3 WHERE col3 = 1

DELETE 제한 (DELETE limitation)

WHERE 절이 지정되면, DELETE 연산은 절의 프레디킷을 데이터 소스로 완전히 푸시다운할 수 있을 때만 동작해요.

ALTER TABLE RENAME TO 제한 (ALTER TABLE RENAME TO limitation)

이 커넥터는 여러 스키마에 걸친 테이블 이름 변경을 지원하지 않아요. 예를 들어 다음 문장은 지원돼요.

ALTER TABLE example.schema_one.table_one RENAME TO example.schema_one.table_two

다음 문장은 스키마를 가로질러 테이블을 이름 변경하려 하므로 지원되지 않아요.

ALTER TABLE example.schema_one.table_one RENAME TO example.schema_two.table_two

ALTER SCHEMA 제한 (ALTER SCHEMA limitation)

이 커넥터는 ALTER SCHEMA RENAME 문으로 스키마 이름 변경을 지원해요. ALTER SCHEMA SET AUTHORIZATION은 지원되지 않아요.

프로시저 (Procedures)

system.flush_metadata_cache()

JDBC 메타데이터 캐시를 플러시해요. 예를 들어 다음 system 호출은 example 카탈로그의 모든 스키마에 대한 메타데이터 캐시를 플러시해요.

USE example.example_schema;
CALL system.flush_metadata_cache();
system.execute('query')

execute 프로시저를 사용하면 기반 데이터 소스에서 쿼리를 직접 실행할 수 있어요. 쿼리는 연결된 데이터 소스의 지원 문법을 사용해야 해요. Trino에서 사용할 수 없는 기능에 접근하거나, 결과 셋을 반환하지 않아 query·raw_query 패스스루 테이블 함수와 쓸 수 없는 쿼리를 실행하는 데 이 프로시저를 사용해요. 일반적인 사용 사례는 객체를 만들거나 변경하는 문장으로, 제약, 기본값, 자동 식별자 생성, 인덱스 같은 네이티브 기능을 요구해요. 쿼리는 데이터를 삽입·갱신·삭제하는 문장을 호출할 수도 있고, 결과로 데이터를 반환하지 않아요.

쿼리 텍스트는 Trino가 파싱하지 않고 단지 통과시킬 뿐이므로, 기반 데이터 소스의 어떤 보안·접근 제어만 적용돼요.

다음 예시는 현재 데이터베이스를 example 카탈로그의 example_schema로 설정해요. 그런 다음 그 스키마에서 프로시저를 호출해 query에 할당된 파라미터 값에 표준 SQL 문법을 사용해 your_table 테이블의 your_column에서 기본값을 제거해요.

USE example.example_schema;
CALL system.execute(query => 'ALTER TABLE your_table ALTER COLUMN your_column DROP DEFAULT');

특정 데이터베이스가 이 문법을 지원하는지 확인하고, 연결된 데이터베이스·버전 문서에 따라 적절히 조정하세요.

테이블 함수 (Table functions)

이 커넥터는 Redshift에 접근하기 위한 특정 테이블 함수를 제공해요.

query(varchar) -> table

query 함수는 기반 데이터베이스를 직접 조회할 수 있게 해줘요. 전체 쿼리가 푸시다운되어 Redshift에서 처리되므로 Redshift 고유 문법이 필요해요. 이는 Trino에서 구현되지 않은 네이티브 기능에 접근하거나, 쿼리를 네이티브로 실행하는 게 더 빠른 상황에서 쿼리 성능을 개선하는 데 유용할 수 있어요.

기반 데이터 소스에 전달된 네이티브 쿼리는 결과 셋으로 테이블을 반환해야 해요. 자체 설정을 사용해 쿼리에 대한 검증이나 보안 검사를 수행하는 것은 데이터 소스뿐이에요. Trino는 이런 작업을 수행하지 않아요. 데이터 읽기에만 패스스루 쿼리를 사용하세요.

예를 들어 example 카탈로그를 조회하고 인구 상위 10개 국가를 선택해요.

SELECT
  *
FROM
  TABLE(
    example.system.query(
      query => 'SELECT
        TOP 10 *
      FROM
        tpch.nation
      ORDER BY
        population DESC'
    )
  );

참고

쿼리 엔진은 이 함수 결과의 순서를 보존하지 않아요. 전달된 쿼리에 ORDER BY 절이 있으면 함수 결과가 예상대로 정렬되지 않을 수 있어요.

성능 (Performance)

커넥터에는 다음 섹션에 자세히 설명된 여러 성능 개선이 포함돼요.

S3를 통한 병렬 읽기 (Parallel read via S3)

이 커넥터는 데이터를 S3의 Parquet 파일로 전송하는 Redshift UNLOAD 명령을 지원해요. 이를 통해 커넥터가 사용하는 기본 단일 스레드 JDBC 기반 Redshift 연결 대신 Trino에서 데이터를 병렬로 읽을 수 있어요.

redshift.unload-location에 필요한 S3 위치를 설정해 병렬 읽기를 활성화해요. Parquet 파일은 쿼리 완료와 함께 자동 제거돼요. Redshift 클러스터와 설정된 S3 버킷은 같은 AWS 리전을 사용해야 해요.

속성 값 설명
redshift.unload-location Redshift 클러스터와 같은 AWS 리전의 Amazon S3 안의 쓰기 가능한 위치. Redshift에서 UNLOAD 명령을 사용한 쿼리 처리 중 임시 저장에 사용. 자동 제거 실패에도 정리를 보장하려면 버킷을 정기적으로 자동 정리하는 수명 주기 정책을 구성해요.
redshift.unload-iam-role 선택 사항. UNLOAD 명령에 사용할 Redshift 클러스터에 연결된 IAM Role의 완전 지정 ARN. 이 역할은 Redshift 클러스터에 대한 읽기 접근과 S3 버킷에 대한 쓰기 접근이 있어야 해요. 기본값은 Redshift 클러스터에 연결된 기본 IAM 역할 사용.

unload_enabled 카탈로그 세션 속성을 사용해 특정 쿼리에 대해 클라이언트 세션 중 병렬 읽기를 비활성화하고, 이후 다시 활성화할 수 있어요.

추가로 fs.s3.enabled를 제외한 IAM 키, 역할, 리전 같은 필요한 추가 S3 설정을 정의해요.

더 알아보기 (Learn more)

Redshift는 JDBC 기반 커넥터예요. JDBC 커넥터의 공통 속성과 동작은 PostgreSQL 커넥터에서도 비슷하게 적용돼요.