日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

如何使用布隆过滤器在Java中建立大容量的内存缓存

發布時間:2023/12/3 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何使用布隆过滤器在Java中建立大容量的内存缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

緩存是解決日常軟件問題的重要概念。 您的應用程序可能會執行CPU密集型操作,而您又不想一次又一次地執行這些操作,而是只導出一次結果并將其緩存在內存中。 有時瓶頸是IO,例如您不想重復訪問數據庫,并且想緩存結果并僅在基礎數據發生更改時才更新緩存。

同樣,在其他一些用例中,我們需要執行快速查找來決定如何處理傳入的請求。 例如,考慮這種用例,您必須識別一個URL是否指向惡意軟件站點。 要在一個實例中執行此操作,可能會有很多類似的URL,如果我們將所有惡意軟件URL緩存在內存中,則將需要大量空間來保存它們。 另一個用例可能是識別用戶鍵入的字符串是否對美國的某個地方有任何引用。 就像“華盛頓博物館”一樣,華盛頓就是美國一個地方的名字。 我們應該把美國的所有地方都留在記憶中然后查找嗎? 緩存大小有多大? 在沒有任何數據庫支持的情況下這樣做是否有效?

這是我們需要脫離基本地圖數據結構并在更高級的數據結構(例如Bloomfilter)中尋找答案的地方。 您可以考慮Bloomfilter,就像其他任何Java集合一樣,您可以在其中放置項目,并詢問它是否已存在某個項目(例如HashSet)。 如果Bloomfilter提到它不包含該項目,那么肯定不存在該項目。 但是,如果它提到看到了該項目,則可能是錯誤的。 如果我們足夠謹慎的話,我們可以設計一個bloomfilter以便控制錯誤的可能性。

說明

Bloomfilter設計為m位的數組(A)。 最初,所有這些位都設置為0。

要添加項目:

為了添加任何項目,需要通過k個散列函數進行饋送。 每個哈希函數都會生成一個數字,該數字可以視為位數組的位置(哈希模數數組的長度可以為我們提供數組的索引),我們應將該位置的值設置為1。例如–第一個哈希函數(hash1)在項I上生成位位置x,類似地,第二和第三哈希函數生成位置y和z。

因此,我們將設置:

A[x]=A[y]=A[z] = 1

查找項目:

將重復類似的過程,將通過三個不同的哈希函數將項目哈希三次。 每個哈希函數將產生一個整數,該整數將被視為數組的位置。 我們將檢查位數組的x,y,z位置,并查看它們是否設置為1。 如果不是,那么肯定沒有人嘗試將其添加到bloomfilter中,但是如果所有位都已設置,則可能是假陽性。

調整的東西

從上面的解釋中可以清楚地看出,要設計一個好的bloomfilter,我們需要跟蹤以下內容

  • 良好的哈希函數可以盡快生成廣泛的哈希值
  • m的值(位陣列的大小)非常重要。 如果大小太小,則所有位將很快設置為1,并且誤報會大大增加。
  • 散列函數(k)的數量也很重要,這樣值才能均勻分布。

如果我們可以估計計劃在Bloom Bloom過濾器中保留多少個項目,則可以計算k和m的最佳值。 跳過數學上的細節,計算k和m的公式足以讓我們編寫一個良好的Bloomfilter。

確定m(布隆過濾器的位數)的公式如下:

m = - nlogp / (log2)^2;

其中p =期望的假陽性概率

確定k(哈希函數數)的公式如下:

k = m/n log(2) ;

其中k =哈希函數的數量,m =位數,n =過濾器中的項目數

散列是一個影響bloomfilter性能的區域。 我們需要選擇一個有效但又不費時的哈希函數。 在“更少的哈希,相同的性能:構建更好的Bloom過濾器”一文中,討論了如何使用兩個哈希函數生成K個哈希函數。 首先,我們需要計算兩個哈希函數h1(x)和h2(x)。 接下來,我們可以使用這兩個哈希函數來模擬自然的k個哈希函數

gi(x) = h1(x) + ih2(x);

我可以在{1..k}范圍內

Google番石榴庫在其Bloomfilter實現中使用了該技巧,哈希邏輯在此處概述:

long hash64 = …; //calculate a 64 bit hash function//split it in two halves of 32 bit hash values int hash1 = (int) hash64; int hash2 = (int) (hash64 >>> 32);//Generate k different hash functions with a simple loopfor (int i = 1; i <= numHashFunctions; i++) {int nextHash = hash1 + i * hash2;}

應用領域

從數學公式可以明顯看出,要使用Bloomfilter解決問題,我們需要非常了解該域。 就像我們可以應用Bloomfilter來保留美國所有城市的名稱一樣。 此數字是確定性的,我們具有先驗知識,因此我們可以確定n(要添加到Bloomfilter的元素總數)。 根據業務需求固定p(假陽性概率)。 在那種情況下,我們有一個完美的緩存,可以提高內存效率,并且查??找時間非常短。

實作

Google番石榴庫具有Bloomfilter的實現。 檢查此類的構造函數如何查詢期望的項目和誤報率。

import com.google.common.hash.BloomFilter; import com.google.common.hash.Funnels;//Create Bloomfilter int expectedInsertions = ….; double fpp = 0.03; // desired false positive probability BloomFilter<CharSequence> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("UTF-8")), expectedInsertions,fpp)

資源:

  • http://en.wikipedia.org/wiki/Bloom_filter
  • http://billmill.org/bloomfilter-tutorial/
  • http://www.eecs.harvard.edu/~kirsch/pubs/bbbf/esa06.pdf

翻譯自: https://www.javacodegeeks.com/2014/07/how-to-use-bloom-filter-to-build-a-large-in-memory-cache-in-java.html

總結

以上是生活随笔為你收集整理的如何使用布隆过滤器在Java中建立大容量的内存缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。