Amazon Redshift에서 클러스터 또는 쿼리 성능 문제를 해결하려면 어떻게 해야 하나요?

최종 업데이트 날짜: 2021년 3월 11일

Amazon Redshift 클러스터의 쿼리 성능이 저하되었습니다.  클러스터 또는 쿼리 성능 문제를 해결하고 개선하려면 어떻게 해야 하나요?

간략한 설명

Amazon Redshift 클러스터에서 성능 문제가 발생하는 경우 다음 접근 방법을 고려합니다.

  • 클러스터 성능 지표를 모니터링합니다.
  • Amazon Redshift Advisor 권장 사항을 확인합니다.
  • 쿼리 실행 알림 및 과도한 디스크 사용량을 검토합니다.
  • 잠금 문제 및 장기 실행 세션 또는 트랜잭션을 확인합니다.
  • 워크로드 관리(WLM) 구성을 확인합니다.
  • 클러스터 노드 하드웨어 유지 관리 및 성능을 확인합니다.

해결 방법

클러스터 성능 지표 모니터링

Amazon Redshift 클러스터에서 성능 문제가 발견되면 클러스터 성능 지표와 그래프를 검토합니다. 클러스터 성능 지표 및 그래프를 사용하면 성능 저하의 근본 원인을 좁힐 수 있습니다. Amazon Redshift 콘솔에서 성능 데이터를 보고 시간에 따른 클러스터 성능을 비교할 수 있습니다.

이러한 지표가 증가하면 Amazon Redshift 클러스터에서 워크로드와 리소스 경합이 높음을 나타낼 수 있습니다. 성능 지표 모니터링에 대한 자세한 내용은 Amazon CloudWatch 지표를 사용하여 Amazon Redshift 모니터링을 참조하세요.

Amazon Redshift 콘솔에서 워크로드 실행 분석를 통해 특정 쿼리 및 실행 시간을 검토합니다. 예를 들어, 쿼리 계획 시간이 늘어날 경우 쿼리가 잠금을 기다리고 있음을 나타낼 수 있습니다.

Amazon Redshift Advisor 권장 사항 확인

Amazon Redshift Advisor에서는 Amazon Redshift 클러스터 성능을 개선하고 최적화하는 방법에 대한 권장 사항을 제공합니다. Amazon Redshift Advisor는 Amazon Redshift 콘솔에서 무료로 사용할 수 있습니다. Amazon Redshift Advisor 권장 사항을 사용하여 클러스터의 잠재적 개선 영역을 알아봅니다. 권장 사항은 일반적인 사용 패턴과 Amazon Redshift 모범 사례를 기반으로 합니다.

쿼리 실행 알림 및 과도한 디스크 사용량 검토

쿼리를 실행하는 동안 Amazon Redshift는 쿼리 성능을 기록하고 쿼리가 효율적으로 실행되고 있는지 여부를 나타냅니다. 쿼리가 비효율적으로 식별되면 Amazon Redshift는 쿼리 ID를 기록하고 쿼리 성능 개선을 위한 권장 사항을 제공합니다. 이러한 권장 사항은 내부 시스템 테이블인 STL_ALERT_EVENT_LOG에 로깅됩니다.

느리거나 비효율적인 쿼리가 관찰되면 STL_ALERT_EVENT_LOG 항목을 확인합니다. STL_ALERT_EVENT_LOG 테이블에서 정보를 검색하려면 다음 쿼리를 사용합니다.

SELECT TRIM(s.perm_table_name) AS TABLE
    , (SUM(ABS(DATEDIFF(SECONDS, Coalesce(b.starttime, d.starttime, s.starttime), CASE
            WHEN COALESCE(b.endtime, d.endtime, s.endtime) > COALESCE(b.starttime, d.starttime, s.starttime)
            THEN COALESCE(b.endtime, d.endtime, s.endtime)
        ELSE COALESCE(b.starttime, d.starttime, s.starttime)
    END))) / 60)::NUMERIC(24, 0) AS minutes
    , SUM(COALESCE(b.ROWS, d.ROWS, s.ROWS)) AS ROWS
    , TRIM(SPLIT_PART(l.event, ':', 1)) AS event
    , SUBSTRING(TRIM(l.solution), 1, 60) AS solution
    , MAX(l.QUERY) AS sample_query
    , COUNT(DISTINCT l.QUERY)
FROM STL_ALERT_EVENT_LOG AS l
LEFT JOIN stl_scan AS s
    ON s.QUERY = l.QUERY AND s.slice = l.slice AND s.segment = l.segment
LEFT JOIN stl_dist AS d
    ON d.QUERY = l.QUERY AND d.slice = l.slice AND d.segment = l.segment 
LEFT JOIN stl_bcast AS b
    ON b.QUERY = l.QUERY AND b.slice = l.slice AND b.segment = l.segment 
WHERE l.userid > 1 AND l.event_time >= DATEADD(DAY, -7, CURRENT_DATE)
GROUP BY 1, 4, 5
ORDER BY 2 DESC, 6 DESC;

이 쿼리는 쿼리 ID와 클러스터에서 실행되는 쿼리에 대한 가장 일반적인 문제 및 문제 발생을 나열합니다.

다음은 쿼리의 출력 예제와 알림이 트리거된 이유를 설명하는 정보입니다.

table | minutes | rows |               event                |                        solution                        | sample_query | count
-------+---------+------+------------------------------------+--------------------------------------------------------+--------------+-------
NULL  |    NULL | NULL | Nested Loop Join in the query plan | Review the join predicates to avoid Cartesian products |      1080906 |     2

쿼리 튜닝을 위한 진단 쿼리를 확인하여 쿼리 성능을 검토합니다. 쿼리 작업이 효율적으로 실행되도록 설계되었는지 확인합니다. 예를 들어, 모든 조인 작업이 효과적이지는 않습니다. 중첩 루프 조인은 가장 비효과적인 조인 유형이며, 가능하면 피해야 합니다. 이 유형은 쿼리 실행 시간을 크게 늘리기 때문입니다.

중첩 루프를 수행하는 쿼리를 식별하여 문제를 진단할 수 있습니다. 일반적인 디스크 사용량 문제를 진단하는 방법에 대한 자세한 내용은 Amazon Redshift를 사용하여 디스크 사용량이 높거나 디스크가 가득 차는 문제를 해결하려면 어떻게 해야 하나요?를 참조하세요.

잠금 문제 및 장기 실행 세션 또는 트랜잭션 확인

클러스터에서 쿼리를 실행하기 전에 쿼리 실행과 관련된 테이블에서 테이블 수준 잠금을 가져와야 할 수 있습니다. 쿼리가 "중단"된 상태로 나타나거나 쿼리 실행 시간이 급증하는 경우가 있을 수 있습니다. 쿼리 실행 시간이 급증하는 경우 잠금 문제가 원인일 수 있습니다. 지연된 쿼리 실행 시간에 대한 자세한 내용은 Amazon Redshift에서 쿼리 계획 시간이 너무 높은 이유는 무엇인가요?를 참조하세요.

테이블이 현재 다른 프로세스 또는 쿼리에 의해 잠겨 있는 경우 쿼리를 진행할 수 없습니다. 그 결과, STV_INFLIGHT 테이블에 쿼리가 나타나지 않습니다. 대신, 실행 중인 쿼리는 STV_RECENTS 테이블에 나타납니다.

때때로 장기 실행 트랜잭션으로 인해 중단된 쿼리가 나타나기도 합니다. 장기 실행 트랜잭션이 쿼리 성능에 영향을 미치지 않도록 하려면 다음 팁을 고려하세요.

  • 장기 실행 세션을 식별하고 즉시 종료합니다. STL_SESSIONSSVV_TRANSACTIONS 테이블을 사용하여 장기 실행 트랜잭션을 확인할 수 있습니다.
  • Amazon Redshift에서 쿼리를 빠르고 효율적으로 처리할 수 있도록 쿼리를 설계합니다.

참고: 장기 실행 트랜잭션은 디스크 공간을 회수하는 VACUUM 기능에도 영향을 주기 때문에, 이로 인해 고스트 행 또는 커밋되지 않은 행이 많이 생길 수 있습니다. 쿼리로 스캔되는 고스트 행은 쿼리 성능에 영향을 줄 수 있습니다.

테이블 잠금이 발생할 수 있는 장기 실행 세션을 식별하는 방법에 대한 자세한 내용은 Amazon Redshift에서 잠금을 감지하고 해제하려면 어떻게 해야 하나요?를 참조하세요.

워크로드 관리(WLM) 구성 확인

WLM 구성에 따라 쿼리가 즉시 실행되기 시작하거나 일정 시간 대기하며 시간을 소비할 수 있습니다. 목표는 항상 쿼리가 실행을 위한 대기 시간을 최소화하는 것입니다. 대기열을 정의하려는 경우 WLM 메모리 할당을 확인합니다.

며칠 동안 클러스터의 WLM 대기열을 확인하려면 다음 쿼리를 사용합니다.

SELECT *, pct_compile_time + pct_wlm_queue_time + pct_exec_only_time + pct_commit_queue_time + pct_commit_time AS total_pcnt
FROM 
(SELECT IQ.*,
   ((IQ.total_compile_time*1.0 / IQ.wlm_start_commit_time)*100)::DECIMAL(5,2) AS pct_compile_time,
   ((IQ.wlm_queue_time*1.0 / IQ.wlm_start_commit_time)*100)::DECIMAL(5,2) AS pct_wlm_queue_time,
   ((IQ.exec_only_time*1.0 / IQ.wlm_start_commit_time)*100)::DECIMAL(5,2) AS pct_exec_only_time,
   ((IQ.commit_queue_time*1.0 / IQ.wlm_start_commit_time)*100)::DECIMAL(5,2) pct_commit_queue_time,
   ((IQ.commit_time*1.0 / IQ.wlm_start_commit_time)*100)::DECIMAL(5,2) pct_commit_time
  FROM 
    (SELECT trunc(d.service_class_start_time) AS DAY,
       d.service_class,
       d.node,
       COUNT(DISTINCT d.xid) AS count_all_xid,
       COUNT(DISTINCT d.xid) -COUNT(DISTINCT c.xid) AS count_readonly_xid,
       COUNT(DISTINCT c.xid) AS count_commit_xid,
       SUM(compile_us) AS total_compile_time,
       SUM(datediff (us,CASE WHEN d.service_class_start_time > compile_start THEN compile_start ELSE d.service_class_start_time END,d.queue_end_time)) AS wlm_queue_time,
       SUM(datediff (us,d.queue_end_time,d.service_class_end_time) - compile_us) AS exec_only_time,
       nvl(SUM(datediff (us,CASE WHEN node > -1 THEN c.startwork ELSE c.startqueue END,c.startwork)),0) commit_queue_time,
       nvl(SUM(datediff (us,c.startwork,c.endtime)),0) commit_time,
       SUM(datediff (us,CASE WHEN d.service_class_start_time > compile_start THEN compile_start ELSE d.service_class_start_time END,d.service_class_end_time) + CASE WHEN c.endtime IS NULL THEN 0 ELSE (datediff (us,CASE WHEN node > -1 THEN c.startwork ELSE c.startqueue END,c.endtime)) END) AS wlm_start_commit_time
     FROM 
       (SELECT node, b.*
          FROM (SELECT -1 AS node UNION SELECT node FROM stv_slices) a,
               stl_wlm_query b
         WHERE queue_end_time > '2005-01-01'
           AND exec_start_time > '2005-01-01') d
     LEFT JOIN stl_commit_stats c USING (xid,node)
     JOIN (SELECT query, MIN(starttime) AS compile_start, SUM(datediff (us,starttime,endtime)) AS compile_us
           FROM svl_compile
           GROUP BY 1) e USING (query)
    WHERE d.xid > 0
      AND d.service_class > 4
      AND d.final_state <> 'Evicted'
 GROUP BY trunc(d.service_class_start_time),
          d.service_class,
          d.node
 ORDER BY trunc(d.service_class_start_time),
          d.service_class,
          d.node) IQ)
WHERE node < 0 ORDER BY 1,2,3;

이 쿼리는 총 트랜잭션 수(xid), 실행 시간, 대기 시간 및 커밋 대기열 세부 정보를 제공합니다. 커미트 대기열 세부 정보를 확인하여 빈번한 커밋이 워크로드 성능에 영향을 미치는지 확인할 수 있습니다.

특정 시점에 실행되는 쿼리의 세부 정보를 확인하려면 다음 쿼리를 사용합니다.

select b.userid,b.query,b.service_class,b.slot_count,b.xid,d.pid,d.aborted,a.compile_start,b.service_class_start_time,b.queue_end_time,b.service_class_end_time,c.startqueue as commit_startqueue,c.startwork as commit_startwork,c.endtime as commit_endtime,a.total_compile_time_s,datediff(s,b.service_class_start_time,b.queue_end_time)
    as wlm_queue_time_s,datediff(s,b.queue_end_time,b.service_class_end_time) as wlm_exec_time_s,datediff(s, c.startqueue, c.startwork) commit_queue_s,datediff(s, c.startwork, c.endtime) commit_time_s,undo_time_s,numtables_undone,datediff(s,a.compile_start,nvl(c.endtime,b.service_class_end_time))
    total_query_s ,substring(d.querytxt,1,50) as querytext from (select query,min(starttime) as compile_start,max(endtime) as compile_end,sum(datediff(s,starttime,endtime)) as total_compile_time_s from svl_compile group by query) a left join stl_wlm_query
    b using (query) left join (select * from stl_commit_stats where node=-1) c using (xid) left join stl_query d using(query) left join (select xact_id_undone as xid,datediff(s,min(undo_start_ts),max(undo_end_ts)) as undo_time_s,count(distinct table_id)
    numtables_undone from stl_undone group by 1) e on b.xid=e.xid
WHERE '2011-12-20 13:45:00' between compile_start and service_class_end_time;

"2011-12-20 13:45:00"을 대기 및 실행된 쿼리를 검사하려는 특정 날짜 및 시간으로 바꿉니다.

클러스터 노드 하드웨어 성능 검토

클러스터 유지 관리 기간에 패치, 내부 구성 변경 및 노드 교체와 같은 유지 관리 작업이 수행될 수 있습니다. 유지 관리 기간에 노드를 교체한 경우 클러스터는 곧 사용할 수 있습니다. 그러나 교체된 노드에서 데이터를 복원하는 데 약간의 시간이 걸릴 수 있습니다. 이 프로세스를 하이드레이션이라고 합니다. 하이드레이션 프로세스 중에 클러스터 성능이 저하될 수 있습니다.

클러스터 성능에 영향을 주는 이벤트(예: 하이드레이션)를 확인하려면 Amazon Redshift 클러스터 이벤트를 확인합니다. 클러스터 이벤트에서는 노드 교체 작업 및 수행되는 기타 클러스터 작업을 사용자에게 알립니다.

하이드레이션 프로세스를 모니터링하려면 STV_UNDERREPPED_BLOCKS 테이블을 사용합니다. 하이드레이션이 필요한 블록은 다음 쿼리를 사용하여 검색할 수 있습니다.

SELECT COUNT(1) FROM STV_UNDERREPPED_BLOCKS;

참고: 하이드레이션 프로세스의 기간은 클러스터 워크로드에 따라 다릅니다. 클러스터의 하이드레이션 프로세스의 진행률을 측정하려면 특정 간격으로 블록을 확인합니다.

특정 노드의 상태를 확인하려면 다음 쿼리를 사용하여 해당 노드의 성능을 다른 노드와 비교합니다.

SELECT day
  , node
  , elapsed_time_s
  , sum_rows
  , kb
  , kb_s
  , rank() over (partition by day order by kb_s) AS rank
FROM (
  SELECT DATE_TRUNC('day',start_time) AS day
    , node
    , sum(elapsed_time)/1000000 AS elapsed_time_s
    , sum(rows) AS sum_rows
    , sum(bytes)/1024 AS kb
    , (sum(bytes)/1024)/(sum(elapsed_time)/1000000) AS "kb_s"
  FROM svl_query_report r
    , stv_slices AS s 
  WHERE r.slice = s.slice 
    AND elapsed_time > 1000000 
  GROUP BY day
    , node 
  ORDER BY day
    , node
);

다음은 쿼리 출력 예제입니다.

day    node    elapsed_time_s    sum_rows         kb         kb_s  rank
...
4/8/20     0      3390446     686216350489    21570133592    6362    4
4/8/20     2      3842928     729467918084    23701127411    6167    3
4/8/20     3      3178239     706508591176    22022404234    6929    7
4/8/20     5      3805884     834457007483    27278553088    7167    9
4/8/20     7      6242661     433353786914    19429840046    3112    1
4/8/20     8      3376325     761021567190    23802582380    7049    8
...This output indicates that the node 7 processed 19429840046 Kb of data for 6242661 amount of seconds, which is a lot slower than the other nodes.

행 수("sum_rows" 열) 및 처리된 바이트 수("kb" 열) 사이의 비율은 거의 동일합니다. "kb_s" 열의 행 수는 하드웨어 성능에 따라 행 수와도 거의 동일합니다. 특정 노드가 일정 기간 더 적은 데이터를 처리하는 조건이 관찰된 경우 성능 저하는 기본적인 하드웨어 문제가 있음을 나타낼 수 있습니다. 기본적인 하드웨어 문제가 있는지 확인하려면 노드의 성능 그래프를 검토합니다.


이 문서가 도움이 되었나요?


결제 또는 기술 지원이 필요합니까?