最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java SpringBoot使用guava過濾器

 更新時間:2022年09月02日 16:14:25   作者:李顯赤赤  
這篇文章主要介紹了Java SpringBoot使用guava過濾器,文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下

介紹

布隆過濾器(BloomFilter)是一種數(shù)據(jù)結(jié)構(gòu),特點(diǎn)是高效地插入和查詢,可以用來告訴你某個key一定不存在或者可能存在,它是用多個哈希函數(shù),將一個key映射到多個數(shù)組下標(biāo)中。

特點(diǎn)

布隆過濾器可以告訴我們 "某樣?xùn)|西一定不存在或者可能存在",也就是說布隆過濾器說這個key不存在則一定不存在,布隆過濾器說這個key存在則可能不存在(會存在誤判),利用這個判斷是否存在的特點(diǎn)可以做很多有趣的事情。

數(shù)據(jù)結(jié)構(gòu)

 由一串很長的二進(jìn)制數(shù)組向量組成,可以將其看成一個二進(jìn)制數(shù)組。既然是二進(jìn)制,那么里面存放的不是0,就是1,但是初始默認(rèn)值都是0。

新增數(shù)據(jù)

把一個key經(jīng)過多個hash函數(shù)計(jì)算出多個數(shù)組下標(biāo),把計(jì)算出的下標(biāo)的位置的0變成1。

查詢數(shù)據(jù)

當(dāng)要查詢一個key是否在布隆過濾器中,用相同的方法計(jì)算出多個1,判斷根據(jù)這個key計(jì)算出的多個1的位置在布隆過濾器中是否都是1,如果都是那么代表可能存在,如果不都是代表一定不存在。

刪除數(shù)據(jù)

布隆過濾器很難進(jìn)行刪除操作。

作用

 高效判斷一個數(shù)據(jù)在不在某一組數(shù)據(jù)中。

誤差率: 創(chuàng)建布隆過濾器時,可以設(shè)置誤差率,誤差率越小,hash函數(shù)越多,二進(jìn)制數(shù)據(jù)占用空間越大。hash函數(shù)越多,計(jì)算出的hash值多,對應(yīng)計(jì)算出的二進(jìn)制數(shù)組下標(biāo)越多,效率越低,有一個位置在布隆過濾器中置不為1,就代表不存在,精確度越高。

業(yè)務(wù)使用

布隆過濾器就是在Redis緩存前面在加一層過濾,負(fù)責(zé)過濾無效的請求,如果請求沒有通過布隆過濾器就不會到緩存和數(shù)據(jù)庫。

布隆過濾器的優(yōu)點(diǎn) :

  • 空間效率 和 查詢效率都遠(yuǎn)遠(yuǎn)超過一般的算法。
  • 增加和查詢元素的時間復(fù)雜為O(N)(N為哈希函數(shù)的個數(shù),通常情況比較?。?/li>
  • 占用空間小,如果允許存在一定的誤判,布隆過濾器是非常節(jié)省空間。
  • 保密性強(qiáng),布隆過濾器不存儲數(shù)據(jù)本身。

布隆過濾器的缺點(diǎn): 有點(diǎn)一定的誤判率,但是可以通過調(diào)整參數(shù)來降低。

  • 無法獲取元素本身。
  • 很難刪除元素。

快速開始

導(dǎo)入依賴:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.0-jre</version>
</dependency>

配置類:

把布隆過濾器對象注入進(jìn)IOC容器。

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.nio.charset.Charset;
@Configuration
public class BloomFilterConfig {
    /**
     * expectedInsertions:期望添加的數(shù)據(jù)個數(shù)
     * fpp:期望的誤判率,期望的誤判率越低,布隆過濾器計(jì)算時間越長
     * @return
     */
    @Bean
    public BloomFilter<String> goodsIDBloom(){
        BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 1000,0.00001);
        return filter;
    }
    @Bean
    public BloomFilter<String> orderBloom(){
        BloomFilter<String> filter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")), 1000,0.00001);
        return filter;
    }
}

啟動項(xiàng)目時把所有key插入布隆過濾器:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.hash.BloomFilter;
import com.liu.seckill.entity.SeckillGood;
import com.liu.seckill.service.SeckillGoodService;
import com.liu.seckill.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
 
@Slf4j
@Configuration
public class InitConfig implements InitializingBean {
    @Autowired
    UserService userService;
    @Autowired
    SeckillGoodService seckillGoodService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RedisConfig redisConfig;
    @Autowired
    @Qualifier("goodsIDBloom")
    BloomFilter<String> goodsIDBloom;
    /**
     * 把商品庫存加載到 Redis中
     * 每天更新
     * @throws Exception
     */
    @Override
    @Scheduled(fixedRate = 1000*60*60*24)
    public void afterPropertiesSet() throws Exception {
        //只緩存秒殺還沒結(jié)束或秒殺還沒開始的商品
        List<SeckillGood> seckillGoods = seckillGoodService.list(new QueryWrapper<SeckillGood>().ge("end_time", LocalDateTime.now()));
        if (seckillGoods == null) {
            log.info("暫無秒殺商品");
            return;
        }
        //將秒殺商品ID和庫存分別存入redis中
        List<Long> seckillGoodIDList = new ArrayList<>();
        for (SeckillGood seckillGood : seckillGoods) {
            seckillGoodIDList.add(seckillGood.getSgId());
            //設(shè)置過期時間
            long millis = Duration.between(LocalDateTime.now(), seckillGood.getEndTime()).toMillis();
            redisTemplate.opsForValue().set("seckillGoodID:" + seckillGood.getSgId(), seckillGood.getSgStock(), millis, TimeUnit.MILLISECONDS);
            //存儲值到布隆過濾器中
            goodsIDBloom.put(seckillGood.getSgId()+"");
        }
        redisTemplate.opsForValue().set("seckillGoodIDList:", seckillGoodIDList,1,TimeUnit.DAYS);
 
    }
}

使用布隆過濾器:

查詢redis之前先走布隆過濾器,如果布隆過濾器判斷沒有則一定沒有。

@RestController
@RequestMapping("/seckillOrder")
public class SeckillOrderController  {
 	//如果有多個布隆過濾器,就同時使用@Qualifier和@Autowired
    @Autowired
    @Qualifier("goodsIDBloom")
    BloomFilter<String> goodsIDBloom;
    @Autowired
    @Qualifier("orderBloom")
    BloomFilter<String> orderBloom;
 
    @GetMapping("/seckillGoods/{goodId}")
    public Result seckillGoods(@PathVariable("goodId") Long goodId) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
 
        //判斷秒殺商品是否存在
        //如果商品id在布隆過濾器中存在,那么就要再去判斷在不在redis中,在,才能證明真的在
        if (goodsIDBloom.mightContain(goodId+"")){
            ArrayList<Long> seckillGoodIDList = (ArrayList<Long>) valueOperations.get("seckillGoodIDList:");
            Assert.isTrue(seckillGoodIDList.contains(goodId),"未找到該商品,商品ID有誤或此商品不參與秒殺或此商品秒殺已結(jié)束");
        }else {
            Assert.isTrue(false,"未找到該商品,商品ID有誤或此商品不參與秒殺或此商品秒殺已結(jié)束");
        }
    }
}

到此這篇關(guān)于Java SpringBoot使用guava的布隆過濾器的文章就介紹到這了,更多相關(guān)SpringBoot使用guava 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException?異常是在使用?Jedis?客戶端與?Redis?集群進(jìn)行交互時發(fā)生的,下面就來介紹一下解決方法,感興趣的可以了解一下
    2024-05-05
  • java String、StringBuilder和StringBuffer的區(qū)別詳解

    java String、StringBuilder和StringBuffer的區(qū)別詳解

    這篇文章主要介紹了java String、StringBuilder和StringBuffer的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • java如何動態(tài)執(zhí)行while循環(huán)

    java如何動態(tài)執(zhí)行while循環(huán)

    這篇文章主要介紹了java如何動態(tài)執(zhí)行while循環(huán)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 利用Java自寫一個生成ID的工具類

    利用Java自寫一個生成ID的工具類

    平時項(xiàng)目中只要涉及表,那么一定能接觸到眾多各式各樣的ID編號。本文將通過Java語言實(shí)現(xiàn)手寫一個ID生成工具類,需要的小伙伴可以參考一下
    2022-11-11
  • 關(guān)于Spring?Boot項(xiàng)目的?log4j2?核彈漏洞問題(一行代碼配置搞定)

    關(guān)于Spring?Boot項(xiàng)目的?log4j2?核彈漏洞問題(一行代碼配置搞定)

    相信昨天,很多小伙伴都因?yàn)長og4j2的史詩級漏洞忙翻了吧,不過我看到群里發(fā)出來的各種修復(fù)方法,還真是不好看...所以這里也提一下Spring Boot用戶怎么修復(fù)最簡單吧,對Spring Boot log4j2 核彈漏洞問題感興趣的朋友參考下吧
    2021-12-12
  • MyBatis-Plus如何解決主鍵自增問題

    MyBatis-Plus如何解決主鍵自增問題

    這篇文章主要介紹了MyBatis-Plus如何解決主鍵自增問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring框架花式創(chuàng)建Bean的n種方法(小結(jié))

    Spring框架花式創(chuàng)建Bean的n種方法(小結(jié))

    這篇文章主要介紹了Spring框架花式創(chuàng)建Bean的n種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Idea如何查看Maven依賴樹

    Idea如何查看Maven依賴樹

    這篇文章主要介紹了Idea如何查看Maven依賴樹問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Springboot?實(shí)現(xiàn)Server-Sent?Events的項(xiàng)目實(shí)踐

    Springboot?實(shí)現(xiàn)Server-Sent?Events的項(xiàng)目實(shí)踐

    本文介紹了在Spring?Boot中實(shí)現(xiàn)Server-Sent?Events(SSE),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • SpringBoot web開發(fā)源碼深入分析

    SpringBoot web開發(fā)源碼深入分析

    Web開發(fā)的核心內(nèi)容主要包括內(nèi)嵌的Servlet容器和SpringMVCSpringBoot使用起來非常簡潔,大部分配置都有SpringBoot自動裝配,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10

最新評論

阿巴嘎旗| 额济纳旗| 永州市| 天津市| 应用必备| 惠来县| 宜兰市| 德清县| 鸡东县| 阳曲县| 沙湾县| 民权县| 东台市| 长治市| 广南县| 黄平县| 广水市| 新巴尔虎右旗| 萨嘎县| 武乡县| 肇庆市| 锦州市| 白朗县| 云安县| 永新县| 聂拉木县| 化州市| 延安市| 石棉县| 香格里拉县| 大冶市| 兴仁县| 永修县| 龙州县| 昌宁县| 和硕县| 泸水县| 吴旗县| 湄潭县| 宁明县| 丰城市|