首頁>技術>

在流量高峰期,會有大量的請求去查詢一個快取和資料庫中都沒有的資料,這時所有的請求就會到達資料庫裡去;當源源不斷地發起請求時,就會打垮資料庫。

這裡我們有一種解決方案就是使用布隆過濾器。下面是布隆過濾器的一個簡單介紹:

布隆過濾器(Bloom Filter)是1970年由布隆提出的。布隆過濾器是一種資料結構,利用極小的記憶體,可以判斷大量的資料。它告訴我們:“如果資料不存在,就肯定不存在”。

布隆過濾器原理

例如:

對“oracle”分別進行三次的hash函式計算,得到3個數值:1、4、5,於是就在對應的陣列的位置上標誌上1。

本文重在實踐,主要是解決布隆過濾器的程式碼實現。要詳細瞭解布隆過濾器的可以自行百度。

布隆過濾器的實現一般有兩種,一種是用谷歌公司提供的guava 工具包;一種是透過Redis底層的資料結構 bitmap 來實現布隆過濾器,客戶端工具Redisson已經封裝好對應的功能。

下面介紹這2種方式:

2、程式碼實現,具體的解釋看註釋好了
import com.google.common.hash.BloomFilter;import com.google.common.hash.Funnels;public class GuavaBloomFilter {    public static void main(String[] args) {        //後邊兩個引數:預計包含的資料量,和允許的誤差值        BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100000, 0.01);        for (int i = 0; i < 100000; i++) {            bloomFilter.put(i);        }        System.out.println(bloomFilter.mightContain(1));        System.out.println(bloomFilter.mightContain(2));        System.out.println(bloomFilter.mightContain(3));        System.out.println(bloomFilter.mightContain(100001));    }}
3、執行結果
truetruetruefalse

和實驗相符。

二、客戶端工具Redisson方式

Redisson實現的方式其實是用了redis來實現的。

1、redis安裝

關於redis的安裝

(1)可以用docker快速安裝單個例項

sudo docker run -p 36379:6379 --name redis5.0 -d redis:5.0 redis-server --appendonly yes

也可以用上次我說到的哨兵模式。

(2)在上篇中已向大家介紹了redis的哨兵方式及使用的方案。如需要看的可以跳轉到下面:

https://www.toutiao.com/i6913744392666841604/
2、程式碼實現:

在程式碼裡已經包括這2種方式,看原始碼即可。

(1)加入jar包
     <dependency>            <groupId>org.redisson</groupId>            <artifactId>redisson</artifactId>            <version>3.12.5</version>        </dependency>
(2)實現方式

A、如果需要用單redis例項方式:

config.useSingleServer().setAddress("redis://192.168.197.24:36379");

B、如果用哨兵模式:

//指定使用哨兵部署方式        config.useSentinelServers()                //設定sentinel.conf配置裡的sentinel別名                //比如sentinel.conf裡配置為sentinel monitor mymaster 192.168.197.24 6379 2,那麼這裡就配置mymaster                .setMasterName("mymaster")                //這裡設定sentinel節點的服務IP和埠,sentinel是採用Paxos拜占庭協議,一般sentinel至少3個節點                //記住這裡不是配置redis節點的服務埠和IP,sentinel會自己把請求轉發給後面monitor的redis節點                .addSentinelAddress("redis://192.168.197.24:26379")                .addSentinelAddress("redis://192.168.197.24:26380")                .addSentinelAddress("redis://192.168.197.24:26381");

可看全部的程式碼如下:

import org.redisson.Redisson;import org.redisson.api.RBloomFilter;import org.redisson.api.RedissonClient;import org.redisson.config.Config;public class RedissonBloomFilter {    public static void main(String[] args) {        Config config = new Config();        //單redis例項方式//        config.useSingleServer().setAddress("redis://192.168.197.24:36379");        //指定使用哨兵部署方式        config.useSentinelServers()                //設定sentinel.conf配置裡的sentinel別名                //比如sentinel.conf裡配置為sentinel monitor mymaster 192.168.197.24 6379 2,那麼這裡就配置mymaster                .setMasterName("mymaster")                //這裡設定sentinel節點的服務IP和埠,sentinel是採用Paxos拜占庭協議,一般sentinel至少3個節點                //記住這裡不是配置redis節點的服務埠和IP,sentinel會自己把請求轉發給後面monitor的redis節點                .addSentinelAddress("redis://192.168.197.24:26379")                .addSentinelAddress("redis://192.168.197.24:26380")                .addSentinelAddress("redis://192.168.197.24:26381");        RedissonClient redisson = Redisson.create(config);        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("user");        // 初始化布隆過濾器,預計統計元素數量為55000000,期望誤差率為0.03        bloomFilter.tryInit(55000000L, 0.03);        bloomFilter.add("yaokj");        bloomFilter.add("jamaly");        System.out.println(bloomFilter.count());   //2        System.out.println(bloomFilter.contains("yaokj"));  //true        System.out.println(bloomFilter.contains("xiaokua"));  //false        //最後關閉RedissonClient        redisson.shutdown();    }}
(3)執行結果三、原始碼

原始碼已開放,可以看連結:

https://gitee.com/yaokj/demo-toutiao

24
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • VBA中頂層物件的DisplayAlerts屬性,怎麼使用