全网首发|阿里资深技术专家数仓调优经验分享(上)
簡介:?本篇文章總結了AnalyticDB表的設計的最佳經驗、數據寫入的最佳經驗、高效查詢的最佳實踐,以及一些常見的問題。
隨著云原生數據倉庫AnalyticDB for MySQL(下文統一簡稱:AnalyticDB)在阿里集團各個業務線、社會上各行各業的推廣應用,我們沉淀了一些最佳實踐,現在筆者整理在這里,供大家參考,希望對大家有幫助。本篇文章總結了AnalyticDB表的設計的最佳經驗、數據寫入的最佳經驗、高效查詢的最佳實踐,以及一些常見的問題。
說明:
1.在讀這篇文章之前,請先了解AnalyticDB的產品官方文檔,以提前適當了解AnalyticDB;
2.本文寫的最佳實踐主要針對AnalyticDB 3.0,AnalyticDB 2.0在原理上也同樣適用。
01 表設計的最佳實踐
AnalyticDB,作為一個分布式數據倉庫,能夠為海量數據的實時分析帶來卓越的性能體驗。為了充分發揮AnalyticDB在數據分析方面的性能優勢,設計表時,需要注意以下幾點規則。
(一)選擇合適的表類型(維度表or普通表)
· 維度表:又稱廣播表,是數據倉庫中的一個概念,一般存儲維度數據。在AnalyticDB中建表語句中有DISTRIBUTED BY BROADCAST的關鍵字,這些表會在集群的每個節點存儲一份數據,因此維度表的數據量不宜太大,建議每張維度表存儲的數據不超過2萬行。
注意:維度表太大,會導致數據存儲空間的膨脹,節點越多膨脹越大,同時也會導致實時寫入時性能下降,IOPS會比較高。
· 普通表:也叫作分區表、事實表,一般存儲業務的主題數據。普通表可存儲的數據量通常比較大,可以存儲千萬條甚至萬億條數據,可以通過一級分區對數據做分片以及二級分區對數據進行生命周期管理。
(二)選擇合適的分布鍵(一級分區鍵)
AnalyticDB中創建普通表時,默認需要通過DISTRIBUTED BY HASH(column_name,...)指定分布鍵,按照column_name的HASH值進行分區。
AnalyticDB支持將多個字段作為分布鍵。
分布鍵的選擇依據:
- 盡可能選擇值分布均勻的字段作為分布鍵,例如交易ID、設備ID、用戶ID或者自增列作為分布鍵;
- 盡可能選擇參與JOIN的字段作為分布鍵,例如進行用戶畫像分析時,可以選擇user_id作為分布鍵。
注意:分布鍵不均勻容易導致數據分布不均,嚴重影響寫入和查詢的效率,此外也容易使單節點磁盤寫滿從而導致整個集群鎖定不可用。除特殊的業務場景外,建表優先考慮數據是否均勻,然后再考慮JOIN KEY對齊的問題。
(三)選擇合適的分區鍵(二級分區鍵)
對于表的數據量非常大的表,需要考慮創建二級分區表來對數據做進一步的切分,設置了二級分區后,也能帶來兩個好處:
1)對數據進行生命周期管理,比如設置了一定數量的二級分區數量后,過期的二級分區會自動被淘汰掉;
2)當查詢條件帶上了二級分區字段時,是可以對二級分區進行裁剪的,從而提升查詢的性能。
- 直接用ds的值來做分區 PARTITION BY VALUE(ds)
- ds轉換后的天做分區 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y%m%d'))
- ds轉換后的月做分區 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y%m'))
- ds轉換后的年做分區 PARTITION BY VALUE(DATE_FORMAT(ds, '%Y'))
二級分區的注意事項:
請提前規劃好實例中所有表的二級分區鍵,充分利用二級分區,不要讓每個二級分區的數據量過小,假如,用天進行二級分區,每天數據量很小,那么可以考慮用月作為二級分區。二級分區數據量過小,會導致數據庫中需要保存分區數據的元數據特別多,而這些元數據存放在內存中,過多的元數據會占據較多的內存空間,導致系統的GC或者OOM,同時也會導致實時寫入的IOPS較高。
二級分區的數據量建議:
(四)選擇合適的主鍵
在表中定義主鍵可以實現數據消重(REPLACE INTO)和數據更新(DELETE、UPDATE)。只有定義過主鍵的表支持數據更新操作(DELETE、UPDATE)。
主鍵的選擇依據:
- 盡可能選擇數值類型的單個字段作為主鍵,表的性能相對更好。
- 如果數值類型的單一主鍵無法滿足業務需要,也可以使用字符串或者多字段組合作為主鍵。
- 主鍵中必須包含分布鍵和分區鍵,如果表中定義了二級分區鍵的話,主鍵必須包含二級分區鍵。
注意:作為主鍵的字段不宜太大,字段的長度不宜過長,否則會影響寫入的性能。
(五)選擇合適聚集索引
聚集索引會將一個或者多個字段排序,保證該字段相同或者相近的數據存儲在磁盤的相同或相近位置,當以聚集索引中的字段作為查詢條件時,查詢結果保持在磁盤的相同位置,可以減少磁盤的IO。
聚集索引的選擇依據:
查詢一定會攜帶的過濾條件的字段可以設計為聚集索引。例如,電商賣家透視平臺中每個賣家只訪問自己的數據,賣家ID可以定義為聚集索引,保證數據的局部性,提升數據查詢性能。
注意:目前只支持一個聚集索引,但一個聚集索引可以包含多列。目前除非對非常分散的數據進行點查,否則聚集索引對性能的幫助很少。
(六)設計合適的數據類型
建議用戶盡可能使用數值類型,減少使用字符串類型。
AnalyticDB處理數值類型的性能遠好于處理字符串類型,原因在于:
- 數值類型定長,占用內存少,存儲空間小。
- 數值類型計算更快,尤其是在數據關聯場景。
- 從內部索引機制上,字符串類型適合等值查詢和范圍查詢,而時間類型、數值類型性能更好。
- 選擇盡可能小的字段長度,比如,性別可以使用Boolean或者Byte類型,數據長度不大的可以用Int類型。
- 在同一個業務模型內,相同字段設計成相同的數據類型和字段長度,字段命名也保持一致,特別是涉及到主外鍵關聯的字段更要注意,避免不同的數據類型的字段關聯導致隱式轉換。
常見字符串數據的處理建議:
- 包含字符前綴或后綴,例如E12345,E12346等。建議去掉前綴或者將前綴映射為數字。
- 字段只有少數幾個值,例如國家名。建議對每個國家編碼,每個國家對應一個唯一數字。
- 時間/日期類型數據,避免使用Varchar字符類型存儲,盡量使用Date,Timestamp或者Int類型。
- 地理的經度/緯度數據,建議采用Double數據類型進行存儲。
如果您在建表前,不清楚自身業務的數據分布特征,可在數據導入后,使用優化建議進行優化。具體請訪問AnalyticDB控制臺的建表診斷頁面:數據建模優化 - 云原生數倉 AnalyticDB MySQL - 阿里云,查看建表問題及優化建議。
02 數據寫入的最佳實踐
(一)實時寫入
1.批量打包的方式提交
向表中寫入數據時,可以通過批量打包方式INSERT INTO和REPLACE INTO提高數據寫入性能。注意事項如下:
- 通過每條INSERT或者REPLACE語句寫入的數據行數需大于1000行,但寫入的總數據量不宜太大,不能超過16MB。
- 通過批量打包方式寫入數據時,單個批次的寫入延遲相對較高,但是整體性能有所提升。
- 寫入報錯時,需要重試以確保數據被成功寫入,重試導致的數據重復可以通過表的主鍵來消除。
- 如果不需要對原始的數據進行修改,可以使用INSERT INTO寫入數據,效率是REPLACE INTO的3倍以上。
樣例:
INSERT INTO test ?(id, name,sex,age,login_time) ? VALUES ?(1,'dcs',0,23,'2018-03-02 10:00:00'), ?(2,'hl',0,23,'2018-03-02 10:01:00'), ?(3,'xx',0,23,'2018-03-02 10:02:00') ? ......;2.更新數據
數據更新有多種方式,使用區別如下:
- 高頻基于主鍵的行級覆蓋更新, 且應用可以補齊所有列,請使用REPLACE INTO VALUES批量打包。
- 高頻基于主鍵的行級覆蓋更新, 應用不能補齊所有列,請使用INSERT ON DUPLICATE KEY UPDATE批量打包。
- 低頻任意條件更新,請使用UPDATE SET WHERE。
注意:UPDATE需要查表來填補更新中缺失的舊值,因此比REPLACE INTO多一次查詢,性能較低,不建議做高頻、大批量的UPDATE操作。如果線上UPDATE性能無法滿足需求,需考慮替換成REPLACE INTO,由應用端填補舊值。
3.刪除數據
數據刪除有多種方式,使用區別如下:
- 低頻主鍵條件刪除,請使用 DELETE FROM WHERE primary key = xxx。
- 低頻任意條件刪除,請使用 DELETE FROM WHERE。
- 刪除單個二級分區,請使用 TRUNCATE PARTITION。
- 刪除單表(包括所有二級分區),請使用TRUNCATE TABLE或DROP TABLE。
(二)批量導入
1.如何選擇批量導入還是實時導入
- 從ODPS、OSS導入AnalyticDB,推薦使用INSERT OVERWRITE SELECT做批量導入,有以下兩個原因:一,批量導入適合大數據量導入,性能好;二,批量導入適合數倉語義,即導入過程中舊數據可查,導入完成一鍵切換新數據,如果導入失敗,新數據會回滾,不影響舊數據的查詢。
- 從RDS、MySQL、AnalyticDB等導入AnalyticDB,根據數據量情況,如果數據量不大(百萬級別的表),推薦使用INSERT INTO SELECT做實時導入;如果數據量較大,推薦使用INSERT OVERWRITE SELECT做批量導入。
- 對相同的一張表,不能既采用INSERT OVERWRITE SELECT又采用INSERT INTO SELECT操作,否則數據會被覆蓋。
2.導入并發和資源說明
- 單張表的導入會在系統內部排隊串行,而多張表的導入,會產生n個并行導入任務(并行度可調整,默認并行度是2),出于資源控制的考慮,超出并行度的任務也會排隊。
- 數據導入,同查詢一樣,會消耗AnalyticDB實例的計算資源。因此,建議在查詢QPS較低時執行數據導入,并推薦通過定時任務進行錯峰導入。
03 高效查詢的最佳實踐
AnalyticDB的優勢是能在海量數據場景下,面對復雜查詢,做到實時的在線分析。AnalyticDB的查詢調優,不僅兼容數據庫查詢優化的通用方法,還提供一些專門的優化方法,使其能夠充分發揮出分布式計算的性能優勢。
(一)查詢優化的通用法則
按照葉正盛早些年在《ORACLE DBA手記》上寫的文章,數據訪問優化滿足以下漏斗法則:
1.減少數據訪問(減少磁盤訪問)
盡量多的使用過濾條件,盡早的提前過濾數據,從而減少參與計算的數據量,例如在子查詢里提前把能過濾的數據先過濾。
2.返回更少數據(減少網絡傳輸或磁盤訪問)
在OLAP數據庫中,由于表的列數往往比較多,且是基于列存或者行列混存,所以SELECT * 的操作,會導致較多的請求IO。因此,請盡量避免SELECT * 的查詢。
3.減少交互次數(減少網絡傳輸)
建議使用上文提到的批量導入,減少交互次數。
4.減少服務器CPU開銷(減少CPU及內存開銷)
- 減少不必要的排序和分頁,特別是子查詢中的排序。
- 在滿足業務前提下,盡量減少COUNT DISTINCT操作。
- 在滿足業務前提下,特別是在海量數據下,采用類似Hyperloglog的近似計算代替準確計算。
5.利用更多資源(增加資源)
- 設計表的時候,盡量避免分區傾斜, 不要把存儲和計算壓在某一個節點上。建議盡量把數據都均勻的散列到所有的節點上,充分利用所有機器的能力,最大程度地發揮分布式數據庫的效能。
- AnalyticDB本身就是MPP大規模并行處理的典型系統,在內核層面做了大量的優化處理,能夠充分利用更多的資源。
(二)AnalyticDB特殊場景的優化
1.外表查詢的最佳實踐
- 不推薦使用外表進行復雜計算。外表計算會拉取全部數據,因此外表的復雜計算會導致嚴重的GC,也會給網絡帶寬造成較大壓力。
- 外部表不支持DML操作(DELETE、UPDATE、TRUNCATED)。如果需要修改外表數據,請到源表中進行DML操作。
2.合理的使用索引
合理使用索引是數據庫調優的一個非常重要的手段,AnalyticDB也不例外。在AnalyticDB中,默認每列都會創建索引。但是也有例外情況。如果某列的Cardinality值較低,索引的選擇性不高,通過索引查詢,性能可能會更差。此時,建議在建表時關閉自動創建索引的功能。如果表已經建好,可以使用如下SQL語句,刪除索引或者通過hint繞過索引。
ALTER TABLE table_name DROP INDEX index_name; --方法一:刪除枚舉列的索引 /+no_index_columns=[t_order_content.fdelete;fdbid]/ --方法二:通過hint使查詢繞過索引3.巧妙的使用聚集索引
當查詢條件一定包含某列,特別是該列數據在存儲上非常分散時,對該列建立聚集索引,性能會有明顯的提升。您可以采用類似如下的SQL語句添加聚集索引:
ALTER TABLE table_name ADD CLUSTERED INDEX index_cls (d_fdbid);注意:如果表中已經有了數據,直接ADD CLUSTER INDEX不會對存量的數據排序,需要重新建表,并在建表的時候加上聚集列關鍵字;或者在添加完聚集索引后對該表做一次build操作:build table table_name force=true。
4.減少節點間的數據交互
分布式數據庫,在充分發揮分布式計算優勢的同時,有時也會加大跨節點間的網絡開銷。特別是請求的數據量較少,數據卻分散在較多節點的情況,跨網絡開銷的情況就非常明顯。本文提供以下兩個思路:
- 盡量在本地節點內進行Join,充分利用Local Join特性,大大減少跨網絡訪問。具體做法為:盡量采用一級分區鍵關聯;
- 盡量在本地節點內進行聚合分析,減少跨網絡訪問shuffle的數據量。具體做法為:盡量對一級分區鍵進行GROUP BY。
04 AnalyticDB連接的最佳實踐
在使用方法上,AnalyticDB與MySQL的兼容程度高達99%以上,支持多種連接方式,包括MySQL命令行,JDBC連接,Python連接,C#連接,PHP連接等等。更詳細地使用方法,請參考官方文檔:連接集群 - 云原生數倉 AnalyticDB MySQL - 阿里云。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。?
總結
以上是生活随笔為你收集整理的全网首发|阿里资深技术专家数仓调优经验分享(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构建制品不一致,后续工作都是白费 | 研
- 下一篇: 贾扬清谈云原生-让数据湖加速迈入3.0时