Redshift 설정
Redshift 설정
dbt-redshift 어댑터의 설정을 정리한 페이지예요. incremental materialization 전략, distkey·sortkey 성능 최적화, 세션 구성(query_group), 데이터셰어링(datasharing), late binding view, materialized view 설정을 소개해요.
출처: dbt 공식 문서
본문
Incremental materialization 전략
dbt-redshift에서 다음 incremental materialization 전략을 지원해요.
append(unique_key가 정의되지 않았을 때 기본값)mergedelete+insert(unique_key가 정의됐을 때 기본값)microbatch
이 전략들은 모두 dbt-postgres에서 상속받은 것이에요.
성능 최적화
sortkey와 distkey 사용하기
Amazon Redshift의 테이블에는 쿼리 성능을 개선하는 두 가지 강력한 최적화(distkey와 sortkey)가 있어요. 이 값들을 모델 수준 설정으로 제공하면 생성된 CREATE TABLE DDL에 해당 설정이 적용돼요. 이 설정들은 view나 ephemeral로 설정된 모델에는 효과가 없어요.
dist는all,even,auto, 또는 키 이름으로 설정할 수 있어요.sort는 정렬 키 목록을 받아요. 예:['reporting_day', 'category']. dbt는 필드가 제공된 순서와 같은 순서로 정렬 키를 만들어요.sort_type은interleaved또는compound로 설정할 수 있어요. 지정하지 않으면sort_type은 기본값compound예요.
정렬 키를 다룰 때는 정렬 키의 효과와 카디널리티에 대한 Redshift 모범 사례를 따르는 걸 적극 권장해요.
Sort와 dist 키는 모델 .sql 파일의 {{ config(...) }} 블록에 추가해야 해요. 예를 들어:
my_model.sql
-- Example with one sort key
{{ config(materialized='table', sort='reporting_day', dist='unique_id') }}
select ...
-- Example with multiple sort keys
{{ config(materialized='table', sort=['category', 'region', 'reporting_day'], dist='received_at') }}
select ...
-- Example with interleaved sort keys
{{ config(materialized='table',
sort_type='interleaved'
sort=['category', 'region', 'reporting_day'],
dist='unique_id')
}}
select ...
distkey와 sortkey에 대한 더 자세한 정보는 Amazon 문서를 참고해요.
- AWS 문서 » Amazon Redshift » 데이터베이스 개발자 가이드 » 테이블 설계 » 데이터 분산 스타일 선택
- AWS 문서 » Amazon Redshift » 데이터베이스 개발자 가이드 » 테이블 설계 » 정렬 키 선택
(dbt v1.12 이상에 적용돼요.)
세션 구성
Redshift 어댑터는 query_group 세션 파라미터를 지원해, dbt 실행이 Redshift Workload Manager(WLM)와 쿼리 로깅(예: STL_QUERY, SVL_QLOG)용 쿼리를 태그할 수 있게 해요. query_group을 프로필 레벨(연결 기본값)로 설정하고 모델 레벨에서 덮어쓸 수 있어요.
-
프로필 레벨 설정
profiles.yml에서query_group을 설정하면 그 프로필로 실행되는 모든 쿼리에 기본값을 적용해요. dbt는 연결을 열 때query_group을 설정해요.profiles.yml
outputs: dev: type: redshift host: CLUSTER_ENDPOINT user: REDSHIFT_USER password: REDSHIFT_PASSWORD dbname: REDSHIFT_DBNAME port: 5439 schema: analytics threads: 4 query_group: QUERY_GROUP_NAME-- models/a_default_group.sql -- Runs under query_group = 'QUERY_GROUP_NAME' (from the profile) select 1 as id -
모델 레벨 설정
모델의
config()블록에query_group을 설정하면 해당 모델 실행 동안 기본값을 임시로 덮어써요. dbt는 모델 실행 중에는 모델 레벨 값을 적용하고, 모델 materialization 후에는 기본값을 복원해요.-- models/b_override_group.sql -- dbt temporarily sets query_group = 'dbt_finance' for this model, then restores the default value {{ config(query_group='dbt_finance') }} select 1 as id
데이터셰어링 (Datasharing) Beta
이전에는 Redshift 어댑터가 관계·스키마·컬럼을 나열하는 메타데이터 작업에 PostgreSQL 호환 카탈로그 테이블(예: pg_*, information_schema)을 사용했어요. 이 테이블들은 현재 연결된 데이터베이스 안의 객체만 표시하므로, Redshift Datasharing에 필요한 크로스 데이터베이스 작업을 못 하게 막았어요.
dbt-redshift v1.11.0rc1부터 profiles.yml에서 datasharing: true를 설정해 크로스 데이터베이스·크로스 클러스터 접근을 활성화할 수 있어요. 활성화하면 dbt-redshift가 메타데이터 쿼리를 Redshift 네이티브 SHOW 시스템 명령으로 전환해요. 그러면 {{ config(database='other_db') }}를 써서 프로필에 지정된 것과 다른 데이터베이스나 클러스터에 모델을 materialize할 수 있어요.
설정 예시:
profiles.yml
company-name:
target: dev
outputs:
dev:
type: redshift
host: hostname.region.redshift.amazonaws.com
...
datasharing: true # default: false
활성화한 뒤에는 모델 설정에 database를 설정해 다른 데이터베이스로 모델을 materialize할 수 있어요. 예를 들어:
{{ config(database='other_db') }}
select * from {{ ref('my_model') }}
datasharing: true일 때 SHOW 명령으로 전환되는 매크로는 다음과 같아요.
| 매크로 | datasharing 없음 |
datasharing 있음 |
|---|---|---|
list_relations_without_caching |
information_schema.tables |
SHOW TABLES FROM SCHEMA |
list_schemas, check_schema_exists |
pg_namespace |
SHOW SCHEMAS FROM DATABASE |
get_columns_in_relation |
information_schema.columns |
SHOW COLUMNS FROM TABLE |
| 카탈로그 쿼리 | pg_class, pg_tables, pg_views |
SHOW TABLES FROM SCHEMA + SVV_REDSHIFT_COLUMNS |
get_relation_last_modified |
information_schema.tables |
SHOW TABLES FROM SCHEMA |
| Grants | pg_user, has_table_privilege() |
SHOW GRANTS ON TABLE |
ra3_node: true도 이 동작을 활성화하며 하위 호환성을 위해 지원돼요. 새 프로젝트에는 대신 datasharing: true를 사용해요.
참고
datasharing을 활성화한 상태에서 pg_* 쿼리가 실행되는 걸 봐도 반드시 버그는 아니에요. 위에 나열한 매크로만 마이그레이션되고, 일부 매크로는 설계상 pg_*에 남아요(예: 의존성 추적용 get_relations, 함수 발견용 list_function_relations_without_caching). 프로젝트의 커스텀 매크로 오버라이드는 영향받지 않아요. pg_* 쿼리가 예상된 것인지 확인하려면 어떤 매크로가 오버라이드되고 어떤 메타데이터 작업이 실행 중인지 확인해요.
datasharing을 사용할 때 다음 제한 사항이 적용돼요.
- 다른 데이터베이스에서 뷰(materialized view 포함)를 만드는 것은 지원되지 않아요.
- 객체에 대한 크로스 데이터베이스 grants는 지원되지 않아요.
- 소스 신선도 확인은 최대 5분까지 지연될 수 있어요.
- 메타데이터 쿼리는 10,000행으로 제한돼요. 데이터베이스에 스키마가 10,000개를 넘거나 스키마에 테이블이 10,000개를 넘으면 dbt 실행에서 예상치 못한 상황이 생길 수 있어요.
- 크로스 데이터베이스 쓰기에는
SNAPSHOT트랜잭션 격리 수준이 필요해요. - 다른 데이터베이스의 테이블을 참조하는 뷰는 late-binding view로 정의해요.
설정 방법은 Redshift 셋업을 참고해요.
Late binding views
Redshift는 의존성에 묶이지 않은 뷰, 즉 late binding views를 지원해요. 이 DDL 옵션은 뷰를 데이터를 선택하는 대상에서 "분리(unbind)"해요. 실제로는 업스트림 뷰나 테이블이 cascade 한정자와 함께 드롭돼도 late-binding 뷰는 함께 드롭되지 않는다는 뜻이에요.
프로덕션 dbt 배포에서 late-binding view를 쓰면 웨어하우스의 데이터 가용성이 크게 향상될 수 있어요. 특히 late-binding view로 materialize되고 최종 사용자가 쿼리하는 모델은 업스트림 모델이 업데이트될 때 드롭되지 않으니까요. 또한 late binding view는 Redshift Spectrum을 통한 외부 테이블과 함께 쓸 수 있어요.
dbt 모델을 late binding view로 materialize하려면 bind: false 설정 옵션을 사용해요.
my_view.sql
{{ config(materialized='view', bind=False) }}
select *
from source.data
모든 뷰를 late-binding으로 만들려면 dbt_project.yml 파일을 이렇게 설정해요.
dbt_project.yml
models:
+bind: false # Materialize all views as late-binding
project_name:
....
Materialized views
Redshift 어댑터는 다음 설정 파라미터와 함께 materialized views를 지원해요.
| 파라미터 | 타입 | 필수 | 기본값 | 변경 모니터링 지원 |
|---|---|---|---|---|
on_configuration_change |
<string> |
아니요 | apply |
n/a |
dist |
<string> |
아니요 | even |
drop/create |
sort |
[<string>] |
아니요 | none |
drop/create |
sort_type |
<string> |
아니요 | sort 없으면 autosort 있으면 compound |
drop/create |
auto_refresh |
<boolean> |
아니요 | false |
alter |
backup |
<string> |
아니요 | true |
n/a |
프로젝트 YAML 파일
dbt_project.yml
models:
<resource-path>:
+materialized: materialized_view
+on_configuration_change: apply | continue | fail
+dist: all | auto | even | <field-name>
+sort: <field-name> | [<field-name>]
+sort_type: auto | compound | interleaved
+auto_refresh: true | false
+backup: true | false
프로퍼티 YAML 파일
models/properties.yml
models:
- name: [<model-name>]
config:
materialized: materialized_view
on_configuration_change: apply | continue | fail
dist: all | auto | even | <field-name>
sort: <field-name> | [<field-name>]
sort_type: auto | compound | interleaved
auto_refresh: true | false
backup: true | false
SQL 파일 설정
models/<model_name>.sql
{{ config(
materialized="materialized_view",
on_configuration_change="apply" | "continue" | "fail",
dist="all" | "auto" | "even" | "<field-name>",
sort=["<field-name>"],
sort_type="auto" | "compound" | "interleaved",
auto_refresh=true | false,
backup=true | false,
) }}
이 파라미터들 중 상당수는 테이블의 것과 대응하며 위에 링크돼 있어요. materialized view에 고유한 파라미터는 auto-refresh와 backup 기능인데, 아래에서 다룰게요.
이 파라미터에 대한 자세한 내용은 Redshift의 문서를 참고해요.
Auto-refresh (자동 새로고침)
| 파라미터 | 타입 | 필수 | 기본값 | 변경 모니터링 지원 |
|---|---|---|---|---|
auto_refresh |
<boolean> |
아니요 | false |
alter |
Redshift는 materialized view에 자동 새로고침 설정을 지원해요. 기본적으로 materialized view는 자동으로 새로고침되지 않아요. dbt는 이 파라미터의 변경을 모니터링하고 ALTER 문으로 적용해요.
파라미터에 대한 더 자세한 정보는 Redshift 문서에서 확인해요.
Backup (백업)
| 파라미터 | 타입 | 필수 | 기본값 | 변경 모니터링 지원 |
|---|---|---|---|---|
backup |
<boolean> |
아니요 | true |
n/a |
Redshift는 객체 레벨에서 클러스터의 backup 설정을 지원해요. 이 파라미터는 materialized view가 클러스터 스냅샷의 일부로 백업되어야 하는지 식별해요. 기본적으로 materialized view는 클러스터 스냅샷 중에 백업돼요. dbt는 이 파라미터가 Redshift 안에서 쿼리할 수 없어서 모니터링하지 못해요. 값이 바뀌면 materialized view는 설정하기 위해 --full-refresh를 거쳐야 해요.
이 파라미터에 대한 더 자세한 정보는 Redshift 문서에서 확인해요.
제한 사항
대부분의 데이터 플랫폼처럼 materialized view에도 제한 사항이 있어요. 주목할 만한 것 몇 가지:
- materialized view는 뷰, 임시 테이블, 사용자 정의 함수, late-binding 테이블을 참조할 수 없어요.
- materialized view가 변경 가능한 함수, 외부 스키마, 또는 다른 materialized view를 참조하면 자동 새로고침을 쓸 수 없어요.
materialized view 제한 사항에 대한 더 자세한 정보는 Redshift 문서에서 확인해요.
유닛 테스트 제한 사항
-
Redshift는 공통 테이블 표현식(CTE) 안의 SQL에
LISTAGG,MEDIAN,PERCENTILE_CONT같은 함수가 있으면 유닛 테스트를 지원하지 않아요. 이 함수들은 사용자가 만든 테이블에 대해 실행해야 해요. dbt는 주어진 행들을 CTE의 일부로 결합하는데, Redshift는 이를 지원하지 않아요.미래에 이 패턴을 지원하려면 dbt는 입력 픽스처를 CTE로 보간하는 대신 테이블로 "materialize"해야 해요. 이 기능에 관심이 있다면 GitHub 이슈에서 참여해 주세요: dbt-labs/dbt#8499
-
Redshift는 모델과 다른 데이터베이스의 소스에 의존하는 유닛 테스트를 지원하지 않아요. 자세한 내용은 GitHub 이슈를 참고해요: https://github.com/dbt-labs/dbt-redshift/issues/995
더 알아보기 (Learn more)
- Late binding views — AWS 문서
- Redshift data distribution styles — distkey 선택
- Redshift sort keys — sortkey 선택