切分策略
切分維度的選擇是決定分布式數據最重要的一個權衡性因素,需要審慎選擇,一般而言,可以按照以下五個維度進行思考和權衡,包括數據均衡度考慮、事務邊界因素、常用查詢效率考慮、切片索引考慮、簡單性策略。
容量和訪問均衡
數據容量和訪問均衡是我們考量的第一點,不均衡的數據分布和訪問無法充分發揮數據拆分的能力,讓訪問體驗變差,同時帶來成本上的損耗。所以一般來說拆分字段區分度比較大,數據分布和訪問相對會比較均衡,但是這點也需要考慮到某一個拆分值是否有熱點的問題。
事務邊界
事務邊界越大(或者單個sql所執行的數據分片數),那么系統的鎖沖突概率越高,系統越難以擴展,性能越低。因此,若想將系統做到很好的擴展性,那么一個最重要的原則就是想辦法劃小事務邊界,并盡可能讓事務的邊界限制在單臺機器內。縮小事務邊界的方式。
常用查詢
對于常用查詢優化的核心要義,就是盡可能讓您的一次前端請求,物理上直接發送到一臺存儲的機器上,盡可能避免那些需要將請求下發到多臺機器的查詢。下發到多臺機器的查詢,雖然每次查詢的延遲不會出現問題,但這類查詢會導致一次請求物理上必須被發送到很大一批存儲的機器上,會額外占用過多下層數據節點的各類的資源,因此應該盡可能的予以避免。
切片索引
對常用的非分片鍵查詢條件構建切片索引,提升非分片鍵查詢(select語句)時的效率,避免廣播查詢。
保持簡單
如果查詢優化與均衡讀寫訪問兩個選項發生了沖突,那么請選擇均衡讀寫訪問作為優先考慮原則,因為查詢的問題相對的更好解決,無論是加機器做全表掃描或做切片索引都是可以解決的。而寫入或單機容量如果出現不均衡,處理起來難度就比較大。
盡管復雜的切分規則或取巧的程序代碼能夠帶來短期系統性能或成本上的好處,但其后面所帶來的系統運維復雜度上升將會吃掉之前您在系統中獲得的大部分好處。因此,從系統架構上來說,以82法則,簡單直接處理的方式往往是最有效的方式。
切分原則
分表分庫雖然能解決大表對數據庫系統的壓力,但它并不是萬能的,也有一些不利之處,因此首要問題為:分不分庫,分哪些庫,什么規則分,分多少分片。
原則一
分片數量盡量少,分片盡量均勻分布在多個DataHost 上,因為一個查詢SQL 跨分片越多,則總體性能越差,雖然要好于所有數據在一個分片的結果,只在必要的時候進行擴容,增加分片數量。
原則二
能不分片就不分片,800萬以內的表,不建議分片,通過合適的索引,讀寫分離等方式,可以很好的解決性能問題。
原則三
不到800 萬但跟大表(超800 萬的表)有關聯查詢的表也要拆分,在此稱為大表關聯表。大表關聯表如何拆:小于100 萬的使用全局表;大于100 萬小于800 萬跟大表使用同樣的拆分策略;無法跟大表使用相同規則的,可以考慮從java 代碼上分步驟查詢,不用關聯查詢,或者破例使用全局表。
原則四
破例的全局表(例如item_sku 表250萬行數據),跟大表關聯了,又無法跟大表使用相同拆分策略,也做成了全局表。破例的全局表必須滿足的條件:沒有太激烈的并發update,如多線程同時update 同一條id=1 的記錄。雖有多線程update,但不是操作同一行記錄的不在此列。多線程update 全局表的同一行記錄會死鎖,批量insert 沒問題。
原則五
拆分字段只能是一個字段,如果想按照兩個字段拆分,必須新建一個冗余字段,冗余字段的值使用兩個字段的值拼接而成(如大區+年月拼成zone_yyyymm 字段)。
原則六
分片規則需要慎重選擇,分片規則的選擇,需要考慮數據的增長模式,數據的訪問模式,分片關聯性問題,分片擴容問題以及數據熱點問題。
原則七
分片規則的選擇問題,如果某個表的數據有明顯的時間特征,比如訂單、交易記錄等,則他們通常比較合適用時間范圍分片,因為具有時效性的數據,我們往往關注其近期的數據,查詢條件中往往帶有時間字段進行過濾,比較好的方案是,當前活躍的數據,采用跨度比較短的時間段進行分片,而歷史性的數據,則采用比較長的跨度存儲。總體上來說,分片的選擇是取決于最頻繁查詢SQL 的條件。