binlog真的是銀彈嗎?有些時候也讓人頭疼

架構擺渡人發表於2021-12-07

大家好,我是架構擺渡人。這是實踐經驗系列的第三篇文章,這個系列會給大家分享很多在實際工作中有用的經驗,如果有收穫,還請分享給更多的朋友。

binlog 用於記錄使用者對資料庫操作的SQL語句資訊,同時主從複製也是依靠binlog來實現的,由此可見binlog的重要性。

在業務中的使用場景

binlog除了資料庫本身使用它實現一些功能,在業務中我們也會經常依靠binlog實現各種需求。

資料異構

基於binlog的資料異構是用的最多的一個場景,可以通過監聽binlog將資料異構成其他維度,方便查詢。

比如多表聚合成一張寬表,搜尋相關的異構到ES中,訂單可以異構成買家視角,賣家視角等等諸多場景。

快取失效

對於高併發的網際網路業務,資料庫往往是最後的瓶頸,用快取來提高效能是最常見的一種優化手段。也就是在訪問資料庫之後會將資料放入一份在快取中,下次請求的時候直接從快取取來提高響應速度和減少對資料庫的壓力。

一提到快取,大家立馬能想到的問題就是快取和資料的一致性要怎麼保障?這種還是得結合業務場景來講,本身能用快取的業務基本上還是能夠接受短暫的不一致問題,也就是並非強一致性。

最常見的方式就是在運算元據後,立馬對快取進行操作。這樣的方式意味著業務程式碼中都是這種快取失效的程式碼,當然也有封裝成註解的形式,讓使用更加便捷。

binlog在這個場景中也能產生重大作用,可以基於binlog的變更來淘汰對應的快取,而且可以和業務程式碼解耦,為我們解決快取資料一致性問題多提供了一種方案。

資料分發

資料分發也是一種比較常見的業務場景,當很多下游依賴上有的資料,常見的實現方式有下面幾種:

  • 程式碼中通過訊息進行資料分發
    如果自己在程式碼中通過訊息將資料分發出去,就會比較被動。因為一旦有欄位變更,有下游想要其他的資料,你都得需要改動程式碼來滿足下游的需求,基本上不可取。

  • 多搭建幾個從節點,給下游直接使用從節點
    這種方式如果是在一個部門內還好點,如果是跨部門的,本來許可權就管的比較嚴,不可能讓其他部門直接連線你們的資料庫,而且增加從節點的成本也是你們自己的,所以這種方式基本上也不會用。

  • 讓下游消費binlog自己構建資料
    下游需要使用資料,那麼就用下游自己的資料庫,用什麼庫都跟你沒關係。我們只需要通過中介軟體將binlog釋出出去,哪個業務方需要資料就自己消費,自己儲存即可。

這種方式我們既不用改業務程式碼,也不用申請資料庫增加我們的成本,是一種完全解耦的方式,但是這種方式也是有弊端的,請繼續往下看。

給業務帶來的風險點

欄位變更

如果上游的欄位發生了變更,比如把name換成了username,對消費binlog的下游來說,這個欄位就有可能影響了現有的邏輯,導致取值錯誤。不過在實際工作中這種場景還是比較少的,一般都不會去隨意變更欄位名稱,也不能說完全沒有變更的情況。

資料變更

欄位變更帶來的影響相對來說較小,最讓人頭痛的就是資料的變更了。特別是資料量特別大的表進行資料變更的時候,比如你的表有10億條資料,當然是分庫分表的。然後有個欄位需要重新清洗下資料,也就是update某個欄位。看上去對業務沒有任何影響,其實對下游是有影響的。

如果資料清洗過快,binlog就會很多,下游消費不過來就會出現訊息堆積,影響正常的業務邏輯,因為下游都依賴了binlog做業務。

所以在這種場景下,大家有資料清洗的需求,一定要考慮到對下游的影響,本來你洗資料可能一天就洗完了,但是下游扛不住,可能需要10天才能慢慢洗完。但是感覺不合理啊,我自己的表變更還要問問別人,我能洗這麼快麼?

解決方案

對於欄位名稱儘量不做變更,非得變更的話得提前和下游溝通好,讓下游消費2個欄位,如果哪個有就消費哪個,這樣你改名稱之後就不會影響下游的邏輯。

對於資料清洗之類的導致大量binlog場景,最簡單的就是控制清洗速度,始終保持下游能夠接受的程式去清洗,缺點就是時間會比較長。

另一種方案就是按需訂閱,比如有的場景你清洗的這個欄位下游壓根就不消費,這個時候可以在訊息投遞處進行處理,按需進行訊息的投遞,比如對訊息打Tag, 下游根據Tag進行訊息過濾。

或者下游消費時直接過濾,這樣速度也是很快的。

如果你的改動下游真的要感知,並且速度還不能慢,要趕時間,那麼只能讓下游擴容了。

大家好,我是從古代穿越過來的美男子:架構擺渡人。我將把我的武功祕籍全部傳授與你們,覺得有用請分享給身邊的朋友。來個三連吧,感謝各位!

相關文章