如何使用 Amazon Redshift 對磁碟用量很高或已滿進行疑難排解?

3 分的閱讀內容
0

我在 Amazon Redshift 上遇到磁碟使用率很高或已滿,並且想要對此問題進行疑難排解。

解決方法

高磁碟用量錯誤可能取決於下列幾個因素,包括:

  • 分佈和排序索引鍵
  • 查詢處理
  • 具有 VARCHAR(MAX) 資料欄的資料表
  • 高資料欄壓縮
  • 維護操作
  • 具有交叉聯結的笛卡爾乘積
  • 最小資料表大小
  • 標記區塊
  • 複製大型檔案

分佈和排序索引鍵

檢閱資料表的分佈樣式、分佈索引鍵和排序索引鍵選擇。具有分佈偏態的資料表 (其中位於一個節點中的資料比另一個節點中的資料更多) 可能會導致磁碟節點已滿。如果您的資料表具有偏態的分佈樣式,請將分佈樣式變更為更均勻的分佈。請注意,在查詢執行時,分佈和資料列偏態可能會影響儲存偏態和中繼資料列集。如需有關分佈索引鍵和排序索引鍵的詳細資訊,請參閱 Amazon Redshift 引擎的進階資料表設計手冊:序言、先決條件和優先順序

若要判斷分佈索引鍵的基數,請執行下列查詢:

SELECT <distkey column>, COUNT(*) FROM <schema name>.<table with distribution skew> GROUP BY <distkey column> HAVING COUNT(*) > 1 ORDER BY 2 DESC;

注意: 若要避免排序步驟,請在 ORDER BY 子句中使用 SORT KEY 資料欄。排序步驟可能會使用過多的記憶體,造成磁碟溢出。如需詳細資訊,請參閱使用排序索引鍵

在篩選的結果集中,選擇具有高基數的資料欄以檢視資料分佈。如需有關資料表分佈樣式的詳細資訊,請參閱選擇最佳分佈樣式

若要查看分佈索引鍵中的資料庫區塊如何映射至叢集,請使用 Amazon Redshift table_inspector.sql 公用程式

查詢處理

檢閱配置給查詢的任何記憶體。在處理查詢時,中繼查詢結果可以儲存在暫時區塊中。如果沒有足夠的可用記憶體,則資料表會導致磁碟溢出。中繼結果集不會壓縮,這會影響可用的磁碟空間。如需詳細資訊,請參閱配置給查詢的記憶體不足

Amazon Redshift 預設為具有均勻分佈,且暫存資料表沒有資料欄編碼的資料表結構。但是,如果您使用的是 SELECT...INTO 語法,請使用 CREATE 陳述式。如需詳細資訊,請參閱 Amazon Redshift 的 10 大效能調校技術。請遵循提示 #6: 解決暫時資料表使用效率低下的問題下的指示進行操作。

如果為查詢配置的記憶體不足,您可能會在 SVL_QUERY_SUMMARY 中看到一個步驟,其中 is_diskbased 顯示值「true」。若要解決此問題,請增加查詢插槽的數量,以向查詢配置更多記憶體。如需有關如何暫時增加查詢插槽的詳細資訊,請參閱 wlm_query_slot_count調校 WLM 以執行混合工作負載。您也可以使用 WLM 查詢監控規則來應對繁重的處理負載,並識別 I/O 密集型查詢。

具有 VARCHAR(MAX) 資料欄的資料表

檢查 VARCHAR 或 CHARACTER VARYING 資料欄中是否有結尾空白,當資料儲存在磁碟上時,這些空白可能會省略。在查詢處理期間,結尾空白可以佔據記憶體中完整長度 (VARCHAR 的最大值為 65535)。最佳實務是使用盡可能小的資料欄大小

若要產生最大資料欄寬的資料表清單,請執行下列查詢:

SELECT database, schema || '.' || "table" AS "table", max_varchar FROM svv_table_info WHERE max_varchar > 150 ORDER BY 2;

若要識別並顯示寬 VARCHAR 資料表欄的實際寬度,請執行下列查詢:

SELECT max(octet_length (rtrim(column_name))) FROM table_name;

在此查詢的輸出中,驗證長度是否適合您的使用案例。如果資料欄達到最大長度並超出您的需求,請將長度調整為所需的大小下限。

如需有關資料表設計的詳細資訊,請檢閱 Amazon Redshift 設計資料表的最佳實務

高資料欄壓縮

使用 ANALYZE COMPRESSION 或使用 Amazon Redshift 中的自動資料表最佳化功能,對所有資料欄 (排序索引鍵除外) 進行編碼。Amazon Redshift 提供了資料欄編碼。最佳實務是使用此功能,即使它可以提高讀取效能並降低整體儲存消耗。

維護操作

請確保定期對 Amazon Redshift 資料庫中的資料庫資料表進行分析和清除。識別針對缺少統計資料的資料表執行的任何查詢。防止對缺少統計資料的資料表執行查詢,可防止 Amazon Redshift 掃描不必要的資料表列。這也有助於將您的查詢處理最佳化。

注意: VACUUM 和 DEEP COPY 等維護操作會使用暫時儲存空間進行排序操作,因此預期磁碟用量會激增。

例如,下列查詢可協助您在 Amazon Redshift 中識別過時的統計資料:

SELECT * FROM svv_table_info WHERE stats_off > 10 ORDER BY size DESC;

此外,使用 ANALYZE 命令來檢視和分析資料表統計資料。

如需有關維護操作的詳細資訊,請參閱 Amazon Redshift Analyze & Vacuum 結構描述公用程式

具有交叉聯結的笛卡爾乘積

使用查詢的 EXPLAIN 計畫來尋找笛卡爾乘積的查詢。笛卡爾乘積是不相關的交叉聯結,可以產生更多的區塊數。這些交叉聯結可能會導致更高的記憶體使用率,以及更多資料表溢出至磁碟。如果交叉聯結不共用 JOIN 條件,則聯結會產生兩個資料表的笛卡爾乘積。然後,一個資料表的每個資料列會聯結至另一個資料表的每個資料列。

交叉聯結也可以作為巢狀迴圈聯結執行,這需要最長的處理時間。巢狀迴圈聯結會導致整體磁碟用量激增。如需詳細資訊,請參閱識別具有巢狀迴圈的查詢

最小資料表大小

相同資料表可以在不同的叢集中具有不同的大小。然後,資料表大小下限由資料欄數以及資料表是否具有 SORTKEY 和填入的磁碟切片數量來確定。如果您最近調整了 Amazon Redshift 叢集的大小,您可能會發現整體磁碟儲存空間有所變更。這是因切片數量變更所導致。Amazon Redshift 也會計算每個資料表使用的資料表區段。如需詳細資訊,請參閱為什麼 Amazon Redshift 叢集中的資料表耗用的磁碟儲存空間超過預期或更少?

標記區塊

發生 Amazon Redshift 資料表的 WRITE 交易時,會產生標記區塊,並且存在並行讀取。Amazon Redshift 會在寫入操作之前保留區塊,以保持並行讀取操作的一致性。Amazon Redshift 區塊無法變更。每次插入更新刪除動作都會建立一組新的區塊,將舊區塊標示為已標記。

有時,由於長時間執行的資料表交易,因此標記無法在認可階段清除。當有太多 ETL 負載同時執行時,標記也可能無法清除。由於 Amazon Redshift 會從交易開始時監控資料庫,因此寫入資料庫的任何資料表也會保留標記區塊。如果長時間執行的資料表交易經常發生在多個負載中,則可能會累積足夠的標記,導致「磁碟已滿」錯誤。

您也可以執行 commit 命令,強制 Amazon Redshift 執行有關標記區塊的分析。

如果存在處於作用中狀態的長時間執行的查詢,則使用 commit 命令終止查詢 (並釋放所有後續區塊):

begin;
create table a (id int);
insert into a values(1);
commit;
drop table a;

然後,若要確認標記區塊,請執行下列查詢:

select trim(name) as tablename, count(case when tombstone > 0 then 1 else null end) as tombstones from svv_diskusage group by 1 having count(case when tombstone > 0 then 1 else null end) > 0 order by 2 desc;

複製大型檔案

在 COPY 操作期間,即使有足夠的儲存空間,您也可能會收到磁碟已滿錯誤。如果排序操作溢出至磁碟並建立暫時區塊,則會發生此錯誤。

如果遇到磁碟已滿 錯誤訊息,請檢查 STL_DISK_FULL_DIAG 資料表。檢查哪個查詢 ID 導致錯誤以及建立的暫時區塊:

select '2000-01-01'::timestamp + (currenttime/1000000.0)* interval '1 second' as currenttime,node_num,query_id,temp_blocks from pg_catalog.stl_disk_full_diag;

如需更多最佳實務,請參閱 Amazon Redshift 載入資料的最佳實務

其他疑難排解

Amazon Redshift 主控台效能標籤下,檢查磁碟空間的百分比。對於每個叢集節點,Amazon Redshift 會提供額外的磁碟空間,該空間大於標稱磁碟容量。

如果您注意到使用率突然激增,請使用 STL_QUERY 來識別正在執行的活動和任務。請注意磁碟溢出時正在執行的查詢:

select * from stl_query where starttime between '2018-01-01 00:30:00' and '2018-01-01 00:40:00';

注意: 使用激增發生的時間更新值。

若要識別前 20 個磁碟溢出查詢,請執行下列查詢:

select A.userid, A.query, blocks_to_disk, trim(B.querytxt) text from stl_query_metrics A, stl_query B where A.query = B.query and segment=-1 and step = -1 and max_blocks_to_disk > 0 order by 3 desc limit 20;

檢視資料欄值 blocks_to_disk 以識別磁碟溢出。如果需要,請終止溢出過多的查詢。然後,再次執行查詢之前,向查詢配置額外的記憶體。如需詳細資訊,請參閱 STL_QUERY_METRICS

若要確定查詢是否正確寫入磁碟,請執行下列查詢:

SELECT q.query, trim(q.cat_text)
FROM (
SELECT query,
replace( listagg(text,' ') WITHIN GROUP (ORDER BY sequence), '\\n', ' ') AS cat_text
FROM stl_querytext
WHERE userid>1
GROUP BY query) q
JOIN (
SELECT distinct query
FROM svl_query_summary
WHERE is_diskbased='t' AND (LABEL ILIKE 'hash%' OR LABEL ILIKE 'sort%' OR LABEL ILIKE 'aggr%' OR LABEL ILIKE 'save%' OR LABEL ILIKE 'window%' OR LABEL ILIKE 'unique%')
AND userid > 1) qs
ON qs.query = q.query;

此命令也可識別溢出至磁碟的查詢。


相關資訊

效能

Amazon Redshift 系統概觀

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