如何對 Amazon Redshift 中的叢集或查詢效能問題進行疑難排解?
我想排解或改進 Amazon Redshift 叢集中的查詢效能。
簡短說明
如果您在 Amazon Redshift 叢集中遇到效能問題,請完成下列任務:
- 監控叢集效能指標。
- 查看 Amazon Redshift Advisor 建議。
- 檢閱查詢執行警示和磁碟過度使用情況。
- 檢查鎖定問題以及長時間執行的工作階段或交易。
- 檢查您的工作負載管理 (WLM) 組態。
- 檢查叢集節點硬體維護和效能。
解決方法
監控叢集效能指標
檢閱叢集效能指標和圖表,以協助您找到效能降級的根本原因。在 Amazon Redshift 主控台中檢視效能資料,以比較一段時間內的叢集效能。
這些指標的增加可能表示 Amazon Redshift 叢集上的工作負載和資源競爭較高。如需詳細資訊,請參閱使用 Amazon CloudWatch 指標監控 Amazon Redshift。
在 Amazon Redshift 主控台中檢查工作負載執行細分,以檢閱特定的查詢和執行時期。例如,如果您看到查詢計劃時間增加,則查詢可能正在等待鎖定。
查看 Amazon Redshift Advisor 建議
使用 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 可能會針對查詢執行所涉及的資料表取得資料表層級鎖定。有時,查詢顯示沒有回應,或者查詢執行時期激增。如果查詢執行時期激增,則可能是鎖定問題導致激增。如需詳細資訊,請參閱為什麼我在 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
**注意:**上面的輸出顯示節點 7 處理了 19429840046 KB 的資料,用時 6242661 秒。這比其他節點慢得多。
sum\ _rows 欄中的列數與 kb 欄中處理的位元組數之間的比率大致相同。視硬體效能而定,kb_s 欄中的列數與 sum_rows 欄中的列數也大致相同。如果節點在一段時間內處理較少的資料,則可能是基礎硬體有問題。若要檢查是否存在基礎硬體問題,請檢閱節點的效能圖表。
相關內容
- 已提問 2 個月前lg...
- 已提問 1 年前lg...
- 已提問 2 個月前lg...
- 已提問 1 年前lg...
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 1 年前
- AWS 官方已更新 3 年前