Amazon Redshift のクラスターまたはクエリのパフォーマンスの問題をトラブルシューティングする方法を教えてください。

所要時間4分
0

Amazon Redshift クラスターのクエリパフォーマンスをトラブルシューティングまたは改善したいと考えています。

簡単な説明

Amazon Redshift クラスターでパフォーマンスの問題が発生した場合は、次のタスクを実行してください。

  • クラスターのパフォーマンスメトリクスを監視します。
  • Amazon Redshift アドバイザーの推奨事項を確認します。
  • クエリ実行アラートと過剰なディスク使用量を確認します。
  • ロックの問題や実行時間の長いセッションやトランザクションがないか確認します。
  • ワークロード管理 (WLM) の設定を確認します。
  • クラスターノードのハードウェアのメンテナンスとパフォーマンスを確認します。

解決策

クラスターのパフォーマンスメトリクスを監視する

クラスターのパフォーマンスメトリクスとグラフを確認すると、パフォーマンス低下の根本原因を突き止めるのに役立ちます。Amazon Redshift コンソールパフォーマンスデータを表示して、クラスターのパフォーマンスを経時的に比較します。

これらのメトリックスが増加すると、Amazon Redshift クラスターのワークロードとリソースの競合が高まっている可能性があります。詳細については、「Amazon CloudWatch メトリクスによる Amazon Redshift のモニタリング」を参照してください。

Amazon Redshift コンソールでワークロード実行の詳細を確認して、特定のクエリとランタイムを確認します。たとえば、クエリのプランニング時間が長くなると、クエリがロックされるのを待っている可能性があります

Amazon Redshift アドバイザーの推奨事項を確認する

Amazon Redshift アドバイザーの推奨事項を使用して、クラスターの潜在的な改善点について詳細を学びます。推奨事項は、一般的な使用パターンと 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 はクエリの実行に関連するテーブルでテーブルレベルのロックを取得することがあります。クエリが応答していないように見えたり、クエリのランタイムが急上昇したりすることがあります。クエリランタイムでスパイクが発生した場合は、ロックの問題がスパイクの原因である可能性があります。詳細については、「Amazon Redshift でクエリプランニングに時間がかかるのはなぜですか?」を参照してください。

テーブルが現在別のプロセスまたはクエリによってロックされている場合、クエリは続行できません。その結果、STV_INFLIGHT テーブルにクエリが表示されません。代わりに、実行中のクエリが STV_RECENTS テーブルに表示されます。

トランザクションの実行時間が長いと、クエリの応答が停止することがあります。実行時間の長いセッションやトランザクションがクエリのパフォーマンスに影響を与えないように、次のアクションを実行してください。

  • STL_SESSIONS テーブルと SVV_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_pcntFROM
(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

**注:**上記の出力は、ノード 719429840046 KB のデータを 6242661 秒間処理したことを示しています。これは他のノードよりもはるかに遅いです。

sum_rows 列の行数と kb 列の処理済みバイト数の比率はほぼ同じです。ハードウェアのパフォーマンスにもよりますが、kb_s 列の行数も sum_rows 列の行数とほぼ同じです。ノードが一定期間にわたって処理するデータが少ない場合は、根本的なハードウェアの問題がある可能性があります。根本的なハードウェアの問題があるかどうかを確認するには、ノードのパフォーマンスグラフを確認します。

AWS公式
AWS公式更新しました 1年前
コメントはありません

関連するコンテンツ