<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>

          萬億級數據應該怎么遷移?

          共 1673字,需瀏覽 4分鐘

           ·

          2020-11-19 11:04

          之前寫過一篇文章:binlog還能這么用之Canal篇,在里面介紹了一些增量數據遷移的一些方法,但是對于整體的數據的遷移介紹得不是很深,這里想對遷移數據整體做一個介紹,希望能幫助到大家。

          背景

          在星爺的《大話西游》中有一句非常出名的臺詞:“曾經有一份真摯的感情擺在我的面前我沒有珍惜,等我失去的時候才追悔莫及,人間最痛苦的事莫過于此,如果上天能給我一次再來一次的機會,我會對哪個女孩說三個字:我愛你,如果非要在這份愛上加一個期限,我希望是一萬年!”在我們開發(fā)人員的眼中,這個感情就和我們數據庫中的數據一樣,我們多希望他一萬年都不改變,但是往往事與愿違,隨著公司的不斷發(fā)展,業(yè)務的不斷變更,我們對數據的要求也在不斷的變化,大概有下面的幾種情況:

          • 分庫分表:業(yè)務發(fā)展越來越快,導致單機數據庫承受的壓力越來越大,數據量也越來越多,這個時候通常會使用分庫的方法去解決這個問題,將數據庫的流量均分到不同的機器上。從單機數據庫到分庫這個過程,我們就需要完整的遷移我們的數據,我們才能成功的分庫的方式上使用我們的數據。

          • 更換存儲介質:上面介紹的分庫,一般來說我們遷移完之后,存儲介質依然是同樣的,比如說之前使用的是單機Mysql,分庫之后就變成了多臺機器的Mysql,我們的數據庫表的字段都沒有發(fā)生變化,遷移來說相對比較簡單。有時候我們分庫分表并不能解決所有的問題,如果我們需要很多復雜的查詢,這個時候使用Mysql可能就不是一個靠譜的方案,那么我們就需要替換查詢的存儲介質,比如使用elasticsearch,這種的遷移就會稍微要復雜一些,涉及到不同存儲介質的數據轉換。

          • 切換新系統(tǒng):一般公司在高速發(fā)展中,一定會出現(xiàn)很多為了速度快然后重復建設的項目,當公司再一定時間段的時候,往往這部分項目會被合并,變成一個平臺或者中臺,比如我們一些會員系統(tǒng),電商系統(tǒng)等等。這個時候往往就會面臨一個問題,將老的系統(tǒng)中的數據需要遷移到新的系統(tǒng)中,這個時候就更加復雜了,有可能不僅是存儲介質有變動,有可能項目語言也不同,從更上層的角度來看,部門有可能也不同,所以這種數據遷移的難度是比較高,風險也更加的大。

          在實際業(yè)務開發(fā)中,我們會根據不同的情況來做出不同的遷移方案,接下來我們來討論一下到底應該怎么遷移數據。

          數據遷移

          數據遷移其實不是一蹴而就的,每一次數據遷移都需要一段漫長的時間,有可能是一周,有可能是幾個月,通常來說我們遷移數據的過程基本都和下圖差不多:

          首先我們需要將我們數據庫已經存在的數據進行批量的遷移,然后需要處理新增的這部分數據,需要實時的把這部分數據在寫完原本的數據庫之后然后寫到我們的新的存儲,在這一過程中我們需要不斷的進行數據校驗。當我們校驗基本問題不大的時候,然后進行切流操作,直到完全切流之后,我們就可以不用再進行數據校驗和增量數據遷移。

          存量數據遷移

          首先我們來說一下存量數據遷移應該怎么做,存量數據遷移在開源社區(qū)中搜索了一圈發(fā)現(xiàn)沒有太好用的工具,目前來說阿里云的DTS提供了存量數據遷移,DTS支持同構和異構不同數據源之間的遷移,基本支持業(yè)界常見的數據庫比如Mysql,Orcale,SQL Server等等。DTS比較適合我們之前說的前兩個場景,一個是分庫的場景,如果使用的是阿里云的DRDS那么就可以直接將數據通過DTS遷移到DRDS,另外一個是數據異構的場景,無論是Redis還是ES,DTS都支持直接進行遷移。

          那么DTS的存量遷移怎么做的呢?其實比較簡單大概就是下面幾個步驟:

          1. 當存量遷移任務啟動的時候,我們獲取當前需要遷移的最大的id和最小id

          2. 設置一個分段,比如1萬,從最小id開始每次查詢1萬的數據給DTS服務器,交給DTS處理。sql如下:

          select?*?from?table_name?where?id?>?curId?and?id?10000;

          3.當id大于maxId之后,存量數據遷移任務結束

          當然我們在實際的遷移過程中可能不會去使用阿里云,或者說在我們的第三個場景下,我們的數據庫字段之間需要做很多轉換,DTS不支持,那么我們就可以模仿DTS的做法,通過分段批量讀取數據的方式來遷移數據,這里需要注意的是我們批量遷移數據的時候需要控制分段的大小,以及頻率,防止影響我們線上的正常運行。

          增量數據遷移

          存量數據的遷移方案比較有限,但是增量的數據遷移方法就是百花齊放了,一般來說我們有下面的幾種方法:

          • DTS: 阿里云的DTS算是一條龍服務了,在提供存量數據遷移的同時也提供了增量數據遷移,只不過需要按量收費。

          • 服務雙寫:比較適合于系統(tǒng)沒有切換的遷移,也就是只換了存儲但是系統(tǒng)還是同一個,比如說分庫分表,redis數據同步等,這個的做法比較簡單直接在代碼里面同步的去寫入需要遷移的數據,但是由于不是同一個數據庫就不能保證事務,有可能導致遷移數據的時候會出現(xiàn)數據丟失,這個過程通過后續(xù)的數據校驗會進行解決。

          • MQ異步寫入:這個可以適用于所有的場景,當有數據修改的時候發(fā)送一個MQ消息,消費者收到這個消息之后再進行數據更新。這個和上面的雙寫有點類似,但是他把數據庫的操作變成了MQ異步了出問題的概率就會小很多

          • 監(jiān)聽binlog: 我們可以使用之前說過的canal或者其他的一些開源的如databus去進行binlog監(jiān)聽,監(jiān)聽binlog的方式 就和上面的消息MQ方式一樣,只是發(fā)送消息的這一步被我們省略了。這個方式的一個開發(fā)量來說基本是最小的。

          這么多種方式我們應該使用哪種呢?我個人來說是比較推薦監(jiān)聽binlog的做法的,監(jiān)聽binlog減少開發(fā)成本,我們只需要實現(xiàn)consumer邏輯即可,數據能保證一致性,因為是監(jiān)聽的binlog這里不需要擔心之前雙寫的時候不是一個事務的問題。

          數據校驗

          前面所說的所有方案,雖然有很多是成熟的云服務(dts)或者中間件(canal),但是他們都有可能出現(xiàn)一些數據丟失,出現(xiàn)數據丟失的情況整體來說還是比較少,但是非常難排查,有可能是dts或者canal不小心抖了一下,又或者是接收數據的時候不小心導致的丟失。既然我們沒有辦法避免我們的數據在遷移的過程中丟失,那么我們應該通過其他手段來進行校正。

          通常來說我們遷移數據的時候都會有數據校驗這一個步驟,但是在不同團隊可能會選取不同的數據校驗方案:

          • 之前在美團的時候,我們會做一個雙讀,也就是我們所有的讀取都會從新的里面讀取一份,但是返回的還是老的,這個時候我們需要做這部分數據的校驗,如果有問題可以發(fā)出報警人工修復或者自動修復。通過這種方式,我們常用的數據就能很快的進行一個修復,當然也會不定時的去跑一個全量的數據check,只是這種check出來修復數據的時間就比較滯后。

          • 現(xiàn)在在猿輔導之后,我們沒有采用之前的那種方式,因為雙讀check雖然能很快發(fā)現(xiàn)數據的不對,但是我們并沒有對這部分數據有那么高的一個實時性校驗并且雙讀的一個代碼開發(fā)量還是稍微比較大的,但是又不能依靠不定時全量check去保證,這樣就會導致我們的數據校驗時間會非常的延長。我們采取了一個折中的方法,我們借鑒了對賬里面的T+1的一個思路,我們每天凌晨獲取老數據庫中昨天更新的數據,然后和我們新數據庫中的數據做一一比對,如果有數據不一樣或者數據缺失,我們都可以立馬進行一個修復。

          當然在實際開發(fā)過程中我們也需要注意下面幾點:

          • 數據校驗任務的一個正確性如何保證,校驗任務本來就是去校正其他數據的,但是如果他自身出現(xiàn)了問題,就失去了校驗的意義,這里目前來說只能靠review代碼這種方式去保證校驗任務的正確性。

          • 校驗任務的時候需要注意日志的打印,有時候出現(xiàn)問題可能是直接所有數據出現(xiàn)問題,那么校驗任務就有可能會打出大量的錯誤日志,然后進行報警,有可能會將系統(tǒng)打掛,或者說影響其他人的服務。這里如果要簡單一點搞,可以將一些非人工處理的報警搞成warn,復雜一點搞得話,可以封裝一個工具,某個error打印再某個時間段超過一定量然后就不用再打印了。

          • 校驗任務注意不要影響線上運行的服務,通常校驗任務會寫很多批查詢的語句,會出現(xiàn)批量掃表的情況,如果代碼沒有寫好很容易導致數據庫掛掉。

          切流

          當我們數據校驗基本沒有報錯了之后,說明我們的遷移程序是比較穩(wěn)定的了,那么我們就可以直接使用我們新的數據了嗎?當然是不可以的,如果我們一把切換了,順利的話當然是很好的,如果出現(xiàn)問題了,那么就會影響所有的用戶。

          所以我們接下來就需要進行灰度,也就是切流。對于不同的業(yè)務切流的的維度會不一樣,對于用戶維度的切流,我們通常會以userId的取模的方式去進行切流,對于租戶或者商家維度的業(yè)務,就需要按照租戶id取模的方式去切流。這個切流需要制定好一個切流計劃,在什么時間段,放出多少的流量,并且切流的時候一定要選擇流量比較少的時候進行切流,每一次切流都需要對日志做詳細的觀察,出現(xiàn)問題盡早修復,流量的一個放出過程是一個由慢到快的過程,比如最開始是以1%的量去不斷疊加的,到后面的時候我們直接以10%,20%的量去快速放量。因為如果出現(xiàn)問題的話往往在小流量的時候就會發(fā)現(xiàn),如果小流量沒有問題那么后續(xù)就可以快速放量。

          注意主鍵ID

          在遷移數據的過程中特別要注意的是主鍵ID,在上面雙寫的方案中也提到過主鍵ID需要雙寫的時候手動的去指定,防止ID生成順序錯誤。

          如果我們是因為分庫分表而進行遷移,就需要考慮我們以后的主鍵Id就不能是自增id,需要使用分布式id,這里比較推薦的是美團開源的leaf,他支持兩種模式一種是雪花算法趨勢遞增,但是所有的id都是Long型,適合于一些支持Long為id的應用。還有一種是號段模式,這種會根據你設置的一個基礎id,從這個上面不斷的增加。并且基本都走的是內存生成,性能也是非常的快。

          當然我們還有種情況是我們需要遷移系統(tǒng),之前系統(tǒng)的主鍵id在新系統(tǒng)中已經有了,那么我們的id就需要做一些映射。如果我們在遷移系統(tǒng)的時候已經知道未來大概有哪些系統(tǒng)會遷移進來,我們就可以采用預留的方式,比如A系統(tǒng)現(xiàn)在的數據是1到1億,B系統(tǒng)的數據也是1到1億,我們現(xiàn)在需要將A,B兩個系統(tǒng)合并成新系統(tǒng),那么我們可以稍微預估一些Buffer,比如給A系統(tǒng)留1到1.5億,這樣A就不需要進行映射,B系統(tǒng)是1.5億到3億,那么我們轉換成老系統(tǒng)Id的時候就需要減去1.5億,最后我們新系統(tǒng)的新的Id就從3億開始遞增。
          但是如果系統(tǒng)中沒有做規(guī)劃的預留段怎么辦呢?可以通過下面兩種方式:

          • 需要新增一個表,將老系統(tǒng)的id和新系統(tǒng)的id做一個映射記錄,這個工作量還是比較大的,因為我們一般遷移都會涉及幾十上百張表,記錄的成本還是非常的高。

          • 如果id是Long型的話,我們可以好好利用long是64位這個因素,我們可以制定一個規(guī)則,我們新系統(tǒng)的id都是從一個比較大的數開始,比如從大于Int的數開始,將小Int的那部分數都可以留給我們的老系統(tǒng)做Id遷移,比如我們上面的1.5億的數據量,其實只用了28位,我們的Int是32位,那么還有4位可以使用,這個4位可以代表16個系統(tǒng)做遷移,當然如果規(guī)劃中有更多的系統(tǒng)做遷移,可以將新系統(tǒng)的id起始點設置得更大一點。如下圖所示:

          總結

          最后簡單來總結下這個套路,其實就是四個步驟,一個注意:存量,增量,校驗,切流,最后再注意一下id。不管是多大量級的數據,基本上按照這個套路來遷移就不會出現(xiàn)大的問題。希望能在大家的后續(xù)遷移數據工作中,這篇文章能幫助到你。

          后臺回復?學習資料?領取學習視頻


          如有收獲,點個在看,誠摯感謝


          瀏覽 26
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  看一级黄色视频 | 国产伦精品一区二区三区最新章节 | 91 京东视频 | 精品熟妇视频一区二区三区 | 国产成人精品免费视频麻豆大全 |