聽五年大數據經驗大佬給你講:Redis穿透的解決方法—布隆過濾器

Redis概述:

Redis是一個開源的Key-Value存儲系統,其中Value支持String、list、set、hash、zset五種數據結構,這些數據都支持push/pop、add/remove、取交集並集、排序等豐富的操作,並且這些操作都是原子性的。

與同為NoSQL型緩存數據庫的memcached類似,Redis的數據都存在內存中,數據的運算都在內存中進行,不會發生IO,這也是Redis為什麼這麼快的一個原因;區別是Redis具備持久化方式,會週期性的把更新的數據寫入磁盤(RDB)或者把修改操作追加寫入記錄文件中(AOF)。

也就是說,Redis的數據存放在內存中,但Redis也支持持久化將數據存入磁盤或文件。

Redis是單線程的,但是多任務併發時可以開啟多個Redis,並且Redis支持主從同步,避免了宕機帶來的影響,以及寫時同步技術實現了數據讀寫分離(主機負責寫入、從機負責讀取)。

ps:Redis的特點是單線程+多路IO複用


Redis緩存的使用,極大的提升了應用程序的性能和效率,特別是數據查詢方面。但同時,它也帶來了一些問題。其中,最要害的問題,就是數據的一致性問題,從嚴格意義上講,這個問題無解。如果對數據的一致性要求很高,那麼就不能使用緩存。

另外的一些典型問題就是,緩存穿透、緩存雪崩和緩存擊穿。目前,業界也都有比較流行的解決方案。本篇文章,來給大家講解一下Redis穿透的解決方法—布隆過濾器

緩存穿透

緩存穿透,是指查詢一個數據庫一定不存在的數據。正常的使用緩存流程大致是,數據查詢先進行緩存查詢,如果key不存在或者key已經過期,再對數據庫進行查詢,並把查詢到的對象,放進緩存。如果數據庫查詢對象為空,則不放進緩存。

聽五年大數據經驗大佬給你講:Redis穿透的解決方法—布隆過濾器

代碼流程

  1. 參數傳入對象主鍵ID
  2. 根據key從緩存中獲取對象
  3. 如果對象不為空,直接返回
  4. 如果對象為空,進行數據庫查詢
  5. 如果從數據庫查詢出的對象不為空,則放入緩存(設定過期時間)

想象一下這個情況,如果傳入的參數為-1,會是怎麼樣?這個-1,就是一定不存在的對象。就會每次都去查詢數據庫,而每次查詢都是空,每次又都不會進行緩存。假如有惡意攻擊,就可以利用這個漏洞,對數據庫造成壓力,甚至壓垮數據庫。即便是採用UUID,也是很容易找到一個不存在的KEY,進行攻擊。

布隆過濾器(Bloom Filter)

它實際上是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率和刪除困難。

聽五年大數據經驗大佬給你講:Redis穿透的解決方法—布隆過濾器

布隆過濾器解決方法:

將數據庫中所有的查詢條件,放入布隆過濾器中,

當一個查詢請求過來時,先經過布隆過濾器進行查,如果判斷請求查詢值存在,則繼續查;如果判斷請求查詢不存在,直接丟棄。

布隆過濾器原理

原理就是一個對一個key進行k個hash算法獲取k個值,在比特數組中將這k個值散列後設定為1,然後查的時候如果特定的這幾個位置都為1,那麼布隆過濾器判斷該key存在。

布隆過濾器可能會誤判,如果它說不存在那肯定不存在,如果它說存在,那數據有可能實際不存在;

Redis的bitmap只支持2^32大小,對應到內存也就是512MB,誤判率萬分之一,可以放下2億左右的數據,性能高,空間佔用率及小,省去了大量無效的數據庫連接。

因此我們可以通過布隆過濾器,將Redis緩存穿透控制在一個可容範圍內。

五年大數據工作經驗大佬講解Redis穿透解決方法:

聽五年大數據經驗大佬給你講:Redis穿透的解決方法—布隆過濾器

獲取方式:


分享到:


相關文章: