티스토리 뷰

개발/Cloud (AWS)

AWS Redshift: WLM, Queue, and Slot

Jaeyeon Baek 2024. 7. 20. 13:52

Redshift는 Workload management(WLM) 설정을 통해 큐(queue)와 슬롯(slot)이라는 개념을 제공합니다. 넓은 범주에서 이야기하면 한 개에 큐 안에는 여러 개의 슬롯이 존재할 수 있습니다. 그리고 슬롯은 쿼리 실행의 동시성을 나타낸다고 보시면 됩니다. 즉, 슬롯 개수만큼 쿼리가 동시에 실행될 수 있는 거죠. 그렇다고 쿼리 속도가 슬롯에 독립적으로 보장된다는 말은 아닙니다. 클러스터 전체에서 사용하는 메모리를 나눠서 사용하는 구조라서요. 

큐는 실행을 기다리는 쿼리 그룹을 나타내는 논리적 구성입니다. 큐 종류는 다음과 같습니다.
- 삭제할 수 없는 default queue 1개
- 사용자가 추가로 정의할 수 있는 큐 7개
- AWS 콘솔 상에 나타나지 않는 superuser를 위한 큐 1개

총 9개인데 보통 superuser 큐는 포함시키지 않기 때문에 WLM은 8개의 큐를 가질 수 있다고 이야기합니다.

한 개의 큐 안에 기본적으로 다섯 개의 슬롯이 존재한다

 

여기서 slot은 쿼리에 할당되는 컴퓨팅 용량의 단위 입니다. 큐에 들어온 쿼리는 기본적으로 1개의 slot을 사용하게 되는데요. 성능을 더 끌어올려야 하는 경우에는 1개 이상의 slot을 지정해서 사용하도록 해야 합니다. slot 1개가 100 MiB의 메모리를 갖는다고 가정하면 250 MiB를 사용하는 쿼리는 돌릴 수가 없는 거죠. 이때는 세션에 slot을 3개 할당하고 쿼리를 실행하면 최대 300 MiB까지 메모리를 사용할 수 있게 됩니다(방법은 글의 뒷부분에서 다룹니다). 하지만 이렇게 1개 이상의 slot을 사용하기 위해서는 수동 WLM(Manual WLM)을 사용해야 합니다.

WLM은 자동과 수동 두 가지 방식을 지원합니다.

기본적으로는 자동으로 설정되어 있다

 

자동과 수동의 가장 큰 차이점은 큐의 메모리를 사용자가 직접 컨트롤할 수 있느냐입니다. 조금 아이러니하죠? CPU 사용량을 조절하는 게 아니라 메모리라니. 그런데 생각해 보면 DW 클러스터 안에 노드 간에 데이터 통신, 쿼리 결과 집계 등을 생각하면 모두 메모리 위에서 이동될 테니 납득되는 것 같기도 합니다.

아무튼, 그럼 수동의 경우 예를 들어봅시다. 기본 큐를 포함해서 총 3개의 큐를 운영한다고 했을 때 메모리 퍼센트 총합을 100%로 해서 큐에 메모리를 할당할 수 있습니다. 당연한 이야기지만 모든 큐에 설정된 메모리 퍼센트의 합이 100을 넘을 수 없습니다.

ETL 큐, 서비스 큐, 사용자를 위한 큐. 이렇게 세 개의 큐가 있다고 가정해 봅시다. ETL 큐에 50%, 서비스 큐에 40% 그리고 사용자 큐에 10% 이렇게 나눠서 설정할 수 있겠습니다. 일반적으로 분석가 등 사용자가 실행하는 쿼리가 다른 큐에 비해 빠르게 결과를 낼 필요는 없기 때문입니다. 정말 급한 쿼리라면 superuser 큐를 사용해야 합니다. ( 더 안전하게 운영하려면 Redshift Data Share를 통해 Redshift 클러스터를 분리해서 사용하는 게 맞습니다 )

수동 WLM에서 메모리 직접 설정

 

메모리 설정 외에도 Concurrency on main 설정을 통해 슬롯의 개수를 조정할 수 있습니다. 모든 큐에 정의된 슬롯의 개수의 합은 50을 넘을 수 없습니다. 그리고 Concurrency scaling mode를 통해 클러스터를 확장시킬 수 있습니다. 필요시에 클러스터가 확장되는 개념인데 분(minute) 당 비용이 과금되기 때문에 과금 범위를 예상하기 어렵습니다. 만약 Redshift에 끊임없이 쿼리가 실행된다면 scaling mode를 활성화했을 때 아마도 확장 상태가 계속 유지되지 않을까 하는 우려가 됩니다(실제로 그렇다는 이야기는 아닙니다. 테스트를 못 해봤네요). 

한편 자동 WLM(Automatic WLM)의 경우 메모리는 설정할 수 없고 대신 Query priority를 통해 큐의 우선순위를 설정할 수 있습니다.

자동 WLM에서 쿼리 우선순위 설정

 

큐에는 User groups, Query groups 조건을 걸 수 있습니다. 즉, 두 개 조건 중에 하나라도 매칭되는 쿼리가 입력되면 해당 큐에서 처리되는 방식입니다. 예를 들어 ETL_QUEUE 가 있고 User group이 ETL로 설정되어 있다고 가정합니다. 그리고 ETL 그룹 안에는 etl_user 유저가 들어있다고 생각해 보죠. 그럼 etl_user 계정으로 실행되는 모든 쿼리는 ETL_QUEUE에서 처리되게 됩니다.

ETL 그룹

 

유저 그룹은 아래처럼 생성할 수 있습니다.

create group ETL with user etl_user;
create group service with user service_a,service_b,service_c;

 

 

alter 쿼리를 사용해서 그룹에 사용자를 추가할 수도 있습니다.

alter group admin_group add user user_a, user_b, user_c;

 

 

Query groups을 살펴봅시다. 큐에 priority라는 이름으로 Query groups가 설정되어 있고 해당 규칙으로 쿼리를 실행하려면 아래와 같이 set query_group을 사용할 수 있습니다.

set query_group to 'priority';
select count(*)from stv_blocklist;
select query, elapsed, substring from svl_qlog order by query desc limit 5; 
reset query_group;

 

이렇게 되면 priority가 설정된 큐로 지정되어 쿼리가 실행되게 됩니다. 여러 개의 큐가 존재하고 각 큐마다 User groups, Query groups 설정이 복합적으로 들어있다면 어떻게 동작할까요? 쿼리가 들어오면 다음 규칙에 따라 큐가 할당됩니다.

대기열 할당 규칙

 

여기까지 자동 WLM의 콘셉트에 대해서 살펴봤는데요. 수동(Manual)으로 WLM을 구성하게 되는 경우 큐 마다 메모리 사용량(%)을 직접 지정할 수 있게 됩니다. 그리고 쿼리당 slot 개수를 지정할 수 있게 되기 때문에 복잡하고 무거운 쿼리를 실행할 수 있게 되는 거죠. 쿼리당 slot 개수 지정은 아래와 같이 사용할 수 있습니다.

set wlm_query_slot_count to 3;

 

이렇게 지정된 구성은 동일한 세션에서만 유효합니다. 재설정은 아래와 같이 진행할 수 있습니다.

reset wlm_query_slot_count;

 

# 마무리

일반적인 경우라면 자동 WLM(Automatic WLM)으로 충분할 겁니다. 쿼리의 우선순위를 조정하는 것만으로도 대부분의 비즈니스 목표를 달성할 수 있을 테니까요. 하지만 세세한 조정이 필요한 경우 수동 WLM(Manual WLM)을 사용해야 합니다. 서두에 언급한 것처럼 무거운 쿼리를 실행해야 하는 경우에는 세션에 slot 개수를 지정해줘야 하니까요. 그렇다고 slot을 무지성으로 할당해서도 안됩니다. 그럼 모든 slot을 점유해서 다른 쿼리들은 대기 중인 상태로 빠질 테니까요. 다른 서비스에서 사용할 slot은 충분히 남겨두고 필요한 만큼의 slot을 사용하는 게 좋습니다. 수동 WLM은 미세하게 조율해서 사용해야 하는 것들이 많기 때문에 전문가 모드라고 볼 수 있겠네요. 비즈니스를 이해하고 slot을 잘 분해서 사용하실 수 있길 바랍니다. 

댓글
최근에 올라온 글
최근에 달린 댓글
글 보관함
Total
Today
Yesterday