現在維護著乙個使用者標籤服務,大概的功能,是每日定時統計符合某些標籤的使用者群組,儲存到redis中,然後供前端展示廣告,推送活動等做判斷用
主要的操作就是判斷使用者是否屬於指定的群組id。
所以最簡單的辦法,就是把群組id做key,使用者id做value,存進redis的set集合裡,這樣做群組間的交集差集,也非常方便。
一切都執行很好。。直到最近訪問量突增,監控頁面看到redis的io有點高了,觀察info命令發現,redis的miss的佔比非常高,hit/miss 大約是1/8。這其實也好理解,畢竟滿足某些標籤的群組使用者數量和總使用者數相比確實算少的。這樣大量的請求其實就是查詢不到資料的,這時候就可以考慮布隆過濾器出場了。
簡單介紹下布隆過濾器:
簡單說就是乙個bool陣列,陣列每個值是0或1,插入資料時,選擇k個hash函式,計算k個位置,把陣列的這k個位置設為1,查詢是否插入過的時候,同樣求k個hash,判斷每一位是否為1。大家看完應該就想到了,這樣的判斷不是百分百準確的,查詢時,如果有一位不是1,那可以100%確定沒有插入過,但是如果全是1,也不能確定一定插入過,因為hash函式是可能有衝突的。要怎樣提高判斷準確率,這個和陣列大小,hash函式個數k都有關係。直接給出結果:
n是要插入的元素個數,p是期望的錯誤率
陣列長度 = -1 * n * math.log(p) / (ln2 * ln2)
hash函式個數 = ln2 * this.bloomlength / n
照我們前面說的標籤業務,正好是大部分使用者不在群組裡,所以布隆過濾器正合適。
接下來就是具體的實現,也很簡單了。
布隆過濾器什麼時候計算:定時任務生成群組的時候,順便把群組的布隆過濾器計算了,也存在redis裡。
從**讀:我們用布隆過濾器本來就是為了減少redis的訪問,所以我們不可能每次去redis查,因為布隆過濾器占用空間小的優點,我們可以把他快取在伺服器本地,這樣就能過濾掉大量redis查詢。
這樣我們就通過使用布隆過濾器,既花費較少的空間,又過濾了大量的請求
redis 使用 布隆過濾器
我們知道有 hyperloglog 可以用來做基數統計,但它沒提供判斷乙個值是否存在的查詢方法,那我們如何才能查詢乙個值是否存在於海量資料之中呢?如果使用傳統的方式,例如 sql 中的傳統查詢,因為資料量太多,查詢效率又低有占用系統的資源,因此我們需要乙個優秀的演算法和功能來實現這個需求,這是我們今...
Redis 中的布隆過濾器
布隆過濾器是乙個神奇的資料結構,可以用來判斷乙個元素是否在乙個集合中。很常用的乙個功能是用來去重。在爬蟲中常見的乙個需求 目標 url 千千萬,怎麼判斷某個 url 爬蟲是否寵幸過?簡單點可以爬蟲每採集過乙個 url,就把這個 url 存入資料庫中,每次乙個新的 url 過來就到資料庫查詢下是否訪問...
布隆過濾器的使用(實戰策略)
前言 布隆過濾器主要的使用用途就是用來判斷乙個元素是否在集合內存在的工具,現在企業業務處理的資料量越來越大,很多時候如果使用list等集合儲存的內容會顯得占用資源過於的龐大。使用方法 使用布隆過濾器網上有很多實現方法,自己寫起來也很麻煩,還好google提供了相應的包可以直接引用,使用起來十分的方便...