1. 程式人生 > >技術分享 | 基於分散式中介軟體的SQL改造指南

技術分享 | 基於分散式中介軟體的SQL改造指南

原創: 孫正方


4月12日,GOPS全球運維大會在深圳隆重召開,全球運維大會是國內第一個運維行業大會,愛可開源社群在基礎架構及DevOps解決方案專場分享了《基於分散式中介軟體的SQL改造指南》的主題演講。

本文由根據演講內容進行整理,希望有助於大家對分散式架構的理解及SQL改造實踐。

 

一.中介軟體中的簡單SQL

 

1.簡單SQL的分類

在一般SQL中,一個單表查詢的SQL往往是最簡單的,而在中介軟體中也沒什麼區別,中介軟體中將一個對於單表的欄位查詢作為最簡單的SQL進行處理。

 

2.中介軟體對於簡單SQL的處理方式

下面先來簡單的回顧下中介軟體中的表格處理的最基礎方式。

 

中介軟體會按照在配置檔案中既定的資料拆分的設定,對於“使用者表”這個表格的資料進行拆分,將每條通過中介軟體插入的資料按照規則進行分佈,圖上給的例子是按照“使用者表”的ID奇偶性進行了資料的拆分。

有了合理的資料分佈之後就是中介軟體是如何在需要的時候取用資料,在中介軟體中,對於基礎SQL,也就是單表的資料查詢分為一下兩個情況:

 

  • 帶有分片資訊的資料查詢:下圖展示了一個例子,在單表查詢的過程中,如果存在影響資料分佈的查詢條件(在此例子中為使用者的ID=1),

在查詢的簡單SQL附帶有分片條件時,中介軟體根據SQL語義解析的結果,根據這個分片條件對於資料可能存在的DB進行計算,最終把SQL轉發到對應的DB中進行執行,查詢出最終的正確結果。

 

  • 不帶有分片資訊的資料查詢(廣播):當查詢的SQL不帶有分片條件時,中介軟體只好把SQL內容傳送到表格涉及到的所有DB中,並從每個DB中返回資料並整合。

在這個過程中就存在一個現象,即“這一個查詢需要等待最慢的那個DB查詢結束”。

 

3.簡單SQL的注意事項

上文中有提及廣播型別的簡單SQL存在一個特徵“需要等待最慢的那個DB查詢結束”,當分片數量持續上升的時候,如下圖所示的場景,需要等待的連線數量會持續變多。

可以通過概率的方法分析下當連線數量增長的時候會發生什麼變化:

通過Matlab對於中介軟體廣播查詢的場景進行了如下的模擬,可以發現在隨著需要等待連線數量的上升,整體的中介軟體響應速度會有一個成倍的下降,從單個連線平均5ms的查詢延遲一直上升到100連線時候的接近15ms的整體延遲。

針對以上的場景,提出在中介軟體中進行單表查詢的時候,儘量降低單個SQL涉及到的後端DB數量,具體方法是在SQL中給表格新增分片列的限定條件,就像select * from 使用者表 where ID = 1中的這個條件ID =1。

 

二.中介軟體中的ER表格JOIN

 

1.中介軟體中ER關係的定義

單表查詢不能覆蓋應用對於SQL的需求,中介軟體中就引入了ER關係的概念。

ER關係指的是兩個表格在邏輯上就擁有的從屬關係,如下圖中所示的使用者表和訂單表:

當兩個表或者更多的表格存在這樣邏輯上的從屬關係的時候,在中介軟體中把這些關係定義為ER關係,並且當一個查詢語句有且僅有存在ER關係的表格關聯組成的時候,這個SQL被稱為“ER表格JOIN”。

 

2.中介軟體對於ER表格JOIN的處理方式

當兩個表格能夠被定義為ER關係的時候,中介軟體能夠按照之間的關聯關係組織資料的儲存,最後的儲存方式如下圖所示:

可以看到大致的結果就是子表(訂單表)的資料會被存放在父表(使用者表)對應資料的DB節點。

當出現這種資料分佈的時候,就可以在DB1中查詢到上例中張三的使用者和他的所有資料,所以中介軟體就能直接把SQL語句下發到對應節點進行執行。

 

3.ER關聯SQL的注意事項

可以看到ER的這種查詢方式是有一定的侷限的,需要把查詢的表格宣告為ER關係,並且ER關係還是單向的,就是一個表只能是某一個表的子表,一個分片表不能擁有兩個父表。

其次就是由於這個ER關聯的查詢處理是和上文的簡單查詢在本質上是一樣的,就是查詢SQL下發到DB中來執行,所以在注意事項上也是一致的,儘量在使用的時候提供能夠確定分片的限定條件。

 

 

三.中介軟體中的跨庫表格JOIN

 

1.跨庫表格JOIN的定義

事實上上文所有的查詢方法限制都是非常大的,但是往往應用的SQL無法滿足於被限制在這麼侷限的範圍內,那中介軟體中就有另一種機制來實現更廣泛意義上的SQL執行,跨庫表格關聯查詢。

當我的SQL內容無法被定義進入上文的兩個“簡單SQL”或者是“ER SQL”的時候,中介軟體就會使用這種跨庫表格JOIN的方式來處理這個問題,當然並非所有的中介軟體都有實現對應的功能,在這裡僅討論實現的部分中介軟體的實現邏輯。

 

2.中介軟體中跨庫表格JOIN的執行

以下是在中介軟體中執行跨庫表查詢的這麼一個大致執行邏輯圖,圖中可以看到整體的執行邏輯是從每個DB中分別取TABLEA和TABLEB的資料,最終在中介軟體中進行資料的整理組織和對比:

具體的跨庫查詢的執行過程可以被歸納為以下的幾個步驟:

  • 根據配置檔案中對於TABLEA和TABLEB的描述將表格的資料分別從DB中進行查詢

  • 對於查詢得到的表格資料進行整理,分別按照ID的值(關聯列的值)進行排序和歸檔

  • 對於歸檔完成的資料進行ID值的對比,計算關聯結果

在這個過程中會產生幾個方面的資源消耗:

  • 組織資料產生的臨時記憶體儲存消耗

  • 對比資料產生的CPU消耗

  • 查詢每一個存在DB中的表資料產生的連線數以及網路消耗

另一個方面就是中介軟體由於不能儲存真實的資料,所以無法像MySQL優化器一樣提前計算不同表格的聚合代價,這麼一來,中介軟體就直接按照SQL中原有的表格聚合順序進行資料的聚合和整理,這可能帶來以下的SQL執行的計劃。

案例中使用者表由於表格順序的問題先和沒有直接關係的商品表進行了表關聯,這樣一來這裡的中間結果就出現了一個笛卡爾積,也就是無條件無欄位的關聯結果,其結果為雙邊資料的乘積:

1000X1000=1000000

如果SQL中的表格順序進行進一步的優化,則可以在同樣的SQL中獲得以下圖中的執行順序。

這次我們優化完成之後的查詢中間結果將由使用者表和有關係的訂單表優先聚合完成,因為他們之間的關係,最多存在2000條中間結果,相比與上例中的1000000條來說,整個SQL執行效率上得到了很大的優化

 

3.跨庫JOIN的注意事項

針對以上的幾種消耗型別,可以通過以下的幾個手段進行降低消耗的量以獲取最好的執行效果:

  • 新增足夠的限定條件

  • 使用重複率低的列進行關聯

  • 通過手動調整SQL中表格順序的手段來進行執行計劃的調整

 

四.通篇總結

從DB儲存到真正成熟的分散式DB,分散式中介軟體的架構是整個過程中的重要一環,在分散式架構的過程中,對SQL的規範和使用存在一些特別要求,應用在向這方面進行改造和適應的過程中需要更多的考慮到中介軟體架構帶來的限制及相關注意事項。整體歸納可分為以下內容:

1.在中介軟體中儘量使用分片條件進行資料的查詢,不論整個SQL是屬於簡單SQL,ER查詢或者是複雜查詢。

2.在複雜查詢的狀態下,優化方向為中介軟體中處理的資料儘量少,此目標可以通過給表格新增限定條件,選擇更加重複率低的關聯列以及調整SQL中的表格關