大家好,我是架構擺渡人。這是實踐經驗系列的第三篇文章,這個系列會給大家分享很多在實際工作中有用的經驗,如果有收獲,還請分享給更多的朋友。
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進行消息過濾。
或者下游消費時直接過濾,這樣速度也是很快的。
如果你的改動下游真的要感知,並且速度還不能慢,要趕時間,那么只能讓下游擴容了。
大家好,我是從古代穿越過來的美男子:架構擺渡人。我將把我的武功秘籍全部傳授與你們,覺得有用請分享給身邊的朋友。來個三連吧,感謝各位!