亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
1117
2022-05-29
前言
數據存儲傾斜(即圖中1-4被占用存儲資源不均衡)是Shared nothing分布式架構下的重要難題,它破壞了MPP架構中各個節點對等的要求,導致傾斜節點所需存儲及計算資源都遠大于其他節點,進而導致性能下降(木桶效應)、full disk或oom等嚴重問題。
技術背景
目前各類分布式數據庫廠商都有提供存儲傾斜的檢測工具,常用方法主要有計算表的COUNT,計算表的SIZE和通過統計信息計算這三種,下面以在GaussDB(DWS)分布式數據庫產品為例,分別介紹這三種方式的優劣:
方法一:通過表的COUNT計算傾斜
方案:例如使用table_skewness函數,其內部通過統計表在各節點的COUNT數實現
postgres=#?select?dnname,num?from?table_skewness('mytable')?order?by?dnname; ??dnname???|?num ---------------+------ ?datanode1??|?4800 ?datanode2??|?5216 ?datanode3??|?5792 ?datanode4??|?5568 ?datanode5??|?5152 ?datanode6??|?5472 (6?rows)
優點:簡單粗暴,適用表數據量小且UPDATE/DELETE少的表;
缺點:數據量大的場景計算表的COUNT比較耗時;臟數據占存儲和SCAN消耗但不會統計;
方法二:通過表的SIZE計算傾斜(推薦)
方案:例如使用table_distribution函數,其內部通過統計表在各節點的SIZE大小實現
postgres=#?select?nodename,dnsize?from?table_distribution('public','mytable')?order?by?nodename; ?nodename??|?dnsize -------------+-------- ?datanode1?|?221184 ?datanode2?|?229376 ?datanode3?|?253952 ?datanode4?|?253952 ?datanode5?|?229376 ?datanode6?|?253952 (6rows)
優點:實時性好;準確度高;相比計算COUNT速度快;
缺點:表對應數據文件多的場景性能會受影響,當前實測100+節點場景影響在可接受范圍
方法三:通過統計信息計算傾斜
方案:使用pg_class中reltuples/relpages以及統計信息來計算傾斜
CREATE?OR?REPLACE?FUNCTION?PUBLIC.pgxc_analyzed_tuples ( ????OUT?schemaname?text, ????OUT?tablename?text, ????OUT?dn_name?text, ????OUT?tuples?real ) RETURNS?SETOF?record AS?$$ DECLARE ????datanode_rd?????record; ????fetch_tuples????record; ????fetch_dn????????text; ????fetch_tuple_str?text; BEGIN ????fetch_dn?:=?'SELECT?node_name?FROM?pg_catalog.pgxc_node?WHERE?node_type=''D''?order?by?node_name'; ????FOR?datanode_rd?IN?EXECUTE(fetch_dn)?LOOP ????????dn_name?????????:=??datanode_rd.node_name; ????????fetch_tuple_str?:=?'EXECUTE?DIRECT?ON?('?||?dn_name?||?')?''SELECT?n.nspname,?c.relname,?c.reltuples ???????????????????FROM?pg_catalog.pg_class?c ???????????????????INNER?JOIN?pg_catalog.pg_namespace?n?ON?n.oid?=?c.relnamespace ???????????????????where?c.oid?>16384?AND?c.relkind?=?''''r''''? ???????????????????and?n.nspname?<>?''''cstore''''?and?n.nspname?<>?''''pmk''''? ???????????????????and?n.nspname?<>?''''pg_catalog'''''''; ????????FOR?fetch_tuples?IN?EXECUTE(fetch_tuple_str)?LOOP ????????????tuples????:=?fetch_tuples.reltuples; ????????????schemaname?:=?fetch_tuples.nspname; ????????????tablename??:=?fetch_tuples.relname; ????????????return?next; ????????END?LOOP; ????RAISE?INFO?'Finished?fetching?stats?info?from?DataNode?%?at?%',dn_name,?clock_timestamp(); ????END?LOOP; ????return; END;?$$ LANGUAGE?'plpgsql' ROWS?1000000; postgres=#?select?dn_name,tuples?from?public.pgxc_analyzed_tuples()?where?tablename='mytable'; ??dn_name?|?tuples -------------+-------- ?datanode1?|?4800 ?datanode2?|?5216 ?datanode3?|?5792 ?datanode4?|?5568 ?datanode5?|?5152 ?datanode6?|?5472 (6?rows)
優點:計算過程不需要實時SCAN,只需要通過已有統計信息來計算,速度最快。
缺點:強依賴實時ANALYZE統計信息來保證實時性;不包含實際占用存儲空間和SCAN?消耗的臟數據統計,準確度不如方法二。
小結
以上三種方法主要針對單個表的傾斜查詢,各有優劣,這里比較推薦準確度最高速度居中的方法二,并基于此方法實現了系統視圖PGXC_GET_TABLE_SKEWNESS用于查詢庫內所有表的存儲分布情況,例:
postgres=#?select?*?from?PGXC_GET_TABLE_SKEWNESS; schemaname?|?tablename?|?totalsize?|?avgsize??|?maxratio?|?minratio?|?skewsize?|?skewratio?|?skewstddev ------------+------------+-------------+------------+------------+------------+-----------+------------+------------ ?public??|?orders??|?705413120?|?117568853?|??.167??|??.166??|?278528??|??0.000??|??95628 ?public??|?mytable??|?1441792??|?240299??|??.176??|??.153??|?32768??|??.023??|??15253 ?public??|?customer?|?131579904?|?21929984?|??.167??|??.166??|?131072??|??.001??|??46050 ?public??|?part???|?101646336?|?16941056?|??.167??|??.166??|?114688??|??.001??|??38772 ?public??|?supplier?|?8552448??|?1425408??|??.168??|??.166??|?16384??|??.002??|??8974 ?public??|?lineitem?|?3351937024?|?558656171?|??.167??|??.166??|?1302528?|??0.000??|??516984 ?public??|?partsupp?|?461922304?|?76987051?|??.167??|??.166??|?401408??|??.001??|??148130 (7?rows)
后面將語句基于table_distribution函數及PGXC_GET_TABLE_SKEWNESS視圖,介紹如何在真實業務場景中及早、快速定位到存儲傾斜的表。
實戰場景
從早發現、快定位、勤檢查三個角度,介紹如何在實際業務場景中最大程度避免數據存儲傾斜帶來的影響。
早發現:數據導入場景即時檢測
當前我們支持在數據導入過程對DN導入行數進行統計,導入完成后計算傾斜率,超過一定閾值時,立即進行告警。傾斜率通過(?DN導入行數最大值-DN導入行數最小值)?/導入總行數計算,方法如下:
1、開啟即時檢測的參數
table_skewness_warning_rows:表傾斜告警最小行數,取值范圍0~?INT_MAX,默認值100000,表示當導入總行數超過該值與導入DN數之積時,才可能觸發告警,避免小數據量導入的場景進行無意義的告警。
table_skewness_warning_threshold:表傾斜告警閾值,取值范圍0~1.0,默認值為0,表示當DN返回行數的最小值和最大值的比例小于指定的傾斜告警閾值時,進行告警。
2、執行導入(INSERT或COPY)
當導入數據出現傾斜,執行SQL和日志中會發出告警,告警信息包括表名、最小行數、最大行數、總行數、平均行數、傾斜率,以及提示信息(檢查數據分布或者修改參數)。
WARNING:?Skewness?occurs,?table?name:?xxx,?min?value:?xxx,?max?value:?xxx,?sum?value:?xxx,?avg?value:?xxx,?skew?ratio:?xxx HINT:?Please?check?data?distribution?or?modify?warning?threshold
快定位:磁盤滿場景快速定位傾斜表
出現磁盤滿場景,在表數量非常多的情況下,全量排查哪些表傾斜非常耗時,我們支持使用如下方式快速定位傾斜表:
1、查詢近期發生過數據變更的表
通過pg_stat_get_last_data_changed_time(oid)函數查詢出近期發生過數據變更的表,基于表的最后修改時間只在進行IUD操作的CN記錄,要查詢庫內1天(間隔可在函數中調整)內被修改的所有表,可以使用如下封裝函數:
CREATE?OR?REPLACE?FUNCTION?get_last_changed_table(OUT?schemaname?text,?OUT?relname?text)?RETURNS?setof?record AS?$$ DECLARE ????row_data?record; ????row_name?record; ????query_str?text; ????query_str_nodes?text; BEGIN ????query_str_nodes?:=?'SELECT?node_name?FROM?pgxc_node?where?node_type?=?''C'''; ????FOR?row_name?IN?EXECUTE(query_str_nodes)?LOOP ???????query_str?:=?'EXECUTE?DIRECT?ON?('?||?row_name.node_name?||?')?''SELECT?b.nspname,a.relname ???????????????FROM?pg_class?a?INNER?JOIN?pg_namespace?b?on?a.relnamespace?=?b.oid?where ???????????????pg_stat_get_last_data_changed_time(a.oid)? ???????????????BETWEEN?current_timestamp?-?1?AND?current_timestamp;'''; ??????FOR?row_data?IN?EXECUTE(query_str)?LOOP ????????schemaname?=?row_data.nspname; ????????relname?=?row_data.relname; ????????return?next; ??????END?LOOP; ????END?LOOP; ????return; END;?$$ LANGUAGE?plpgsql;
2、查看近期數據變更的表的分布情況
postgres=#?SELECT?table_distribution(schemaname,relname)?FROM?get_last_changed_table()?limit?6; ????????table_distribution ----------------------------------- ?(public,mytable,datanode1,221184) ?(public,mytable,datanode2,229376) ?(public,mytable,datanode3,253952) ?(public,mytable,datanode4,253952) ?(public,mytable,datanode5,229376) ?(public,mytable,datanode6,253952) (6?rows)
勤檢查:常規數據傾斜巡檢
1、在庫中表個數比較少(<1W)場景
直接使用PGXC_GET_TABLE_SKEWNESS視圖來查詢當前庫內所有表的數據傾斜情況。
2、在庫中表個數非常多(>1W)場景
PGXC_GET_TABLE_SKEWNESS涉及全庫查并計算非常全面的傾斜字段,所以可能會花費比較長的時間(小時級),建議參考PGXC_GET_TABLE_SKEWNESS視圖定義,直接使用table_distribution()函數自定義輸出,減少輸出列進行計算優化,例如:
postgres=#?SELECT?schemaname,tablename,max(dnsize)?AS?maxsize,?min(dnsize)?AS?minsize postgres-#?FROM?pg_catalog.pg_class?c postgres-#?INNER?JOIN?pg_catalog.pg_namespace?n?ON?n.oid?=?c.relnamespace postgres-#?INNER?JOIN?pg_catalog.table_distribution()?s?ON?s.schemaname?=?n.nspname?AND?s.tablename?=c.relname postgres-#?INNER?JOIN?pg_catalog.pgxc_class?x?ON?c.oid?=?x.pcrelid?AND?x.pclocatortype?=?'H' postgres-#?GROUP?BY?schemaname,tablename; schemaname?|?tablename?|?maxsize?|?minsize ------------+-------------+-----------+----------- ?public??|?orders???|?117686272|?117407744 ?public??|?mytable??|?253952??|?221184 ?public??|?customer??|?21979136?|?21848064 ?public??|?part????|?16982016?|?16867328 ?public??|?supplier??|?1433600?|?1417216 ?public??|?lineitem??|?559284224|?557981696 ?public??|?partsupp??|?77094912?|?76693504 (7?rows)
總結
分布式框架下的傾斜是個大課題,本文主要針對存儲傾斜(不包含計算傾斜)重點分享我們在業務中如何盡快發現傾斜、定位傾斜,希望能給大家提供一些思路和幫助。
DWS 分布式 EI企業智能
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。