本文為您介紹Hologres中Table Group和Shard Count選定的基本原則、適用情境、設定策略以及常見問題,以助您擷取更優的查詢效能。
執行個體規格推薦
在實踐過程中存在資料量可預估,最適宜的Shard數區間應該設定為多少的問題,由於最適宜Shard數不僅和資料存放區量有關,還和實際訪問頻率、實際資料訪問量、計算負載的類型(點查、分析等)、寫入吞吐、Table Group上表的個數等因素有關,該問題無法給出準確答案。您可參見下表中根據資料量估算的所需Shard數和執行個體規格的推薦數,選擇適合您的參數配置。
資料總規模 | 推薦Shard數 | 推薦規格 |
4000萬行以下 | 10~20 | 32Core以上 |
4000萬行~4億行 | 20~40 | 64Core以上 |
4億行~40億行 | 40~80 | 128Core以上 |
40億行~400億行 | 80~240 | 256Core以上,考慮建立新的Table Group |
400億行~4000億行 | 160~400 | 512Core以上,通常配置多個Table Group |
上表根據資料量估算的所需Shard數和執行個體規格的推薦數不是唯一標準,小資料量的表也可以放在多的Shard Count之上,巨量資料量的表也可以放在單個Shard上。請您根據實際業務情境選擇一個合適的Shard Count,既滿足有較高的並發度,帶來更高計算效率,又滿足資料較集中,從而避免不必要的Shuffle開銷。
建議一個Table Group下不要超過10000張表(包括分區子表,不包括外部表格),同一個Table Group中的表數量過多,會導致中繼資料堆積,從而降低DDL操作的執行速度。
您可以根據以下Table Group規劃的最佳實務,來決定是否需要建立以及如何放置Table Group。
規劃一:使用預設Table Group
如果您使用Hologres滿足下列條件,建議您直接使用預設Table Group即可。Hologres執行個體升配或降配後,預設Table Group的Shard數不會變,因此可以通過如下命令語句,查看Table Group的Shard數。
SELECT * FROM hologres.hg_table_group_properties; --結果樣本 tablegroup_name | property_key | property_value -----------------+---------------+---------------- test_tg_default | is_default_tg | 1 test_tg_default | shard_count | 40 test_tg_default | tg_version | 1 test_tg_default | table_num | 1 (4 rows)
資料量:
當前預設Table Group的Shard數,符合目前資料量大小的需求。可以使用預設Table Group直接建表。
總體規模:
全部表的資料量規模總和可控,可預估,使用方式沒有大的變化。
Local Join:
需要與已在預設Table Group的表,進行高效的Local Join。
規劃二:建立Table Group
如果預設Table Group不能滿足您的需求,那麼您可能需要多個Table Group。通常在如下條件下,在您的執行個體中可能需要多個Table Group:
資料量
已有Table Group的Shard數不適合當前表的預估資料量,例如,資料量小的表一般不適合放在大Table Group中,會造成小檔案太多,IO開銷變大,資料量大的表一般也不適合放在小Table Group中,造成查詢並發度下降。這是最常見的需要劃分多個Table Group的原因。
負載分離
已有的Table Group容納的表數量很多,且大多數表需要同時寫入,導致執行個體的負載很高,而即將建立的新表又需要較高的查詢和寫入吞吐,這時多個Table Group可以實現寫入和查詢一定程度上的獨立,不受其他表寫入查詢影響(更準確的負載分離請參考計算資源隔離章節)。或者經過問題排查,確定是已有Table Group無法滿足寫入和查詢需求時,也需要多個Table Group。
表的相關性
業務上有一系列具有獨特寫入或者查詢模式的表,且這一系列表之間具有(或未來具有)Local Join的需求(Local Join需要左右表同在一個Table Group才能實現,並且Join Key是各自的分布列),同時這些表和其他Table Group的表具有很淺的聯絡或根本沒有聯絡。這種情況下可以建立多個獨立的Table Group。也就是說,如果您有一組表之間相關性很強的表,而這組表與其他表相關性很低、聯集查詢的機率很低,可以考慮建立多個Table Group。
執行個體資源擴縮容
如果執行個體進行過擴、縮容超過5倍以上,原來定的Shard數很可能不再滿足需求,可以考慮更換預設Table Group。Shard數應大於計算節點數,小於執行個體總Core數的60%(即計算總Core數)。
規劃三:多個Table Group放置
如果需要規劃多個Table Group,那麼最好是能夠在壓測和生產之前,提前規劃好多個Table Group的作用與意義,以及每個表所屬的Table Group。規劃時可以考慮如下因素:
資料量
首先應該考慮的是資料量,也就是大表放更多的Shard,中小表放更少的Shard。
寫入效能需求
Shard數和資料寫入效能呈一定的正相關性,單個Shard的寫入能力是有上限的。Shard越多,寫入的並發越多,寫入的吞吐越高。因此,如果表有較高RPS的寫入需求,那麼可能需要增大shard數。Hologres單Shard將單core打滿時,寫入RPS為3000-5000條/秒(1KB/條),可以據此估算所需Shard數。考慮到每個shard還需要進行查詢等讀操作,一般不能使寫入打滿CPU,因此可以說,使用1/3core的shard,寫入RPS為1000條/秒(每條1KB)。因此,舉例而言,如果您要求寫入RPS 6W/s,每條1KB,則應該選擇的Shard數約在60Shard之上,視情況增減。
Table Group負載
在建立一個新的Table Group時,需要考慮當前Table Group需要承載的表數量。例如,如果未來放在此Table Group的表很多,並且多數表都需要經常訪問,那麼Shard數很小將會存在並發不夠的風險。
常見問題
我有512Core規格執行個體,主要針對一張即時事件表進行OLAP分析,表規模約200~400億,該怎麼設計Table Group和Shard Count?
計算負載比較單一,可以使用一個Table Group。512的預設Shard數為160,如果事件表列比較多,例如達到數百列,那麼為了加強OLAP分析的並發度,可以適當增大Shard數。例如更改DB的預設Table Group的Shard數為200,或200以上,以放置事件表。
我有256Core規格執行個體,有很多張列存表,主要進行毫秒級快速OLAP分析,每張表資料量千萬條層級,主要情境為group by多個欄位,以及按條件查明細,該怎麼設計Table Group和Shard Count?
計算負載比較單一,可以一個Table Group解決。256Core規格執行個體,預設Table Group的Shard數為120,而對於千萬層級的表,我們的建議是10-20shard,尤其對於group by等彙總操作,shard越多會有更多的shuffle開銷,無法應對毫秒級分析。因此,預設Table Group可能無法應對我們的需求,可以視具體情況,更改DB的預設Table Group的Shard Count為16~40之間,並進行壓測,效果會更好。
通過哪些手段排查慢Query是否為Shard Count不合適的原因?
Shard數不合適分為過多和過少兩種情況。
Shard數過多,一般會表現為:start query cost高,可以通過explain analyze後的start query cost行看出來;或者表現為shuffle開銷大,這點可以通過explain analyze後,查看Redistribution Motion的Max_GetNext_Time的大小來判定。v0.10以上,可以通過慢查詢日誌查看歷史Query的這些開銷。
Shard數過少,一般會表現為:長時間計算時CPU也無法打滿;或者scan資料的開銷比較大(因為並發度不足),這點可以通過explain analyze後,查看Scan Node的Max_GetNext_Time大小來判定;或者資料寫入的效能不足,上文提到Hologres單shard打滿單core時,寫入RPS為3000-5000,可據此估算Shard數是否過少。
我是點查的服務情境,我的QPS還不夠高,是不是Shard不夠的原因?
首先要判斷是不是別的原因引起的,例如並非點查而是分析查詢、未走索引、未做Shard裁剪以及CPU已經打滿等原因。當排查完後,不屬於上述情況,且單SQL效能達到極致後,如果QPS仍不滿足要求,則考慮增大shard數,以增大點查的後端並發。
如何排查Shard傾斜?
Hologres提供了內部欄位:hg_shard_id,即資料所在的Shard編號。可以通過SQL查看Shard傾斜情況。
SELECT hg_shard_id, COUNT(1) FROM <Table_Name> GROUP BY hg_shard_id ORDER BY COUNT(1) DESC;
如果有Shard上的資料量顯著高於其他Shard,則存在資料扭曲,可能需要調整分布列。