分片規則概述
在數據切分處理中,特別是水平切分中,中間件最終要的兩個處理過程就是數據的切分、數據的聚合。選擇合適的切分規則,至關重要,因為它決定了后續數據聚合的難易程度,甚至可以避免跨庫的數據聚合處理。
前面講了數據切分中重要的幾條原則,其中有幾條是數據冗余,表分組(Table Group),這都是業務上規避跨庫join的很好的方式,但不是所有的業務場景都適合這樣的規則,因此本章將講述如何選擇合適的切分規則。
Mycat全局表
如果你的業務中有些數據類似於數據字典,比如配置文件的配置,常用業務的配置或者數據量不大很少變動的表,這些表往往不是特別大,而且大部分的業務場景都會用到,那么這種表適合於Mycat全局表,無須對數據進行切分,只要在所有的分片上保存一份數據即可,Mycat 在Join操作中,業務表與全局表進行Join聚合會優先選擇相同分片內的全局表join,避免跨庫Join,在進行數據插入操作時,mycat將把數據分發到全局表對應的所有分片執行,在進行數據讀取時候將會隨機獲取一個節點讀取數據。
目前Mycat沒有做全局表的數據一致性檢查,后續版本1.4之后可能會提供全局表一致性檢查,檢查每個分片的數據一致性。
全局表的配置如下
<table name="t_area" primaryKey="id" type="global" dataNode="dn1,dn2" />
ER分片表
有一類業務,例如訂單(order)跟訂單明細(order_detail),明細表會依賴於訂單,也就是說會存在表的主從關系,這類似業務的切分可以抽象出合適的切分規則,比如根據用戶ID切分,其他相關的表都依賴於用戶ID,再或者根據訂單ID切分,總之部分業務總會可以抽象出父子關系的表。這類表適用於ER分片表,子表的記錄與所關聯的父表記錄存放在同一個數據分片上,避免數據Join跨庫操作。
以order與order_detail例子為例,schema.xml中定義如下的分片配置,order,order_detail 根據order_id進行數據切分,保證相同order_id的數據分到同一個分片上,在進行數據插入操作時,Mycat會獲取order所在的分片,然后將order_detail也插入到order所在的分片。
<table name="order" dataNode="dn$1-32" rule="mod-long"><childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="order_id" /></table>
多對多關聯
有一類業務場景是 “主表A+關系表+主表B”,舉例來說就是商戶會員+訂單+商戶,對應這類業務,如何切分?
從會員的角度,如果需要查詢會員購買的訂單,那按照會員進行切分即可,但是如果要查詢商戶當天售出的訂單,
那又需要按照商戶做切分,可是如果既要按照會員又要按照商戶切分,幾乎是無法實現,這類業務如何選擇切分規則非常難。目前還暫時無法很好支持這種模式下的3個表之間的關聯。目前總的原則是需要從業務角度來看,關系表更偏向哪個表,即“A的關系”還是“B的關系”,來決定關系表跟從那個方向存儲,未來Mycat版本中將考慮將中間表進行雙向復制,以實現從A-關系表 以及B-關系表的雙向關聯查詢如下圖所示:
主鍵分片vs 非主鍵分片
當你沒人任何字段可以作為分片字段的時候,主鍵分片就是唯一選擇,其優點是按照主鍵的查詢最快,當采用自動增長的序列號作為主鍵時,還能比較均勻的將數據分片在不同的節點上。
若有某個合適的業務字段比較合適作為分片字段,則建議采用此業務字段分片,選擇分片字段的條件如下:
1.盡可能的比較均勻分布數據到各個節點上;
2.該業務字段是最頻繁的或者最重要的查詢條件。
常見的除了主鍵之外的其他可能分片字段有“訂單創建時間”、“店鋪類別”或“所在省”等。當你找到某個合適的業務字段作為分片字段以后,不必糾結於“犧牲了按主鍵查詢記錄的性能”,因為在這種情況下,MyCAT提供了“主鍵到分片”的內存緩存機制,熱點數據按照主鍵查詢,絲毫不損失性能。
<table name="t_user" primaryKey="user_id" dataNode="dn$1-32" rule="mod-long"><childTable name="t_user_detail" primaryKey="id" joinKey="user_id" parentKey="user_id" /></table>
對於非主鍵分片的table,填寫屬性primaryKey,此時MyCAT會將你根據主鍵查詢的SQL語句的第一次執行結果進行分析,確定該Table 的某個主鍵在什么分片上,並進行主鍵到分片ID的緩存。第二次或后續查詢mycat會優先從緩存中查詢是否有id–>node 即主鍵到分片的映射,如果有直接查詢,通過此種方法提高了非主鍵分片的查詢性能。
本節主要講了如何去分片,如何選擇合適分片的規則,總之盡量規避跨庫Join是一條最重要的原則,下一節將介紹Mycat目前已有的分片規則,每種規則都有特定的場景,分析每種規則去選擇合適的應用到項目中。