<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>

您的位置:首頁 >聚焦 >

27.上的了天但落不了地的BloomFilter 全球新視野

2023-03-04 12:44:31    來源:程序員客棧
?1 BloomFilter是個好東西

它思路清奇,輾轉騰挪,號稱可解決Redis緩存三大困境之首的穿透問題,是后端面試必備的佳品,但你見過有文章介紹過BloomFilter怎么落地么?似乎沒有~


(資料圖)

Redis緩存三大困境:穿透、擊穿、雪崩。null object可以解決正常的穿透問題,然而面對黑客人惡意制作的穿透則無能為力,但BloomFilter可以。以用戶注冊登錄為例,BloomFilter通過預先收集所有有效uid,并創建一個多hash的bitmap向量,可以有效攔截惡意uid登錄的情況。

好了,從這里開始,幾乎所有文章都會轉向介紹BloomFilter如何優秀,或者其實現原理如何如何。但卻故意跳過了一個很關鍵的問題:BloomFilter如何更新?

仍然以用戶注冊登錄為例。我們預先創建一個包含所有uid的bitmap向量沒有問題,但是當有新用戶注冊后,如何把新注冊用戶的uid加入到BloomFilter中呢?

2 看似可行的方案1 Dual Write

中文翻譯為交叉寫或雙寫,即在新注冊用戶成功后,立馬把新注冊用戶的uid加入到BloomFilter中。

這個方案的優點是實時性很好。但問題是:萬一新注冊用戶成功了,但寫Redis失敗了怎么辦?比如有新用戶的注冊的時候,剛剛在MySQL注冊成功,但還未來得及寫入到Redis時,由于網絡閃斷,寫Redis超時了。此時MySQL就比Redis中多一個新注冊的用戶uid,該用戶在登錄系統就無法通過BloomFilter驗證了。

只所以把Dual Write翻譯為『交叉寫』,是暗含著在并發情形下,寫入MySQL的順序與寫入Redis的順序可能并不相同。這在很多情況下是無法接受的,比如用戶轉賬類業務,也因此導致Dual Write不是一個常規方案。但在BloomFilter應用場景中,恰好對不同用戶uid的寫入順序不敏感。

2 Change Data Capture

數據變更捕獲,簡稱CDC。在我們的前述應用場景中,簡化的思路是新啟動一個服務進程,把自己模擬成MySQL的從庫,通過解析binlog,拿到新注冊用戶的uid,然后再將這個uid寫入到BloomFilter中。

正式的CDC過程,通常會先把解析出來的binlog寫入到kafka之類的消息隊列中,通過消息隊列相關的可靠性方案保證新用戶的uid一定會寫入到BloomFilter中,因此不會有丟消息的情形。

這個方案的優點是可靠性很好。但問題是:kafka消息消費可能有延遲。假如我們新注冊了一個用戶,但1分鐘之后才消費到該用戶的注冊消息,那么這1分鐘之內該新用戶登錄系統也是通不過BloomFilter驗證的。

3 落地方案

講了半天,應該如何既要XX又要XX呢?

說穿了一文不值:既然我們既想要Dual Write的實時性,又要CDC的可靠性,那么我們只要同時使用這兩個方案就好了~

4 別打我

但你可以來公眾號挑釁我,有本事你。。。。過來呀~

5 References

16.從核酸檢測到BloomFilter

關鍵詞: 的可靠性 用戶注冊 同時使用

相關閱讀

巨胸护士在线播放视频二区

<i id="bcuty"><sub id="bcuty"></sub></i>

<b id="bcuty"></b>