資料出問題了!
一次偶發的端上問題。
排查日誌、監控、資料、程式碼邏輯。
服務沒有新增事務性保障,不可避免的資料不一致:快取有資料,資料庫沒資料或者相反;有A階段資料,沒有B階段資料;該有的資料沒有,不該有的資料卻存在。
主從機制遇到了強一致性需求,偶發的快取不一致。
服務被埋下了錯誤的邏輯,日積月累全量的錯誤資料。
... ...
不管是哪種情景,總之是資料變髒了。
怎麼辦?
一、處理當前問題的資料
對的,不是所有問題資料,是當前問題的資料,我們通常稱這種為緊急的問題,重不重要分情景另說。
使用者的問題訴求,總是需要第一時間響應的,這個關係大公司產品的使用體驗及公司形象,不容推延。
當然,在此之前,還是需要保留現場的,這些現場就是你排查的經過,每一步印證問題所提取的資訊。
經驗需要積累,教訓也要留存。
二、修復引發問題的誘因
已經排查了問題的所在,也已經處理了個例的問題。那麼接下來需要做的就是去修正服務的問題。
1、事務性保障問題
首先確定問題點是不是關鍵核心模組,是不是可以容忍。
類如,交易系統,訂單、庫存、賬戶餘額等關聯,是一點錯亂都無法忍受的,這就要從全方位進行資料一致性、正確性的保障。
服務邏輯層面的介面冪等性,業務操作的事務性,補償、重試保障可靠性;訊息中介軟體層面的或涉及訊息的持久化、映象容錯等;資料儲存層面的分散式快取、資料庫主從等,不一例舉。
類如,閱讀數,點贊數此等,很少人會去關注具體的多一個或者少一個(較真兒的除外),某大V寫了篇文章,瞬間閱讀數就查過了幾萬,轉發上千,大V不會去關心本該有30001的閱讀數只有30000。
此類資料,或者求個最終一致性,或者偶爾的遺失資料也可以忽略。也就不必要去新增額外的耗損效能的事務性保障。
2、主從與強一致性
主從與強一致性就像兩個同極的磁鐵,通常都是無法共存的。
以前遇到過有同事在提到“剛寫進去又查出來”總會發笑,那種認為可笑的發笑。
而往往此時,我沒有笑,只有疑惑和思考。疑惑是笑的同事,為什麼會笑;思考是,是不是隻有這樣才能達到目的,有沒有更好的替代方式。
通常現實中的業務都是大業務套著小業務,小業務套著更小的業務,環環相扣,一環連著一環。也如,一個人揹著一打木板過河,放下一個踩上去,然後再放下下一個,有二必先有一。
所以,固化前一個變更,然後進行下一個變更,這,很正常。
然而,隨著資訊時代的爆炸式發展,資訊服務的載重和載壓一年便是一個量級,這就不斷演化了現如今的許多多般複雜資訊服務。而在這其中,便是這“主從”應運而生,橫亙至今。
主從是一種分治的思想,讀場景和寫場景,量級不同,處理邏輯不同,保障性不同,所以涉及資料層面,就可以採用不同的提供方式。
快取或者資料庫,從主節點分離出一個或多個從節點專門用於資料的查詢,從節點實時同步主節點的資料變更,資料會有一定的延遲,但是基本符合現實的應用場景,我們追求的是不那麼強的最終一致性。
主節點則主要負責對資料變更的處理,以及,必要的資料查詢,對於需要強一致性的場景。
在實際的應用開發中,要特別注意篩選出對資料延遲零容忍的的業務邏輯,結合實際,應用主節點進行資料查詢或者其它手段來保障資料的強一致性需求。
3.避免不必要的低階邏輯錯誤
這裡,我們強調的是因為疏忽,非因個人能力而導致邏輯錯誤。
以前讀過卡耐基的人性的弱點,人是情感的生物,一生都在與自己的弱點作鬥爭。人類自大,容易煩躁,又缺乏耐心。而這,往往會導致一些不必要的的失誤。
屬性賦值錯了,未賦值;空值未判斷; 特殊狀態值未過濾等等,細枝末節往往影響深遠。
人不可能不犯錯誤,我們需要做的是怎麼去避免不必要的錯誤。
這裡需要提一下就是 Code Review 的重要性。一個人很難發現自己錯誤,這其中有主觀情感因素及客觀認知問題。旁觀者清,Code Review 的過程就是一個發現,糾正,優化改進的過程,每個人的關注點不同,或全域性的架構設計,或細節的變數命名,層層濾網過濾之後,將極大的減少出錯的可能。有一點需要指出的是,很多初次接觸 Code Review 的開發人員,往往會有牴觸情緒,或認為不必要,後羞於漏洞與眾人,團隊間在此方面需要建設共同的認知,意識,規約是非常有必要的。
三、處理髒資料
資料髒了怎麼辦?洗洗就好了!
髒資料好處理嗎?好處理。問題是髒資料在哪裡?
單個使用者問題的資料可以針對性的去處理。而那些隱藏的髒資料則需要去定位清洗。
1、限定影響範圍
哪些資料受影響了?從什麼時候開始?影響是什麼?
限定業務邏輯範圍,影響的資料面,比如,粉絲+好友+群組關聯的資料群,A關注了B,A多了一個好友,B多了一個粉絲,A把B放在了特定的群組裡。
限定時間範圍:從什麼時候開始上線了或者從什麼時候觸發了有問題的業務邏輯,比如,對 X 物件的變更修改調整起始於 1 號,那麼就需要查詢所有 1 號至今的所有與 X 物件修改相關的活動資料。
限定影響:確定對資料的影響是什麼,才能進一步決定下一步怎麼處理,比如漏掉了一個屬性賦值,那麼是否可以根據其它狀態屬性進行修正?改刪除的資料沒有刪除,是否直接刪除就能解決問題?
2、篩查資料
有了第一步的基礎,這一步需要做的就是找出問題資料。one by one,一個一個與校準值進行對比過濾。通常,我們會新增一個臨時的處理介面進行實時的校驗。
這裡,需要指出的是,不同量級的資料的處理篩查方式上會有所區別。
如果,你的資料量是萬級別的,那麼單個順序過濾就行了,不需要做什麼額外的處理;
如果,你的資料量是十萬級別的,那麼你可能需要在處理介面上新增批處理。
如果,你的資料量是百萬級別的,那麼除了介面批處理外,指令碼的多執行緒處理也會需要。
如果,你的資料量是千萬級別的,臨時擴充套件一些資料處理節點也會大大提高處理效率。
3、處理髒資料
髒資料總歸不是大量級的,處理之前,必要的校驗,驗證不可或缺。
選取測試資料或者從髒資料中選擇少許進行處理結果驗證。充分認證後,再進行全量處理。