本發(fā)明涉及數(shù)據(jù)處理技術(shù)領(lǐng)域,具體地說,涉及一種數(shù)據(jù)結(jié)轉(zhuǎn)方法及系統(tǒng)。
背景技術(shù):
對于大多數(shù)公司而言,隨著公司高速地成長和規(guī)模不斷地擴大,各種數(shù)據(jù)量也在瘋狂地增長,存放數(shù)據(jù)的數(shù)據(jù)庫表單容量達到上億甚至幾十億的規(guī)模。如果從這么大數(shù)據(jù)量的表中查詢出想要的數(shù)據(jù),會是一個很慢的過程,甚至會導致數(shù)據(jù)庫連接中斷或無響應(yīng),更嚴重的會導致數(shù)據(jù)庫崩潰,嚴重影響系統(tǒng)正常運行與用戶體驗。
目前的解決方案主要有以下兩種:
分庫分表:將數(shù)據(jù)庫和數(shù)據(jù)表拆分成多個,把數(shù)據(jù)分攤到不同的庫和表。
手動結(jié)轉(zhuǎn):手動將數(shù)據(jù)轉(zhuǎn)移到歷史庫。
通過分析不同的業(yè)務(wù)場景,發(fā)現(xiàn)上述技術(shù)方案存在以下不足:
針對分庫分表,首先,由于代碼的歷史遺留問題,開發(fā)成本大。其次,歷史數(shù)據(jù)和近期數(shù)據(jù)的耦合度不好。再有,維護成本大。
關(guān)于手動結(jié)轉(zhuǎn),效率低、耗時長,并且成本大。
技術(shù)實現(xiàn)要素:
本發(fā)明要解決的技術(shù)問題在于,針對現(xiàn)有技術(shù)的不足,提供一種數(shù)據(jù)結(jié)轉(zhuǎn)方法及系統(tǒng),用于高效率、低成本的完成數(shù)據(jù)結(jié)轉(zhuǎn)。
為解決上述技術(shù)問題,根據(jù)本發(fā)明的一個方面,本發(fā)明提供了一種數(shù)據(jù)結(jié)轉(zhuǎn)方法,其中,包括:
配置待結(jié)轉(zhuǎn)數(shù)據(jù)的數(shù)據(jù)源信息和結(jié)轉(zhuǎn)條件,其中,所述結(jié)轉(zhuǎn)條件包 括待結(jié)轉(zhuǎn)數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id;
對所述數(shù)據(jù)表分片,得到多個數(shù)據(jù)分片;和
采用多線程異步依次結(jié)轉(zhuǎn)所述多個數(shù)據(jù)分片。
優(yōu)選地,所述采用多線程異步結(jié)轉(zhuǎn)所述多個數(shù)據(jù)分片的步驟包括:
將每一個數(shù)據(jù)分片分割成多個子片;
每一子片作為一個子片數(shù)據(jù)結(jié)轉(zhuǎn)線程;
多個子片數(shù)據(jù)結(jié)轉(zhuǎn)線程并行執(zhí)行;和
當一個數(shù)據(jù)分片結(jié)轉(zhuǎn)完成后,采用上述步驟執(zhí)行下一個數(shù)據(jù)分片的結(jié)轉(zhuǎn),直到完成所有數(shù)據(jù)分片的結(jié)轉(zhuǎn)。
優(yōu)選地,在每一子片數(shù)據(jù)結(jié)轉(zhuǎn)線程執(zhí)行完之后還包括執(zhí)行刪除本子片數(shù)據(jù)的線程。
優(yōu)選地,所述子片數(shù)據(jù)結(jié)轉(zhuǎn)線程包括:
根據(jù)所述數(shù)據(jù)源信息連接到源數(shù)據(jù)庫;
根據(jù)子片數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id,查詢所述源數(shù)據(jù)庫,得到待結(jié)轉(zhuǎn)數(shù)據(jù);
將所述待結(jié)轉(zhuǎn)數(shù)據(jù)轉(zhuǎn)換成dll格式的字符串;和
將所述dll格式的字符串壓縮并上傳到目標存儲區(qū)。
優(yōu)選地,所述將所述dll格式的字符串壓縮并上傳到目標存儲區(qū)的步驟包括:
根據(jù)所述dll格式的字符串生成字節(jié)輸入流;
創(chuàng)建字節(jié)輸出流,并包裝成壓縮輸出流;
將所述字節(jié)輸入流寫入所述壓縮輸出流;和
將所述壓縮輸出流轉(zhuǎn)換成字節(jié)輸入流并上傳到目標存儲區(qū)。
為解決上述技術(shù)問題,根據(jù)本發(fā)明的另一個方面,本發(fā)明提供了一種數(shù)據(jù)結(jié)轉(zhuǎn)系統(tǒng),其中,包括:
配置模塊,用于配置待結(jié)轉(zhuǎn)數(shù)據(jù)的數(shù)據(jù)源信息和結(jié)轉(zhuǎn)條件,其中,所述結(jié)轉(zhuǎn)條件包括待結(jié)轉(zhuǎn)數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id
分片模塊;用于將所述數(shù)據(jù)表分片,得到多個數(shù)據(jù)分片;和
多個結(jié)轉(zhuǎn)模塊,分別與所述分片模塊連接,用于結(jié)轉(zhuǎn)所述多個數(shù)據(jù)分片。
優(yōu)選地,所述結(jié)轉(zhuǎn)模塊包括:
子片分割單元;與所述分片模塊連接,用于將一個數(shù)據(jù)分片分割為多個子片;
多個子片結(jié)轉(zhuǎn)單元,分別與所述子片分割單元相連接,用于結(jié)轉(zhuǎn)所述多個子片;和
多個數(shù)據(jù)刪除單元;分別與對應(yīng)的子片結(jié)轉(zhuǎn)單元相連接,用于刪除已成功結(jié)轉(zhuǎn)的子片數(shù)據(jù)。
優(yōu)選地,所述子片結(jié)轉(zhuǎn)單元包括:
數(shù)據(jù)查詢子單元;用于根據(jù)所述數(shù)據(jù)源信息連接到源數(shù)據(jù)庫,并根據(jù)子片數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id,查詢所述源數(shù)據(jù)庫,得到待結(jié)轉(zhuǎn)數(shù)據(jù);
數(shù)據(jù)轉(zhuǎn)換子單元;與所述數(shù)據(jù)查詢子單元相連接,將所述待結(jié)轉(zhuǎn)數(shù)據(jù)轉(zhuǎn)換成dll格式的字符串;
壓縮子單元;將所述dll格式的字符串壓縮;和
上傳子單元,將壓縮后的字符串上傳到目標存儲區(qū)。
本發(fā)明配置簡單,結(jié)轉(zhuǎn)方便,極大地簡化了結(jié)轉(zhuǎn)、備份的操作流程。并且,本發(fā)明在后臺采用多線程異步分割框架,生成文件不落地等方案,極大地提高了結(jié)轉(zhuǎn)、備份的效率。
附圖說明
通過參照以下附圖對本發(fā)明實施例的描述,本發(fā)明的上述以及其它目的、特征和優(yōu)點將更為清楚,在附圖中:
圖1為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)方法及系統(tǒng)的原理示意圖;
圖2為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)方法的簡要流程圖;
圖3為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)系統(tǒng)的原理結(jié)構(gòu)示意圖;
圖4為本發(fā)明所述結(jié)轉(zhuǎn)模塊的原理結(jié)構(gòu)示意圖;
圖5為本發(fā)明所述結(jié)轉(zhuǎn)數(shù)據(jù)分片的簡要流程圖;
圖6為本發(fā)明所述子片結(jié)轉(zhuǎn)單元的原理結(jié)構(gòu)示意圖;
圖7為本發(fā)明所述子片數(shù)據(jù)結(jié)轉(zhuǎn)線程的簡要流程圖;和
圖8為本發(fā)明所述字符串壓縮并上傳的簡要流程圖。
具體實施方式
以下基于實施例對本發(fā)明進行描述,但是本發(fā)明并不僅僅限于這些實施例。在下文對本發(fā)明的細節(jié)描述中,詳盡描述了一些特定的細節(jié)部分。對本領(lǐng)域技術(shù)人員來說沒有這些細節(jié)部分的描述也可以完全理解本發(fā)明。為了避免混淆本發(fā)明的實質(zhì),公知的方法、過程、流程沒有詳細敘述。另外附圖不一定是按比例繪制的。
附圖中的流程圖、框圖圖示了本發(fā)明實施例的系統(tǒng)、方法、裝置的可能的體系框架、功能和操作,流程圖和框圖上的方框可以代表一個模塊、程序段或僅僅是一段代碼,所述模塊、程序段和代碼都是用來實現(xiàn)規(guī)定邏輯功能的可執(zhí)行指令。也應(yīng)當注意,所述實現(xiàn)規(guī)定邏輯功能的可執(zhí)行指令可以重新組合,從而生成新的模塊和程序段。因此附圖的方框以及方框順序只是用來更好的圖示實施例的過程和步驟,而不應(yīng)以此作為對發(fā)明本身的限制。
如圖1所示,為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)方法及系統(tǒng)的原理示意圖。用a通過頁面填寫配置信息,所述的配置信息包括數(shù)據(jù)源信息(包含數(shù)據(jù)庫類型,數(shù)據(jù)庫連接串,用戶名,密碼)和結(jié)轉(zhuǎn)條件(包含開始時間,結(jié)束時間,開始序列,即數(shù)據(jù)表轉(zhuǎn)的起始主鍵id,結(jié)束序列,即數(shù)據(jù)表轉(zhuǎn)的結(jié)束主鍵id)。該配置信息通過nginx發(fā)送給配置服務(wù)器,由配置服務(wù)器將這些配置信息存儲到配置數(shù)據(jù)庫mysql中,并由zookeeper集群根據(jù)用戶a的結(jié)轉(zhuǎn)指令采用多線程異步的方式分批處理不同的數(shù)據(jù),即將需要結(jié)轉(zhuǎn)的數(shù)據(jù)從源數(shù)據(jù)庫中遷移到目標存儲區(qū),如jss。本發(fā)明中的每個結(jié)轉(zhuǎn)線程經(jīng)過查詢、轉(zhuǎn)換、上傳的流程,這個流程采用數(shù)據(jù)不落地(即不在磁盤生成文件)方案實現(xiàn)快速壓縮上傳,避免了與磁盤的交互,減少io操作,所以極大提升了性能。在每一個結(jié)轉(zhuǎn)線程完成后,由一個結(jié)果線程刪除所述結(jié)轉(zhuǎn)線程結(jié)轉(zhuǎn)的數(shù)據(jù),這樣可以保證下一批數(shù)據(jù)的查詢始終從0開始,解決了大數(shù)據(jù)查詢緩慢的問題。接著用同樣的方式處理下一批數(shù)據(jù)。當其中一個線程查詢無數(shù)據(jù)時,標明已無數(shù)據(jù),等待本批次的其他線程完成工作后,結(jié)束結(jié)轉(zhuǎn)流程。本發(fā)明最大程度地利用系統(tǒng)資源,提升了處理效率。
具體地,參見圖2,圖2為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)方法的簡要流程圖;所述數(shù)據(jù)結(jié)轉(zhuǎn)方法包括以下步驟:
步驟s1,配置待結(jié)轉(zhuǎn)數(shù)據(jù)的數(shù)據(jù)源信息和結(jié)轉(zhuǎn)條件,其中,數(shù)據(jù)源信息包含數(shù)據(jù)庫類型、數(shù)據(jù)庫連接串(即用于連接到數(shù)據(jù)庫的一個參數(shù),例如數(shù)據(jù)庫的ip地址)、用戶名和密碼,所述結(jié)轉(zhuǎn)條件包括待結(jié)轉(zhuǎn)數(shù)據(jù)表的起始主鍵id、結(jié)束主鍵id、開始時間和結(jié)束時間等等;
步驟s2,對所述數(shù)據(jù)表進行分片,得到多個數(shù)據(jù)分片;
步驟s3,采用多線程異步依次結(jié)轉(zhuǎn)所述多個數(shù)據(jù)分片。
參見圖3,為本發(fā)明所述數(shù)據(jù)結(jié)轉(zhuǎn)系統(tǒng)的原理結(jié)構(gòu)示意圖。本發(fā)明所述的數(shù)據(jù)結(jié)轉(zhuǎn)系統(tǒng)包括:配置模塊1、分片模塊2和多個結(jié)轉(zhuǎn)模塊3。其中,所述配置模塊1用于實現(xiàn)步驟s1,即配置待結(jié)轉(zhuǎn)數(shù)據(jù)的數(shù)據(jù)源信息和結(jié)轉(zhuǎn)條件。所述分片模塊2用于實現(xiàn)步驟s2,即將所述數(shù)據(jù)表分片,得到多個數(shù)據(jù)分片。所述多個結(jié)轉(zhuǎn)模塊3用于實現(xiàn)步驟s3,其與所述分片模塊連接,分別結(jié)轉(zhuǎn)一個數(shù)據(jù)分片。
如圖4所示,為本發(fā)明所述結(jié)轉(zhuǎn)模塊的原理結(jié)構(gòu)示意圖。如圖5所示,為本發(fā)明所述結(jié)轉(zhuǎn)數(shù)據(jù)分片的簡要流程圖。結(jié)合圖4和圖5,對本發(fā)明如何結(jié)轉(zhuǎn)數(shù)據(jù)分片進行詳細說明。所述結(jié)轉(zhuǎn)模塊3包括:子片分割單元31、多個子片結(jié)轉(zhuǎn)單元32和多個數(shù)據(jù)刪除單元33。其中,所述子片分割單元31與所述分片模塊2連接,用于將每一個數(shù)據(jù)分片分割為多個子片;每一個子片結(jié)轉(zhuǎn)單元32分別與所述子片分割單元31相連接,用于結(jié)轉(zhuǎn)所述多個子片。所述多個數(shù)據(jù)刪除單元33與對應(yīng)的子片結(jié)轉(zhuǎn)單元32相連接,用于刪除已成功結(jié)轉(zhuǎn)的數(shù)據(jù)。
采用多線程異步結(jié)轉(zhuǎn)所述多個數(shù)據(jù)分片的具體過程如下:
步驟s31,取一個數(shù)據(jù)分片。
步驟s32,將每一個數(shù)據(jù)分片分割成多個子片,每一個子片作為一個任務(wù)。
步驟s33,并行執(zhí)行多個子片數(shù)據(jù)結(jié)轉(zhuǎn)任務(wù),即多線程并行執(zhí)行。
步驟s34,判斷是否全部的線程都執(zhí)行完成,如果都執(zhí)行完成,則執(zhí)行步驟s35,如果沒有,則繼續(xù)步驟s33,并且,如果有線程先執(zhí)行完,即沒有數(shù)據(jù)時,則等待本批其他線程。
步驟s35,判斷是否結(jié)轉(zhuǎn)完成所有的數(shù)據(jù)分片,如果全部的數(shù)據(jù)分片都結(jié)轉(zhuǎn)完成,則結(jié)束本次數(shù)據(jù)結(jié)轉(zhuǎn)。如果還有數(shù)據(jù)分片需要結(jié)轉(zhuǎn),則轉(zhuǎn)回步驟s31,重復上述步驟來執(zhí)行下一個數(shù)據(jù)分片的結(jié)轉(zhuǎn),直到完成所有數(shù)據(jù)分片的結(jié)轉(zhuǎn)。
更好地,在每一個子片數(shù)據(jù)結(jié)轉(zhuǎn)線程執(zhí)行完之后還包括執(zhí)行刪除本子片數(shù)據(jù)的線程。
如圖6所示,為本發(fā)明所述子片結(jié)轉(zhuǎn)單元32的原理結(jié)構(gòu)示意圖。所述子片結(jié)轉(zhuǎn)單元32包括:數(shù)據(jù)查詢子單元321、數(shù)據(jù)轉(zhuǎn)換子單元322、壓縮子單元323和上傳子單元324。其中,所述數(shù)據(jù)查詢子單元321用于根據(jù)所述數(shù)據(jù)源信息連接到源數(shù)據(jù)庫,并根據(jù)子片數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id,查詢所述源數(shù)據(jù)庫,得到待結(jié)轉(zhuǎn)數(shù)據(jù)。所述數(shù)據(jù)轉(zhuǎn)換子單元322與所述數(shù)據(jù)查詢子單元321相連接,將所述待結(jié)轉(zhuǎn)數(shù)據(jù)轉(zhuǎn)換成dll(dynamiclinklibrary,動態(tài)鏈接文件)格式的字符串。所述壓縮子單元323將所述dll格式的字符串壓縮。所述上傳子單元324用于將壓縮后的字符串上傳到目標存儲區(qū)。
圖7為本發(fā)明所述子片數(shù)據(jù)結(jié)轉(zhuǎn)線程的簡要流程圖;即單個線程的執(zhí)行過程。所述子片數(shù)據(jù)結(jié)轉(zhuǎn)線程包括:
步驟s331,根據(jù)所述數(shù)據(jù)源信息連接到源數(shù)據(jù)庫。
步驟s332,根據(jù)子片數(shù)據(jù)表的起始主鍵id和結(jié)束主鍵id,查詢所述源數(shù)據(jù)庫,得到待結(jié)轉(zhuǎn)數(shù)據(jù).
步驟s333,將所述待結(jié)轉(zhuǎn)數(shù)據(jù)轉(zhuǎn)換成dll格式的字符串。
步驟s334,將所述dll格式的字符串壓縮并上傳到目標存儲區(qū)。
由于業(yè)務(wù)邏輯代碼以長期增量的方式堆積,導致邏輯極其復雜和臃腫,更嚴重的是導致程序執(zhí)行的性能嚴重降低,為了解決這種問題,本發(fā)明在結(jié)轉(zhuǎn)所述數(shù)據(jù)分片時,采用了多線程分割的方法,也就是多任務(wù)并行執(zhí)行,同時單個任務(wù)內(nèi)部可以串行執(zhí)行的一種框架。具體原理及實現(xiàn)步驟說明如下:
第一步:將多個任務(wù)通過begin(開始任務(wù)),then(必須在begin之后執(zhí)行),after(非第一個執(zhí)行)等關(guān)鍵詞關(guān)聯(lián)起來,如begin(a).then(b),after(a).then(c)。
第二步:判斷關(guān)鍵詞,如果是begin,after,那么將begin,after任務(wù)作為key,null作為值存入identityhashmap。如果是then,將then線程作為value存入key為begin或者after的identityhashmap,構(gòu)建正向依賴,如果單個任務(wù)沒有依賴,則添加一個默認的依賴給它。該單個依賴可以認為最后一個執(zhí)行。如:
begin(a).then(b).then(c);
after(a).then(d).then(e);
after(a).then(f).then(g);
after(c,e,g).then(h);
生成的正向依賴:{e=[h],g=[h],h=[],a=[b,d,f],b=[c],f=[g],d=[e],c=[h]}。
第三步:根據(jù)正向依賴生成反向依賴,并保存每個反向依賴的size,如:h的size=3,a的size=0。
正向依賴:{e=[h],g=[h],h=[],a=[b,d,f],b=[c],f=[g],d=[e],c=[h]}。
反向依賴:{a=[],b=[a],e=[d],d=[a],g=[f],h=[e,g,c],c=[b],f=[a]}。
第四步:判斷反向依賴的size,如果等于0,那么a第一個開始執(zhí)行。
第五步:循環(huán)正向依賴的任務(wù),并遞減反向依賴size,遞減后如果等于0,才能運行,這樣可以確保h線程最后執(zhí)行。如:當a運行的時候,循環(huán)正向依賴任務(wù)[b,d,f],b,d,f的反向依賴size遞減一次后都為0,那么bdf可以同時異步運行,b運行的時候,循環(huán)正向依賴[c],c的反向依賴size遞減一次后為0,那么c開始運行,同理c運行的時候循環(huán)[h],h反向依賴的size=3,遞減一次后等于2,不滿足等于0的條件,那么h不能運行,只有當e,g都運行完成后,h的反向依賴size遞減3次后等于0,這時候h開始運行。
第六步:h線程開始運行,運行完成釋放鎖。
本發(fā)明利用上述原理,將數(shù)據(jù)結(jié)轉(zhuǎn)過程分別查詢數(shù)據(jù)庫、轉(zhuǎn)換成ddl、壓縮并上傳到j(luò)ss和刪除本子片數(shù)據(jù)4個步驟。那么采用多線程分 割框架包裝后就變成這樣:
begin(前置準備,分片標識);
after(查詢數(shù)據(jù)庫,轉(zhuǎn)換成ddl,壓縮并上傳到j(luò)ss).then(刪除本子片數(shù)據(jù));
after(查詢數(shù)據(jù)庫,轉(zhuǎn)換成ddl,壓縮并上傳到j(luò)ss).then(刪除本子片數(shù)據(jù));
after(查詢數(shù)據(jù)庫,轉(zhuǎn)換成ddl,壓縮并上傳到j(luò)ss).then(刪除本子片數(shù)據(jù));
……。
其中,begin(前置準備,分片標識):表示需要的準備工作,包括維護結(jié)轉(zhuǎn)條件、分片信息、任務(wù)名稱等。只有執(zhí)行完了這一步驟,才能執(zhí)行下面的步驟。
after(查詢數(shù)據(jù)庫,轉(zhuǎn)換成ddl,壓縮并上傳到j(luò)ss):每個after代表可以并行執(zhí)行的任務(wù),上面一共有n個after,那么并行執(zhí)行有n個線程,括號內(nèi)的描述是任務(wù)的具體內(nèi)容。
then(刪除本子片數(shù)據(jù)):表示這個任務(wù)必須在本after之后執(zhí)行,也就是與本after是串行的關(guān)系。
具體的執(zhí)行過程如前所述的說明,在此不再重復說明。
本發(fā)明在結(jié)轉(zhuǎn)數(shù)據(jù)時,采用快速壓縮上傳技術(shù),具體如圖8所示,為本發(fā)明所述字符串壓縮并上傳的簡要流程圖。
步驟s3341,根據(jù)所述dll格式的字符串生成字節(jié)輸入流;
步驟s3342,創(chuàng)建字節(jié)輸出流,并包裝成壓縮輸出流;
步驟s3343,將所述字節(jié)輸入流寫入所述壓縮輸出流;
步驟s3344,將所述壓縮輸出流轉(zhuǎn)換成字節(jié)輸入流并上傳到目標存儲區(qū)。
從上述的處理過程可見,本發(fā)明在數(shù)據(jù)結(jié)轉(zhuǎn)時沒有生成文件,沒有將文件壓縮,而是在內(nèi)存中將字符串壓縮并上傳,因而極大地提高了上傳效率。
以上所述僅為本發(fā)明的優(yōu)選實施例,并不用于限制本發(fā)明,對于本領(lǐng)域技術(shù)人員而言,本發(fā)明可以有各種改動和變化。凡在本發(fā)明的精神 和原理之內(nèi)所作的任何修改、等同替換、改進等,均應(yīng)包含在本發(fā)明的保護范圍之內(nèi)。