<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Mysql百萬(wàn)級(jí)數(shù)據(jù)遷移實(shí)戰(zhàn)筆記

          共 2596字,需瀏覽 6分鐘

           ·

          2021-07-12 13:46

          專注于PHP、MySQL、Linux和前端開(kāi)發(fā),感興趣的感謝點(diǎn)個(gè)關(guān)注喲?。?!文章主要包含的技術(shù)有PHP、Redis、MySQL、JavaScript、HTML&CSS、Linux、Java、Golang、Linux和工具資源等相關(guān)理論知識(shí)、面試題和實(shí)戰(zhàn)內(nèi)容。

          問(wèn)題背景

          上個(gè)月跟朋友一起做了個(gè)微信小程序,趁著5.20節(jié)日的熱度,兩個(gè)禮拜內(nèi)迅速積累了一百多萬(wàn)用戶,我們?cè)谛〕绦蝽?yè)面增加了收集formid的埋點(diǎn),用于給微信用戶發(fā)送模板消息通知。

          這個(gè)小程序一開(kāi)始的后端邏輯是用douchat框架寫(xiě)的,使用框架自帶的dc_mp_fans表存儲(chǔ)微信端授權(quán)登錄的用戶信息,使用dc_mp_tempmsg表存儲(chǔ)formid。截止到目前,收集到的數(shù)據(jù)超過(guò)380萬(wàn),很大一部分formid都已經(jīng)成功使用給用戶發(fā)送過(guò)模板通知,起到了較好的二次推廣的效果。

          隨著數(shù)據(jù)量的增大,之前使用的服務(wù)器空間開(kāi)始有點(diǎn)不夠用,最近新寫(xiě)了一個(gè)專門(mén)用于做小程序后臺(tái)開(kāi)發(fā)的框架,于是想把原來(lái)的數(shù)據(jù)遷移到新系統(tǒng)的數(shù)據(jù)庫(kù)。買(mǎi)了一臺(tái)4核8G的機(jī)器,開(kāi)始做數(shù)據(jù)遷移。下面對(duì)遷移過(guò)程做一個(gè)簡(jiǎn)單的記錄。

          Snipaste_2021-07-11_10-35-43

          方案選擇

          mysqldump遷移

          平常開(kāi)發(fā)中,我們比較經(jīng)常使用的數(shù)據(jù)備份遷移方式是用mysqldump工具導(dǎo)出一個(gè)sql文件,再在新數(shù)據(jù)庫(kù)中導(dǎo)入sql來(lái)完成數(shù)據(jù)遷移。試驗(yàn)發(fā)現(xiàn),通過(guò)mysqldump導(dǎo)出百萬(wàn)級(jí)量的數(shù)據(jù)庫(kù)成一個(gè)sql文件,大概耗時(shí)幾分鐘,導(dǎo)出的sql文件大小在1G左右,然后再把這個(gè)1G的sql文件通過(guò)scp命令復(fù)制到另一臺(tái)服務(wù)器,大概也需要耗時(shí)幾分鐘。在新服務(wù)器的數(shù)據(jù)庫(kù)中通過(guò)source命令來(lái)導(dǎo)入數(shù)據(jù),我跑了一晚上都沒(méi)有把數(shù)據(jù)導(dǎo)入進(jìn)來(lái),cpu跑滿。

          腳本遷移

          直接通過(guò)命令行操作數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)的導(dǎo)出和導(dǎo)入是比較便捷的方式,但是數(shù)據(jù)量較大的情況下往往會(huì)比較耗時(shí),對(duì)服務(wù)器性能要求也比較高。如果對(duì)數(shù)據(jù)遷移時(shí)間要求不是很高,可以嘗試寫(xiě)腳本來(lái)遷移數(shù)據(jù)。雖然沒(méi)有實(shí)際嘗試,但是我想過(guò)大概有兩種腳本方案。

          第一種方式,在遷移目標(biāo)服務(wù)器跑一個(gè)遷移腳本,遠(yuǎn)程連接源數(shù)據(jù)服務(wù)器的數(shù)據(jù)庫(kù),通過(guò)設(shè)置查詢條件,分塊讀取源數(shù)據(jù),并在讀取完之后寫(xiě)入目標(biāo)數(shù)據(jù)庫(kù)。這種遷移方式效率可能會(huì)比較低,數(shù)據(jù)導(dǎo)出和導(dǎo)入相當(dāng)于是一個(gè)同步的過(guò)程,需要等到讀取完了才能寫(xiě)入。如果查詢條件設(shè)計(jì)得合理,也可以通過(guò)多線程的方式啟動(dòng)多個(gè)遷移腳本,達(dá)到并行遷移的效果。

          第二種方式,可以結(jié)合redis搭建一個(gè)“生產(chǎn)+消費(fèi)”的遷移方案。源數(shù)據(jù)服務(wù)器可以作為數(shù)據(jù)生產(chǎn)者,在源數(shù)據(jù)服務(wù)器上跑一個(gè)多線程腳本,并行讀取數(shù)據(jù)庫(kù)里面的數(shù)據(jù),并把數(shù)據(jù)寫(xiě)入到redis隊(duì)列。目標(biāo)服務(wù)器作為一個(gè)消費(fèi)者,在目標(biāo)服務(wù)器上也跑一個(gè)多線程腳本,遠(yuǎn)程連接redis,并行讀取redis隊(duì)列里面的數(shù)據(jù),并把讀取到的數(shù)據(jù)寫(xiě)入到目標(biāo)數(shù)據(jù)庫(kù)。這種方式相對(duì)于第一種方式,是一種異步方案,數(shù)據(jù)導(dǎo)入和數(shù)據(jù)導(dǎo)出可以同時(shí)進(jìn)行,通過(guò)redis做數(shù)據(jù)的中轉(zhuǎn)站,效率會(huì)有較大的提升。

          可以使用go語(yǔ)言來(lái)寫(xiě)遷移腳本,利用其原生的并發(fā)特性,可以達(dá)到并行遷移數(shù)據(jù)的目的,提升遷移效率。

          文件遷移

          第一種遷移方案效率太低,第二種遷移方案編碼代價(jià)較高,通過(guò)對(duì)比和在網(wǎng)上找的資料分析,我最終選擇了通過(guò)mysql的select data into outfile file.txt、load data infile file.txt into table的命令,以導(dǎo)入導(dǎo)出文件的形式完成了百萬(wàn)級(jí)數(shù)據(jù)的遷移。

          遷移過(guò)程

          1. 在源數(shù)據(jù)庫(kù)中導(dǎo)出數(shù)據(jù)文件
          select * from dc_mp_fans into outfile '/data/fans.txt'
          1. 復(fù)制數(shù)據(jù)文件到目標(biāo)服務(wù)器
          zip fans.zip /data/fans.txt
          scp fans.zip root@ip:/data/
          1. 在目標(biāo)數(shù)據(jù)庫(kù)導(dǎo)入文件
          unzip /data/fans.zip
          load data infile '/data/fans.txt' into table wxa_fans(id,appid,openid,unionid,@dummy,created_at,@dummy,nickname,gender,avatar_url,@dummy,@dummy,@dummy,@dummy,language,country,province,city,@dummy,@dummy,@dummy,@dummy,@dummy,@dummy,@dummy,@dummy,@dummy);

          按照這么幾個(gè)步驟操作,幾分鐘內(nèi)就完成了一個(gè)百萬(wàn)級(jí)數(shù)據(jù)表的跨服務(wù)器遷移工作。

          注意項(xiàng)

          1. MySQL安全項(xiàng)設(shè)置

          在mysql執(zhí)行l(wèi)oad data infile和into outfile命令都需要在mysql開(kāi)啟了secure_file_priv選項(xiàng), 可以通過(guò)show global variables like '%secure%';查看mysql是否開(kāi)啟了此選項(xiàng),默認(rèn)值Null標(biāo)識(shí)不允許執(zhí)行導(dǎo)入導(dǎo)出命令。通過(guò)vim /etc/my.cnf修改mysql配置項(xiàng),將secure_file_priv的值設(shè)置為空:

          [mysqld]
          secure_file_priv=''

          則可通過(guò)命令導(dǎo)入導(dǎo)出數(shù)據(jù)文件。

          1. 導(dǎo)入導(dǎo)出的數(shù)據(jù)表字段不對(duì)應(yīng)

          上面示例的從源數(shù)據(jù)庫(kù)的dc_mp_fans表遷移數(shù)據(jù)到目標(biāo)數(shù)據(jù)庫(kù)的wxa_fans表,兩個(gè)數(shù)據(jù)表的字段分別為:dc_mp_fans

          wxa_fans

          在導(dǎo)入數(shù)據(jù)的時(shí)候,可以通過(guò)設(shè)置字段名來(lái)匹配目標(biāo)字段的數(shù)據(jù),可以通過(guò)@dummy丟棄掉不需要的目標(biāo)字段數(shù)據(jù)。

          總結(jié)

          結(jié)合本次數(shù)據(jù)遷移經(jīng)歷,總結(jié)起來(lái)就是:

          小數(shù)據(jù)量可以使用mysqldump命令進(jìn)行導(dǎo)入導(dǎo)出,這種方式簡(jiǎn)單便捷。數(shù)據(jù)量較大,且有足夠的遷移耐心時(shí),可以選擇自己寫(xiě)腳本,選擇合適的并行方案遷移數(shù)據(jù),這種方式編碼成本較高。數(shù)據(jù)量較大,且希望能在短時(shí)間內(nèi)完成數(shù)據(jù)遷移時(shí),可以通過(guò)mysql導(dǎo)入導(dǎo)出文件的方式來(lái)遷移,這種方式效率較高。

          在新系統(tǒng)展示數(shù)據(jù)的效果:



          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  狼友视频入口 | 日韩人妻无码专区 | 婷婷激情成人 | 拍真实国产伦偷精品 | 亚洲日韩三级 |