Amazon Redshift에서 사용량이 높거나 가득 찬 디스크 사용량 문제를 해결하려면 어떻게 해야 하나요?

7분 분량
0

Amazon Redshift의 디스크 사용량이 높거나 가득 찼으며 이 문제를 해결하고 싶습니다.

해결 방법

높은 디스크 사용량 오류는 다음을 포함한 여러 가지 요소에 따라 달라질 수 있습니다.

  • 분포 및 정렬 키
  • 쿼리 처리
  • VARCHAR(MAX) 열이 포함된 테이블
  • 높은 열 압축
  • 유지관리 작업
  • 교차 조인을 사용한 데카르트 곱
  • 최소 테이블 크기
  • Tombstone 블록
  • 대용량 파일 복사

분포 및 정렬 키

테이블 분포 스타일, 분포 키, 정렬 키 선택을 검토합니다. 한 노드에 다른 노드보다 더 많은 데이터가 있는 분포 스큐가 있는 테이블의 경우 디스크 노드가 가득 찰 수 있습니다. 편향 분포 스타일이 포함된 테이블이 있다면 분포 스타일을 더욱 균일한 분포로 변경하세요. 분포 및 행 편향은 쿼리 실행 시 스토리지 편향과 중간 행 집합에 영향을 미칠 수 있습니다. 분포 키 및 정렬 키에 대한 자세한 내용은 Amazon Redshift Engineering의 고급 테이블 설계 플레이북: 서문, 전제 조건, 우선순위 설정을 참조하세요.

분포 키의 기수성을 확인하려면 다음 쿼리를 실행하십시오.

SELECT <distkey column>, COUNT(*) FROM <schema name>.<table with distribution skew> GROUP BY <distkey column> HAVING COUNT(*) > 1 ORDER BY 2 DESC;

참고: 정렬 단계를 피하려면 ORDER BY 절에서 SORT KEY 열을 사용하십시오. 정렬 단계에서 메모리를 과도하게 사용하여 디스크 유출이 발생할 수 있습니다. 자세한 내용은 정렬 키 작업을 참조하세요.

필터링한 결과 집합에서 카디널리티가 높은 열을 선택하여 해당 데이터 분포를 봅니다. 표의 분포 스타일에 대한 자세한 내용은 최상의 분포 스타일 선택을 참조하십시오.

분포 키에서 데이터베이스 블록을 클러스터로 매핑하는 방법을 확인하려면 Amazon Redshift table_inspector.sql 유틸리티를 참조하십시오.

쿼리 처리

쿼리에 할당된 메모리를 검토하십시오. 쿼리가 처리되는 동안 쿼리 중간 결과를 임시 블록에 저장할 수 있습니다. 사용 가능한 메모리가 충분하지 않을 경우, 테이블에서 디스크 유출이 발생합니다. 중간 결과 집합이 압축되지 않으며, 이는 사용 가능한 디스크 공간에 영향을 미칩니다. 자세한 내용은 쿼리에 할당되는 메모리 부족을 참조하십시오.

Amazon Redshift는 분포가 균일하고 임시 테이블에 대해 열 인코딩이 없는 테이블 구조를 기본으로 사용합니다. 하지만 SELECT...INTO 구문을 사용할 경우, CREATE 문을 사용하세요. 자세한 내용은 Amazon Redshift 성능 튜닝을 위한 10가지 기법을 참조하세요. 팁 #6: 임시 테이블의 비효율적인 사용 해결 아래의 지침을 따르세요.

쿼리에 메모리가 부족하게 할당되면 is_diskbased 값이 “true”인 SVL_QUERY_SUMMARY에서 단계가 보일 수 있습니다. 이 문제를 해결하려면 쿼리 슬롯 개수를 늘려 더 많은 메모리를 쿼리에 할당하십시오. 쿼리 슬롯을 임시로 늘리는 방법에 대한 자세한 내용은 wlm_query_slot_count 또는 WLM을 튜닝하여 혼합된 워크로드를 실행하십시오. 또한, WLM 쿼리 모니터링 규칙을 사용하여 과도한 처리 로드에 대응하고 I/O 집약적 쿼리를 식별할 수 있습니다.

VARCHAR(MAX) 열이 포함된 테이블

VARCHAR 또는 CHARACTER VARYING 열에서 데이터가 디스크에 저장될 때 누락될 수 있는 후행 공백을 검사합니다. 쿼리 처리 중에 후행 공백이 메모리의 전체 길이를 차지할 수 있습니다(VARCHAR의 최댓값은 65535). 최대한 작은 열 크기를 사용하는 것이 좋습니다.

최대 열 너비로 테이블 목록을 생성하려면 다음의 쿼리를 실행합니다.

SELECT database, schema || '.' || "table" AS "table", max_varchar FROM svv_table_info WHERE max_varchar > 150 ORDER BY 2;

넓은 VARCHAR 테이블 열의 실제 길이를 식별하고 표시하려면 다음의 쿼리를 실행합니다.

SELECT max(octet_length (rtrim(column_name))) FROM table_name;

이 쿼리의 출력에서 길이가 사용 사례에 적합한지 확인합니다. 기둥이 최대 길이이고 필요한 길이를 초과하는 경우, 필요한 최소 크기로 길이를 조정합니다.

테이블 설계에 대한 자세한 내용은 테이블 설계를 위한 Amazon Redshift 모범 사례를 검토하세요.

높은 열 압축

ANALYZE COMPRESSION을 사용하거나 Amazon Redshift의 자동 테이블 최적화 기능을 사용하여 모든 열(정렬 키 제외)을 인코딩합니다. Amazon Redshift는 열 인코딩을 제공합니다. 이 기능을 사용하면 읽기 성능이 향상되고 전체 스토리지 사용량이 줄어들지만 그래도 사용하는 것이 가장 좋은 방법입니다.

유지 관리 작업

Amazon Redshift 데이터베이스에서 데이터베이스 테이블을 정기적으로 분석하고 비우세요. 통계가 누락된 테이블에 대해 실행 중인 쿼리를 식별합니다. 통계가 누락된 테이블에 대해 쿼리가 실행되지 않도록 하면 Amazon Redshift가 불필요한 테이블 행을 스캔하지 않아도 됩니다. 이는 쿼리 처리를 최적화하는 데도 도움이 됩니다.

참고: VACUUM, DEEP COPY 등의 유지관리 작업은 정렬 작업에 대한 임시 스토리지 공간을 사용하므로 디스크 사용량이 급증할 것으로 예상됩니다.

예를 들어 다음의 쿼리는 Amazon Redshift에서 오래된 통계를 식별하는 데 도움이 됩니다.

SELECT * FROM svv_table_info WHERE stats_off > 10 ORDER BY size DESC;

또한 ANALYZE 명령을 사용하여 테이블 통계를 보고 분석할 수 있습니다.

유지 보수 작업에 대한 자세한 내용은 Amazon Redshift 분석 및 정리 스키마 유틸리티를 참조하십시오.

교차 조인을 사용한 데카르트 곱

쿼리의 EXPLAIN 계획을 사용하여 데카르트 곱으로 쿼리를 검색하십시오. 데카르트 곱은 서로 관련이 없고, 더 많은 블록을 생성할 수 있는 교차 조인입니다. 이러한 교차 조인은 메모리 사용률이 높아지고 더 많은 테이블이 디스크에 유출될 수 있습니다. 교차 조인이 JOIN 조건을 공유하지 않을 경우, 조인은 두 테이블의 데카르트 곱을 생성합니다. 그러면 한 테이블의 모든 행이 다른 테이블의 모든 행과 결합됩니다.

교차 조인은 중첩된 루프 조인으로도 실행될 수 있고, 이는 처리하는 데 가장 오랜 시간이 걸립니다. 중첩된 루프 조인은 전체 디스크 사용량이 급증할 수 있습니다. 자세한 내용은 중첩 루프가 포함된 쿼리 식별을 참조하십시오.

최소 테이블 크기

동일한 테이블이라도 클러스터마다 크기가 다를 수 있습니다. 그러면 열 개수, 테이블에 SORTKEY가 있는지 여부, 채워진 슬라이스 수에 따른 최소 테이블 크기가 결정됩니다. 최근에 Amazon Redshift 클러스터의 크기를 조정했다면 전체 디스크 스토리지가 변경될 수 있습니다. 이는 슬라이스 개수가 변경되면 발생합니다. 또한, Amazon Redshift는 각 테이블에서 사용하는 테이블 세그먼트 수를 계산합니다. 자세한 내용은 Amazon Redshift 클러스터의 테이블이 예상보다 더 많거나 적은 디스크 스토리지 공간을 사용하는 이유는 무엇입니까?

Tombstone 블록

삭제 표시 블록은 Amazon Redshift 테이블에 대한 쓰기 트랜잭션이 발생하고 동시 읽기가 있을 때 생성됩니다. Amazon Redshift는 쓰기 작업 전에 블록을 유지하여 동시 읽기 작업을 일관되게 유지합니다. Amazon Redshift 블록은 변경할 수 없습니다. 모든 삽입, 업데이트 또는 삭제 작업으로 새 블록 세트가 생성되므로 오래된 블록은 삭제 표시됩니다.

때로는 장기 실행 테이블 트랜잭션으로 인해 커밋 단계에서 삭제 표시를 지울 수 없습니다. 또한, 동시에 실행되는 ETL 로드가 너무 많을 때 삭제 표시를 지우지 못할 수 있습니다. Amazon Redshift는 트랜잭션이 시작되는 시점부터 데이터베이스를 모니터링하기 때문에 데이터베이스에 기록된 모든 테이블도 삭제 표시 블록을 유지합니다. 장기 실행되는 테이블 트랜잭션이 여러 로드에 걸쳐 정기적으로 발생할 경우, 삭제 표시가 누적되어 디스크 가득 참 오류가 발생할 수 있습니다.

또한, 커밋 명령을 실행하여 Amazon Redshift가 삭제 표시 블록에 대한 분석을 실행하도록 강제할 수 있습니다.

활성화된 장기 실행 쿼리가 있을 경우, commit 명령을 사용하여 쿼리를 종료(및 모든 후속 블록을 해제)할 수 있습니다.

begin;
create table a (id int);
insert into a values(1);
commit;
drop table a;

삭제 표시 블록을 확인하려면 다음의 쿼리를 실행하세요.

select trim(name) as tablename, count(case when tombstone > 0 then 1 else null end) as tombstones from svv_diskusage group by 1 having count(case when tombstone > 0 then 1 else null end) > 0 order by 2 desc;

대용량 파일 복사

COPY 작업 중에 충분한 스토리지 공간이 남아 있더라도 디스크 가득 참 오류가 발생할 수 있습니다. 정렬 작업이 디스크로 유출되어 임시 블록이 생성되는 경우에 이 오류가 발생합니다.

Disk Full(디스크 가득 참) 오류 메시지가 발생하면 STL_DISK_FULL_DIAG 테이블을 검사하세요. 오류가 발생한 쿼리 ID와 생성된 임시 블록을 확인합니다.

select '2000-01-01'::timestamp + (currenttime/1000000.0)* interval '1 second' as currenttime,node_num,query_id,temp_blocks from pg_catalog.stl_disk_full_diag;

자세한 모범 사례는 Amazon Redshift 데이터 로드 모범 사례를 참조하세요.

추가 문제 해결

Amazon Redshift 콘솔의 [성능(Performance)] 탭에서 디스크 공간 비율을 확인하십시오. 각 클러스터 노드의 경우, Amazon Redshift가 일반 디스크 용량보다 큰 추가 디스크 공간을 제공합니다.

사용률이 갑자기 급증하는 경우, STL_QUERY를 사용하여 실행 중인 활동 및 작업을 식별하십시오. 디스크 유출 시 실행 중인 쿼리는 다음과 같습니다.

select * from stl_query where starttime between '2018-01-01 00:30:00' and '2018-01-01 00:40:00';

참고: 급증이 발생한 시간으로 값을 업데이트합니다.

상위 20개 디스크 유출 쿼리를 식별하려면 다음 쿼리를 실행하십시오.

select A.userid, A.query, blocks_to_disk, trim(B.querytxt) text from stl_query_metrics A, stl_query B where A.query = B.query and segment=-1 and step = -1 and max_blocks_to_disk > 0 order by 3 desc limit 20;

열 값 blocks_to_disk를 보고 디스크 누출을 식별합니다. 필요한 경우 너무 많이 누출된 쿼리를 종료합니다. 그런 다음 쿼리를 다시 실행하기 전에 쿼리에 추가 메모리를 할당합니다. 자세한 내용은 STL_QUERY_METRICS를 참조하세요.

쿼리가 디스크에 올바르게 쓰고 있는지 확인하려면 다음 쿼리를 실행하세요.

SELECT q.query, trim(q.cat_text)
FROM (
SELECT query,
replace( listagg(text,' ') WITHIN GROUP (ORDER BY sequence), '\\n', ' ') AS cat_text
FROM stl_querytext
WHERE userid>1
GROUP BY query) q
JOIN (
SELECT distinct query
FROM svl_query_summary
WHERE is_diskbased='t' AND (LABEL ILIKE 'hash%' OR LABEL ILIKE 'sort%' OR LABEL ILIKE 'aggr%' OR LABEL ILIKE 'save%' OR LABEL ILIKE 'window%' OR LABEL ILIKE 'unique%')
AND userid > 1) qs
ON qs.query = q.query;

이 명령은 디스크로 유출되는 쿼리도 식별합니다.


관련 정보

성능

Amazon Redshift 시스템 개요

AWS 공식
AWS 공식업데이트됨 일 년 전