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

所要時間4分
0

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 でディスク使用率が高くなる、またはいっぱいになる問題をトラブルシューティングする方法を教えてくださいを参照してください。

ロックの問題と長時間実行されているセッションまたはトランザクションをチェックする

クラスターでクエリを実行する前に、クエリの実行に関連するテーブルでテーブルレベルのロックを取得する必要があります。クエリが "hung" として表示されるか、クエリの実行時間がスパイクする場合があります。クエリ実行時間の急増が見られる場合は、ロックの問題が原因である可能性があります。クエリ実行時間が遅延する詳しい内容については、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_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" 列の行数も行数とほぼ同じです。特定のノードが一定期間にわたって処理するデータの量が少ないことがわかった場合、そのパフォーマンスの低下は根本的なハードウェアの問題を示している可能性があります。根本的なハードウェアの問題があることを確認するには、ノードのパフォーマンスグラフを確認します。


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