前言:剛來新公司2個月就面臨了一次線上真實數據的轉換,這些數據異常重要,對我們公司來說就是客戶的資源,說白了就是客戶存在我們公司的錢,一旦處理失敗將會影響極大,可以想象一下你存銀行2萬元,第二天查詢卻一分錢沒有的情況,但是很遺憾此次處理沒有處理好,造成了極大的影響,對我個人而言也是,后續我對此次數據轉換失敗進行了深刻反思,發現處理失敗原因主要2個方面,1是流程不對,2是基礎知識准備不足,現在我將把當時處理的過程以及后續如何處理整理出來,供大家參考,希望大家少入坑。
1、當時處理數據的過程
我們當時采用的是分批處理,第一次灰度處理200個用戶,第2次灰度處理4萬個用戶,第三次是全量處理,那么現在我將記錄當時處理經過,因為我是底層服務的負責人,所以這個需求是別的業務方提出來,然后進行需要和技術進行評審,完畢后由我給出技術方案。
1.1、200個灰度用戶處理
當時由於是200個用戶,那么我采取的處理就是以用戶這個維度進行處理,然后從文件中讀取業務方給的用戶id,然后通過一些業務邏輯處理生成一批可執行的shell腳本。與此同時依然以用戶的維度寫了一個回滾方案,如果執行一斷失敗即可回滾。寫完這些技術方案我們進行了一次技術評審,評審發現我處理的數據有一些過期或者失效的用戶資源,然后我們討論這些資源是否要處理,最后得出結果是不處理,然后我對生成的shell腳本進行修復,只取用戶可用資源。后續我們也進行幾次評審,確定了最終的shell腳本,到上線那天進行執行。處理完畢以后由我先進行測試,然后由qa進行測試,最后由pm進行驗收,整個過程很順利,沒有出現異常情況,完美驗收。
1.2、40000個用戶處理
由於上次處理的比較順利,讓我們放松了警惕,認為這種方案沒什么問題,只不過把上次的200個用戶替換成40000個用戶,在上線的那天進行執行,當時處理也是沒有任何問題,pm也驗收通過,但是過了2天陸續有銷售反應客戶資源比原始資源大了很多,最后查詢發現原來pm給我的用戶數據存在不少是重復的,我並沒有進行重復過濾,導致在刷數據的時候重復刷,這樣一來客戶資源在原來基礎上擴大很多,這個不管pm如何給的數據,但是我作為資源負責人應該考慮這些問題,這是出現的第一例case,后續我們對代碼進行修復。
1.3、全量數據處理
全量處理方案,從數據庫中獲取所有的用戶id,這里我采用了一個笨方法,采用java程序獲取的,用戶總量有好幾百萬,資源總量大約是5千萬,然后我把用戶id分別進行存儲不同的文件中,然后采用多線程來執行從而提高效率,這個處理時長達8個小時(這里已經很明顯不對了)因為中間有些邏輯必須調用服務所以處理時間比較長,但是最終還是得到了可執行的sql腳本,到了夜晚6點左右開始執行,先是有dba進行數據備份,然后由我把准備好的sql腳本交給dba進行執行(因為數據量大,只有dba通過特殊權限才可以快速執行),這些數據全部執行完畢大約用了40分鍾,然后我們進行數據驗證,上游各種服務上線,那天我自己也有job上線,導致從夜晚6點一直處理到第二天凌晨6點,然后pm驗證后回家休息。但是噩夢在當天9點出現,有數萬用戶資源加多或加少或無法進行下載,然后開始修復數據(中間修復過程不在說了),整整修復3天,每天休息時間不超過4小時,終於得以遏止,很長一段時間我就在思考和反思問題出在哪里,以后應該去怎么應對這樣龐大數據的遷移或者轉換,到最后我發現主要死是流程的錯誤,導致一錯再錯,下面我寫下我的總結
2、總結
對於大量數據的轉換或者遷移我們應該遵從下面幾個流程,這樣會最大化的減小數據出錯的幾率
2.1、詳細的上線方案
其實我們也有上線方案(對於任何修改線上的操作我們應該都稱為上線),但是不夠明確或者有太多的點沒有指出來,上線方案應該包括下面幾點
2.1.1、上線前的准備
1是上線前夕需要禁止用戶對數據的操作、查詢等避免操作期間因為用戶的操作導致大量臟數據進入庫中后續處理非常麻煩,2是在文檔中明確每個業務方的負責人是誰在什么時間節點進行關閉用戶操作資源界面,在我們操作期間沒有明確這些事情,導致我們轉換了數據,但是沒有關閉數據操作入口導致還有不少是按照以前邏輯的方式把數據添加到庫中。
2.1.2、技術方案
涉及數據遷移或者轉換我們最重要的2步一個是獲取數據另一個就是處理數據然后生成可執行的shell腳本
數據源的獲取
1、數據源的獲取一定是要通過sql腳本來獲取,禁止用應用程序跑
2、數據源可分庫獲取,把每個庫的數據放在一個文件,文件取名采用庫名_數據條數(如果量很大可以繼續分割)庫名_n_數據條數
3、避免有重復數據,通過shell來對數據進行排重
處理數據源生成可執行的shell腳本
1、確認數據處理的維度,必須要以id為主鍵進行轉換,切不可用用戶id或者其他類型,盡量保證操作的冪等性,不管執行多少次結果不會改變
2、按照數據源文件批量處理數據,在程序執行期間必須要打印日志,而且把處理異常的數據寫入到一個error文件中,執行完畢后查詢生成的數值是否和數據源要處理的數值一致,如果有異常去查看異常是否自己有考慮不全的地方,如果發現數值不一致也立即去排查原因,確保整個數據處理沒有任何問題
3、記錄每個文件的處理時間,比如庫1數據處理時間是1個小時,那么你單台機器只能處理2個應用程序,那么在上線的那天你都需要准備8台機器,這樣還可以估算整個上線的時間
4、程序盡量在服務器執行,因為你數據獲取到處理數據到最后執行肯定是在上游的入口關閉以后,如果本地執行時間可能會太久,服務器執行就可以多申請幾台服務器,把程序做成定時任務,然后同時跑,可能本機需要5個小時服務器20分鍾足矣
2.1.3、執行&測試
1、如果整體數據量比較大還是建議交付給公司dba處理,他們權限比較大,處理效率會高不少
2、執行前選取一條單獨執行,然后驗證看是否正確,避免出現sql錯誤的低級錯誤
3、單庫執行,然后進行測試,因為數據量巨大,一個個比對肯定不現實,可采用的方式查看備份庫數據的數然后在查看按規則轉換后的數據數量,如果一致的話在隨機抽取數據進行驗證,如果發現2中庫的數量差別大,就需要檢查是否出現漏掉數據沒有處理
4、全部執行,測試方式和上面一樣,進行間接的測試來驗證數據的正確性
2.1.4、驗收
1、由pa進行覆蓋性的點擊每項功能查詢是否出現異常
2、由pm隨機進行點擊
2.1.5、回滾
如果數據一斷出現自己無法把控的情況,可以先把情況告訴領導和各方負責人,經評審后聯系dba對數據進行整體回滾,如果數據量比較小,可以在操作的時候記錄數據主鍵,按照主鍵進行還原即可。
2.1.6、上線時間節點和地點
1、上線的地點可以提前預約一個會議室,數據轉換進行投影,減少誤操作
2、上線節點,在每個節點要做什么都明確出來,做到井井有條
因為我們目前處理項目重構和拆分階段,有不少關於數據遷移轉換的情況,后來我們也有大約3萬多條數據遷移,完全按照上面的方式操作很順利,至今沒有反饋一個case。好了到這里就總結完畢了,數據處理需慎重,一定要考慮各種極端情況。