分布式 SQL 數(shù)據(jù)庫與表格優(yōu)化技術(shù)
分布式 SQL 數(shù)據(jù)庫會將應(yīng)用程序數(shù)據(jù)存儲在多個節(jié)點上,從存儲和計算的角度提高了可擴(kuò)展性。這種分布意味著某些應(yīng)用程序請求,包括 JOIN 操作和聚合,可能跨多個數(shù)據(jù)庫節(jié)點,可能導(dǎo)致數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸。
為了減輕網(wǎng)絡(luò)延遲對整體應(yīng)用程序性能的影響,一些數(shù)據(jù)庫支持共置和交錯表格。這種優(yōu)化技術(shù)允許將子表格記錄與其父行一起存儲。因此,在執(zhí)行查詢時,某些需要查詢父子記錄的請求可能會更快,因為數(shù)據(jù)庫節(jié)點在數(shù)據(jù)傳輸過程中的負(fù)載較小。
然而,像任何優(yōu)化技術(shù)一樣,共置和交錯表格也有其優(yōu)缺點。讓我們深入了解這些表格類型,以更好地理解它們的好處和權(quán)衡。
定義
共置表格(Colocated Tables)和交錯表格(Interleaved Tables)是數(shù)據(jù)庫中的優(yōu)化技術(shù),用于改善數(shù)據(jù)存儲和查詢性能。
共置表格(Colocated Tables)
共置表格是一種優(yōu)化方法,允許將子表格(child table)的記錄與其父表格(parent table)的行一起存儲在相同的物理位置或相鄰的位置。它通過將相關(guān)數(shù)據(jù)放置在同一節(jié)點或相近節(jié)點上來提高查詢效率,尤其對于需要頻繁進(jìn)行父子表格數(shù)據(jù)關(guān)聯(lián)的查詢來說,可以減少網(wǎng)絡(luò)傳輸和提升查詢性能。
交錯表格(Interleaved Tables)
交錯表格是共置表格的一種特殊類型。與共置表格不同的是,交錯表格會在同一物理表結(jié)構(gòu)和數(shù)據(jù)庫文件中將子行與其父行物理地相鄰存儲,而不是分開存儲。邏輯上,這些子表格和父表格仍然是不同的表格,但物理上它們的數(shù)據(jù)行被交錯存儲,這有助于更快地執(zhí)行聯(lián)合查詢和減少數(shù)據(jù)查找的次數(shù)。
總的來說,這些優(yōu)化技術(shù)旨在提高數(shù)據(jù)庫查詢效率,減少數(shù)據(jù)傳輸,特別是針對需要頻繁進(jìn)行父子表格數(shù)據(jù)關(guān)聯(lián)的查詢,通過優(yōu)化數(shù)據(jù)存儲和組織來改善性能。
共置表格
舉個例子: 設(shè)想一個虛構(gòu)公司開發(fā)電子商務(wù)應(yīng)用程序,允許各種商家在線銷售商品。
該應(yīng)用程序包括兩個關(guān)鍵表格,跟蹤 Customers(客戶)和他們的 Orders(訂單)(注意,顏色用于區(qū)分來自不同客戶的訂單)。
公司預(yù)計每天會有數(shù)百萬活躍客戶,并決定使用一個包含 3 個節(jié)點的分布式數(shù)據(jù)庫集群以增強可擴(kuò)展性和可用性。
在開發(fā)階段,數(shù)據(jù)庫均勻地分布了所有應(yīng)用程序記錄到集群中,確保每個節(jié)點存儲了可比較量的數(shù)據(jù)并處理了類似的讀寫工作負(fù)載。
在一個架構(gòu)委員會會議期間,公司決定嘗試共置表格功能,該功能允許將子表格記錄與父表格的行一起存儲。
結(jié)果,Order(子表格)與 Customer(父表格)共置,并且數(shù)據(jù)庫開始在相同節(jié)點上將訂單與其客戶記錄一起存儲。
團(tuán)隊選擇了實驗表共置技術(shù)來評估一些請求的性能改進(jìn),這些請求需要在 Customer 和 Order 表格之間進(jìn)行 JOIN 操作。例如,當(dāng)應(yīng)用程序需要計算客戶的總支出時,該請求將在特定的數(shù)據(jù)庫節(jié)點上執(zhí)行。
公司確實觀察到了一些查詢的性能改進(jìn)。
交錯表格
在電子商務(wù)服務(wù)的開發(fā)階段,公司探索了幾個分布式 SQL 數(shù)據(jù)庫。其中一個數(shù)據(jù)庫提供了交錯表格的支持,促使團(tuán)隊也嘗試了這種表格類型。
交錯表格是共置表格的一種特定類別。與共置表格類似,交錯表格將子表格記錄與其父表格記錄一起存儲。但與經(jīng)典共置表格不同,經(jīng)典共置表格在物理表格結(jié)構(gòu)中將子和父記錄存儲在不同的物理表格結(jié)構(gòu)中,交錯表格則在同一表格結(jié)構(gòu)和數(shù)據(jù)庫文件中 物理地 將子行放置在其父行旁邊(邏輯上,Customer 和 Order 仍然是不同的表格)。
通過這種存儲級別的優(yōu)化,公司發(fā)現(xiàn)了與之前經(jīng)典共置表格測試的相同查詢的額外性能增加。這種增加是因為客戶及其訂單存儲在內(nèi)存和磁盤中的同一頁面上,需要更少的查找。
共置和交錯表格權(quán)衡
隨著時間的推移,公司接近電子商務(wù)應(yīng)用程序的預(yù)生產(chǎn)測試階段,出現(xiàn)了新的挑戰(zhàn)。
當(dāng)團(tuán)隊加載一個生產(chǎn)級數(shù)據(jù)集并開始負(fù)載測試時,他們遇到了共置表格的第一個權(quán)衡 — 數(shù)據(jù)和負(fù)載傾斜。此外,由于新的業(yè)務(wù)需求,工程團(tuán)隊遇到了這些表格特定的另一個權(quán)衡 — 選擇最佳的父表格進(jìn)行共置。
數(shù)據(jù)和負(fù)載傾斜權(quán)衡
數(shù)據(jù)傾斜是指集群中的一個節(jié)點開始存儲比其他節(jié)點顯著更多的應(yīng)用程序記錄。這種不平衡通常導(dǎo)致負(fù)載傾斜,因為過載的節(jié)點必須處理更多的應(yīng)用程序請求并處理更大的數(shù)據(jù)量。
在早期開發(fā)階段,團(tuán)隊已經(jīng)注意到某些客戶比其他客戶更頻繁地購物。這種客戶行為導(dǎo)致某些數(shù)據(jù)庫節(jié)點存儲的訂單比其他節(jié)點多。例如,第二個節(jié)點最終存儲了比第一和
第三個節(jié)點合計更多的訂單(5 > 2 + 2 = 4)。
當(dāng)公司開始在使用生產(chǎn)級數(shù)據(jù)集的預(yù)生產(chǎn)環(huán)境中進(jìn)行測試時,這些數(shù)據(jù)和負(fù)載傾斜問題變得更加明顯。雖然某些客戶在系統(tǒng)中只有幾十個訂單,但其他購物頻率更高的客戶則積累了數(shù)百甚至數(shù)千個通過應(yīng)用程序處理的訂單。
這些經(jīng)常購物的顧客是某些節(jié)點存儲和處理更多數(shù)據(jù)的主要原因。
據(jù)我所知,針對這種特定的數(shù)據(jù)傾斜問題沒有簡潔的解決方案。共置表格將子記錄映射到存儲父記錄的節(jié)點,并且每個父記錄一次只能映射到一個數(shù)據(jù)庫節(jié)點。
因此,為了將特定客戶的訂單分布到多個節(jié)點,必須有多個標(biāo)識該客戶的記錄。例如,通過在 Customer 主鍵 (id, bucket) 中添加 bucket ID,你可以為經(jīng)常購買者創(chuàng)建多個記錄 — Customer (1, 1), Customer (1, 2), Customer (1, 3) 等。然后,可以將客戶的訂單添加到特定的桶中,從而允許數(shù)據(jù)庫將它們分布到多個節(jié)點。然而,這種方法使應(yīng)用程序邏輯變得更加復(fù)雜,需要決定桶的數(shù)量和每個新訂單的合適桶。
最佳父表格權(quán)衡
共置表格的第二個權(quán)衡與選擇最合適的父表格進(jìn)行共置有關(guān)。
實際上,電子商務(wù)應(yīng)用程序的數(shù)據(jù)庫架構(gòu)要復(fù)雜得多,涵蓋了許多關(guān)系和依賴關(guān)系。
例如,盡管客戶最初打算購買一件商品,但通常會最終在購物車中有幾個產(chǎn)品。因此,一個訂單可能包括兩個或更多已購買的產(chǎn)品。
假設(shè)公司引入了 SoldProducts 表格來跟蹤所有客戶訂單中銷售的產(chǎn)品。類似于 Orders 表格,決定將這個新表格與 Customer 表格共置。
選擇這種共置策略是有原因的。應(yīng)用程序經(jīng)常需要執(zhí)行請求,這些請求連接了 Customer、Order 和 SoldProduct 表格的數(shù)據(jù)。例如 — 客戶在最近一個月內(nèi)購買了什么產(chǎn)品?
因此,訂單和已售產(chǎn)品的記錄現(xiàn)在都與保持其客戶記錄的數(shù)據(jù)庫節(jié)點一起存儲。
然而,在預(yù)生產(chǎn)測試的中途,來自業(yè)務(wù)團(tuán)隊的新要求出現(xiàn)了。他們的目標(biāo)是優(yōu)先考慮一個專門用于商家和公司物流以及業(yè)務(wù)增長部門的微服務(wù)。該服務(wù)旨在使商家和公司能夠跟蹤和預(yù)測各種產(chǎn)品的需求和可用性。通過實施此功能,公司可以通過向具有相似喜好的客戶推薦熱門產(chǎn)品來提高銷售,而商家則可以主動補充產(chǎn)品。
工程團(tuán)隊決定將表 Product(子表格)記錄與 Merchant 表格(父表格)的行共置。
然而,從性能的角度來看,這種方法證明是不夠的,因為許多查詢需要連接 Merchant、Product 和 SoldProduct 表格的數(shù)據(jù)。這樣一個查詢的示例是 — 最近 12 小時內(nèi)購買的最熱門產(chǎn)品是什么?
從技術(shù)上講,將已售產(chǎn)品記錄存儲在相應(yīng)的商家附近是可行的。但有一個復(fù)雜問題 — SoldProduct 記錄已經(jīng)與 Customer 表格共置,以滿足另一個微服務(wù)的要求。
這是最佳父表格權(quán)衡的一個例子。例如,SoldProducts 表格一次只能與一個父表格共置。確定哪種共置策略從長遠(yuǎn)來看是最好的通常是一項困難的任務(wù)。
總結(jié)
像每一種優(yōu)化技術(shù)一樣,表共置和交錯都有其優(yōu)點和權(quán)衡。要確保共置不是你的用例的過早優(yōu)化,首先在沒有共置的情況下運行應(yīng)用程序工作負(fù)載。檢查查詢執(zhí)行計劃,并應(yīng)用避免需要共置表格的優(yōu)化。有時,你只需要創(chuàng)建適當(dāng)?shù)乃饕瑸?JOIN 操作啟用批處理,為頁面緩沖區(qū)提供更多內(nèi)存等 — 在看到執(zhí)行計劃之前你永遠(yuǎn)不會知道。但是,如果什么都不起作用,那么考慮共置表格,確保它們的權(quán)衡不會對長期產(chǎn)生不良影響。