如何對 Amazon Redshift 中的叢集或查詢效能問題進行疑難排解?

5 分的閱讀內容
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 對磁碟用量很高或已滿進行疑難排解?

檢查鎖定問題以及長時間執行的工作階段或交易

在叢集上執行查詢之前,可能需要在查詢執行中涉及的資料表上取得資料表層級鎖定。在某些情況下,查詢可能會顯示為「掛起」,或者查詢執行時間激增。如果您發現查詢執行時間激增,鎖定問題可能是原因。如需延遲查詢執行時間的詳細資訊,請參閱為什麼我在 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」欄中的列數也大致相同。如果您發現某個特定節點在一段時間內處理的資料較少,則效能不佳可能表示潛在的硬體問題。若要確認是否存在基礎硬體問題,請檢閱節點的效能圖表。


AWS 官方
AWS 官方已更新 3 年前