億級別大表拆分

2022-10-11 04:15:13 字數 3541 閱讀 5473

筆者是在兩年前接手公司的財務系統的開發和維護工作。在系統移交的初期,筆者和團隊就發現,系統內有一張5000w+的大表。跟蹤**發現,該表是用於儲存資金流水的**,關聯著眾多功能點,同時也有眾多的下游系統在使用這張表的資料。進一步的觀察發現,這張表還在以每月600w+的資料持續增長,也就是說,不超過半年,這張表會增長到1個億!

這個資料量,對於mysql資料庫來說是絕對無法繼續維護的了,因此在接手系統兩個月後,我們便開起了大表拆分的專項工作。(兩個月時間實際上主要用來熟悉系統、消化堆積需求了)

分表外掛程式:採用sharding-jdbc作為分表外掛程式。其優勢如下:1、支援多種分片策略,自動識別=或in判斷具體在哪張分表裡。2、輕量級,作為m**en依賴引入即可,對業務的侵入性極低。

為提公升查詢速度,在整個專案的初期,團隊成員考慮引入es儲存流水以提公升查詢速度。經過與es維護團隊的兩輪討論,發現公司提供的es服務對於我們的業務場景並不匹配(見表),經過反覆考量,最終我們放棄了引入es的計畫,直接從資料庫查詢資料,採用每張表設定乙個查詢執行緒的方式提公升查詢效率。

技術方案讀寫

開發成本

弊端sharding-jdbc+es

es資料庫+es

1.向sharding資料來源中寫資料,向es推送資料2.針對查詢需要開發從es讀取資料的api

1.es針對資金特有的多字段匹配搜尋支援的不是很好2.es 支援每次返回的條數有限,個別大批量查詢的功能無法支援3.es不提供特定地集群儲存資金流水資料4.es支援分頁查詢效果不好,有可能比使用資料庫查詢速度更慢

sharding-jdbc

資料庫資料庫

1.向sharding資料來源和原有資料來源中寫資料2.根據查詢條件判斷從sharding資料來源讀取資料還是從原有資料來源讀取資料

1.資金業務場景下sharding支援分頁查詢不夠友好,需要自己實現分頁查詢邏輯2.sharding需要自己定義資料源,涉及到多資料來源事務處理問題

分表的方式有很多種,有縱向分表,有橫向分表,有分為固定的幾個表儲存然後取模進行表拆分等等。總的來說,適合我們具體業務的分表方式只有橫向分表。因為對於資金流水這種特殊資料來說,是不能清理資料的,那麼縱向分表和拆成固定的幾個表都不能解決單錶資料無限膨脹的問題。而橫向分表,可以把每張表的資料量恆定,到一定時間後可以進行財務資料歸檔。

分表的依據一般都是根據表的某個或者某幾個字段進行拆分,最終其實是對資料和業務分析綜合出來的結果。總的來說,原則有這幾個:

綜合分析我們的資料以及業務需要,「交易時間」這個分表依據就呼之欲出了。首先,這個字段作為流水最重要的字段之一一定會出現;第二,如果按照交易月份進行拆表,每張表大概也就是600w-700w的資料;最後,有70%的查詢都附帶「交易時間」作為查詢條件。

多資料來源事務問題

sharding-jdbc在使用的時候是需要用自己的獨立資料來源的,那麼就難免出現多資料來源事務問題。這個我們通過自定義註解,自定義切面開啟事務,通過方法棧逐層回滾or提交的方式解決的。出於保密原則,具體**細節不再展開。

多表的分頁問題

綜合考慮業務實際與開發的複雜程度,專案團隊決定在出現跨表查詢的情況下,每一張表採用乙個執行緒進行查詢,以提高查詢效率。這個方案的難點在於分頁規則的轉換。例如,頁面傳入的offset和pagesize分別為8和20。各分表中符合條件的數量分別為10,10,50。那麼我們需要將總的分頁條件轉化為三個分表各自的分頁條件,如圖

通過上圖可以看到,大分頁條件(offset=8,pagesize=20),轉換為(offset=8,pagesize=2),(offset=0.pagesize=10),(offset=0,pagesize=8)三個條件。整個計算過程如下:

1)      多執行緒查詢各個分表中滿足條件的資料數量

2)      將各個表數量按照分表的先後順序累加,形成圖 8的數軸

3)      判斷第一條資料和最後一條資料所在的表

4)      除第一條和最後一條資料所在表外,其他表offset=0,pagesize=總數量

5)      計算第一條資料的offset,pagesize

計算最後一條資料的pagesize,同時將該錶查詢條件的offset設定為0

在資料遷移前,團隊討論過兩套遷移方案:1)請dba遷移資料;2)手寫**遷移資料,他們各有自己的優缺點:

遷移方案

方案詳細描述

優點缺點

dba遷移資料

1.遷移資料期間將流量切換至master庫2.採用insert into tablea select * from tableb的指令碼遷移資料

1.遷移過程遇到問題可以找dba協助

1.訪問流量遷移至master庫,有可能出現訪問資料庫網路等未知問題2.主從同步延遲很大,會影響到整個集群3.遷移速度過慢,因為涉及到掃瞄全表不走索引的情況

**遷移資料

1.通過介面呼叫的方式來遷移資料2.採用select * from table where id > ? limit ?的指令碼查詢資料,逐條插入資料庫中

1.遷移資料速度可控2.主從同步延遲不明顯3.可提前將歷史資料進行遷移

1.容易出現大事務問題2.容易出現操作失誤3.遷移的歷史資料出現前後不一致的情況4.遷移持續時間較長,實際操作中整個遷移過程長達兩個星期

綜合考慮時間成本和對線上資料庫的影響,團隊決定採用兩種方案結合的方式:交易時間為三個月前的冷資料,由於更新機率不大,採用**的方式遷移,人為控制每次遷移數量,少量多次,螞蟻搬家;交易時間為三個月內的熱資料,由於會在上線前頻繁出現更新操作,則在上線前停止寫操作,而後由dba整體遷移。這樣將時間成本平攤到平時,上線前只有約2個小時左右遷移資料時系統無法使用。同時,除了最後一次dba遷移資料外,能夠人為控制每次遷移的資料量,整體避免資料庫例項級別的高延遲。

為保證新錶拆分功能的穩定性和大表下線的穩定,團隊將整個專案分為三個階段:

第一階段:建立分表,大表資料遷移分表,線上資料新錶老表雙寫,所有查詢走分表

(驗證觀察)

第二階段:停止寫老資料表,其他業務直連資料庫改為資金提供對外介面

(驗證觀察)

第三階段:大表下線

為啥說想說點兒題外話呢,主要是對這次延續了5個多月的專案有感而發。專案進行過程中,難免會與其他系統的維護團隊有工作上的交集,有需要其他團隊配合的地方。這個時候非常考驗程式設計師的溝通能力,最優秀的程式設計師能夠通過話術把對方拉到自己的陣線當中,讓對方感到這項工作對自己也是有好處的。這樣能夠讓對方心甘情願的配合你的工作,達到雙贏的目的。如果程式設計和學習能力是程式設計師的硬實力,那溝通技巧就是程式設計師的軟實力,硬實力能夠保障你的下線,而決定上線的恰恰是軟實力。因此很多程式設計師不注重溝通技巧的培養,其實是相當於瘸腿的,畢竟現在憑單打獨鬥是不大可能做出事情的。

另外,至少對於我們單位來說,對後端程式設計師的綜合素質其實要求最高。後端程式設計師集業務、技術於一身。需要有比較強的業務把控能力,還要有過硬的技術素質。同時,大多數工作的主owner是後端,一般都是後端程式設計師把控前端、後端、qa的開發節奏,協調好各個時間點,做好風險反饋。這就要求後端程式設計師既要懂業務,還要懂技術,還需要有一定的管理能力。這其實對人的鍛鍊還是很可觀的。

MyCat 第七章 MyCAT的億級別任務

top 1 億級別的大量結果集排序 分組 group by 分頁 limit 的優化問題 資料 目前假如乙個查詢sql跨越30個分片,每個分片上有1000萬資料,則總資料規模為3億,select from a orderby field1,field2 limit 100000,100 即取出排序結...

排序演算法 n 2級別

n 2級別的演算法,是排序演算法中,效率最低的,也稱暴力法。主要有 選擇排序,插入排序,氣泡排序。效率較高的希爾排序 1.選擇排序 selection sort 原演算法思想是 從左到右遍歷出最大的,放到右端。然後繼續,每次拿出最大的,放在右端。template void selectionsort...

Sqlmap學習系列之二 級別

sqlmap有多個與等級相關的引數 1 v 按照官方文件說明,v 意為 verbose verbosity level 0 6 default 1 即 詳細等級包括0 6級,預設為1級 在測試語句最後以 v 等級 出現。經指正,詳細等級是指測試結果的輸出的詳細程度。2 level 按照官方文件說明,...