Hologres是一款高效能的、計算儲存分離的分布式一站式即時數倉引擎,資料存放區在位於底層儲存系統的資料分區(又稱Shard)上。本文為您介紹Hologres中Table Group和Shard Count的概念。
Table Group和Shard
在Hologres中資料存放區在Pangu系統上,Shard表示資料分區,Table Group則是用於管理這些Shard,類似於儲存邏輯概念。一個表的資料將會儲存在固定的一組Shard上,資料寫入時會按照Distribution Key將資料分發到具體的Shard上。從建立表開始,負責儲存表資料的這一組Shard就已經分配好了,Table Group則負責管理這一組Shard。
Table Group是Hologres特有的一個儲存邏輯概念(PostgreSQL無此概念)。Table Group與PostgreSQL中的TABLESPACE是不一樣的:TABLESPACE唯一標識了資料庫物件的儲存位置,類似一個目錄的概念。而Table Group代表的是底層的邏輯Shard組。
Table Group布局圖如下:通過Table Group布局圖,可以看出:
Table Group與Schema的區別
Schema是一個標準的資料庫概念,而Table Group是一個邏輯儲存概念,並非資料庫標準。不同Schema下的表可以位於同一個Table Group,即底層使用同一組Shard儲存。
Table Group與資料庫(DB)的關係
一個DB可以包含一個或者多個Table Group,但是一個DB只能有一個預設Table Group。在建立DB之後,系統會建立一個預設Table Group,可以根據業務情況增加Table Group或者修改預設Table Group。
不同Table Group的區別
一個DB可以存在多個Table Group,但Table Group之間的Shard互不相交,每個Shard在執行個體層級擁有單獨的編號。
Shard Count
一個Table Group中Shard的數量稱為Shard Count。Shard Count在建立Table Group時指定,所以Table Group一旦建立,Shard Count就不能調整,如需調整Shard Count,需要重新建立Table Group並指定Shard數。
Shard與Table的關係
Shard負責表資料的儲存和查詢,系統根據Distribution Key決定表資料分布在哪些Shard,如果沒有設定Distribution Key,那麼資料就會被隨機分配到各個Shard。
一個Table Group中可以有多個Table,即多個Table可以分布在同一組Shard上。但是一個Table只能屬於一個Table Group,如果Table Group中沒有Table,那麼Table Group會被系統自動刪除。
如果Table的資料要從一個Table Group遷移至另外一個Table Group,那麼需要重建立表指定Table Group,或者通過遷移函數將資料進行遷移。
Shard與計算節點Worker的關係
在Hologres中儲存引擎Storage Engine(SE)主要負責管理和處理資料,在DML的功能上,SE提供了單條或者批量的建立、查詢、更新、和刪除(CRUD操作)存取方法的介面,查詢引擎(QE)可以通過這些介面訪問Shard上的資料,從而實現資料的高效能寫入或者讀取。
計算節點Worker、SE、Shard的布局關係圖如下。從圖中可以看出Table Group和Shard不僅與資料的儲存分布有關係,還與計算Worker有一定的關係:
當建立Table Group並設定Shard數後(如果沒有顯式設定Table Group和Shard數,那麼Hologres會在建立資料庫時建立一個預設Table Group並為其設定預設的Shard Count,詳情請參見執行個體規格概述),每個計算節點Worker會在內部建立多個SE,一個SE負責一個Shard資料的讀取和寫入。
系統機制會盡量保證每個Worker中的SE數量均勻,這樣能夠讓Worker計算資源均勻分配。
系統會保證一個Table Group內的Shard一定是分配給多個Worker,不會出現一個Table Group僅對應一個Worker,其餘Worker空置的情況。但如果Table Group的Shard數較少,但是執行個體規格較大即Worker較多,則會導致某些Worker無法分配Shard,導致某些Worker空置,因此在設計Shard數時一定要充分考慮業務情況,確保Worker的個數與執行個體總的Shard數有一定的均衡關係。
從上圖中能很容易看出一個問題:假如Table Group的Shard數與Worker個數不成比例關係(如上圖
Table Group 1
有3個Shard,但是只有2個Worker),那麼就一定會存在某個Worker比其他Worker多分配一個SE給Table Group的情況,這樣在計算時,就非常容易造成Worker資源傾斜,容易出現計算長尾。因此我們建議若是要修改Shard Count,建議Shard Count與計算Worker成一定的比例關係。如下圖所示Table Group 1
和Table Group 2
的Shard數都與Worker個數存在倍數關係,計算資源能夠均勻的分配。在實際業務中,可能會存在某個Worker因為OOM等原因出現Failover的情況,那麼該Worker對應的Shard將會在Worker Failover之後自動掛載在其他Worker上,系統會保證每個Worker新分配的Shard均勻。如下樣本,執行個體一共有4個Worker,2個Table Group共8個Shard,其中每個Worker有2個SE均勻對應Shard,當
Worker 4
Failover後,假設Worker 4
對應Shard 7
和Shard 8
,那麼Shard 7
和Shard 8
就會被快速分配給其他3個Worker,因為只有2個Shard,所以系統會隨機播放2個Worker進行分配,盡量保證Worker的SE數量均勻。
總結
Worker數量與Shard數有著非常緊密的聯絡。合理的設定Table Group與Shard Count,其資料寫入和查詢分析處理可以得到更大的並行度,將計算資源充分使用,從而從根本上提高資料的儲存與計算效率。反之如果Table Group和Shard數制定不當,很容易出現效能不如預期的情況,且無法從根本上調優到最佳效能:
一定範圍內Shard數多的Table Group,其資料寫入和查詢分析處理可以得到更大的並行度。但Shard數也並非越多越好,更多的Shard數需要更多的節點間通訊資源、計算資源以及記憶體資源,在資源不滿足的時候,或者Query很小時可能會導致適得其反的效果。
Shard數下限是1,在資料量只有幾百幾千條等很小的情況下,可以設定Shard數為1。一個Table Group上,Shard數的上限建議是執行個體的總計算Core數,這樣是為了保證每個Shard在計算時,至少可以佔據1個Core用於計算。如果Shard數超過計算Core數,那麼執行查詢時,將有部分Shard無法一直分到CPU資源,可能帶來長尾和切換開銷。
除Shard數量外,Table Group本身的數量也不是越多越好。每個Shard無論是否正在使用,都會佔據一定的記憶體空間,用於存放表中繼資料、Schema等資訊,在表有寫入時則會佔據更多記憶體空間。因此如果Table Group越多,則執行個體內總Shard數越多,記憶體空間佔用越大。另外多個表之間有一些特殊的關係(例如需要Local Join)時,這些表必須要處在同一Table Group下才行。
從磁碟上來看,Shard數越多,對於同樣的一張表,資料會分的越散,越容易出現小檔案,從而檔案個數更多。如果表多並且Shard也多,那檔案數量就會非常龐大。在查詢時Failover時都需要更多的開銷,造成查詢I/O增多,恢復變長。