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

java分布式緩存方案

 更新時間:2021年08月23日 17:17:43   作者:女友在高考  
本文簡單介紹了緩存的種類,緩存常見的問題,對大家的學習和工作有一定的參考價值,需要的小伙伴可以參考一下

一、從數(shù)據(jù)說起

我們再做緩存之前需要把數(shù)據(jù)先分好類

按變化頻率:

  • 靜態(tài)數(shù)據(jù):一般不變的,類似于字典表
  • 準靜態(tài)數(shù)據(jù):變化頻率很低,部門結(jié)構(gòu)設(shè)置,全國行政區(qū)劃數(shù)據(jù)
  • 中間狀態(tài)數(shù)據(jù):一些計算的可復用中間數(shù)據(jù),變量副本,配置中心的本地副本

按使用頻率:

  • 熱數(shù)據(jù):使用頻率高的
  • 讀寫比大的:讀的頻率遠大于寫的頻率

這些數(shù)據(jù)就比較適合使用緩存。

緩存無處不在。內(nèi)存可以看作是cpu和磁盤之間的緩存。cpu與內(nèi)存的處理速度也不一致,所以出現(xiàn)了L1&L2 Cache

緩存的本質(zhì):系統(tǒng)各級之間處理速度不匹配,利用空間換時間。

緩存加載時間

1. 啟動時全量加載

2. 懶加載

2.1. 同步使用加載

先看緩存里是否有數(shù)據(jù),沒有的話從數(shù)據(jù)庫讀取。讀取的數(shù)據(jù),先放到內(nèi)存,然后返回給調(diào)用方。

2.2. 延遲異步加載

從緩存里獲取數(shù)據(jù),不管有沒有都直接返回。

策略1:如果緩存為空的話,則發(fā)起一個異步線程負責加載。

策略2:異步線程負責維護緩存的數(shù)據(jù),定期或根據(jù)條件觸發(fā)更新。

緩存過期策略

  • 按FIFO或LRU
  • 固定時間過期
  • 根據(jù)業(yè)務進行時間的加權(quán)。

二、本地緩存

1.Map 緩存

public static final Map<String,Object> CACHE=new HashMap();
CACHE.put("key","value");

2.Guava緩存

Cache<String,String> cache = CacheBuilder.newBuilder() .maximumSize(1024) .expireAfterWrite(60,TimeUnit.SECONDS) .weakValues() .build();
cache.put("word","Hello Guava Cache");
System.out.println(cache.getIfPresent("word"));


3.Spring Cache

  • 基于注解和AOP,使用方便
  • 可以配置Condition和SPEL,非常靈活
  • 需要注意:繞過Spring的話,注解無效

核心功能:@Cacheable、@CachePut、@CacheEvict

本地緩存的缺點:

  • 在集群環(huán)境中,如果每個節(jié)點都保存一份緩存,導致占用內(nèi)存變大
  • 在JVM中長期存在,會影響GC
  • 緩存數(shù)據(jù)的調(diào)度處理,影響業(yè)務線程,爭奪資源

三、遠程緩存

1.Redis
Redis是一個開源的使用ANSI C語言編寫的,基于內(nèi)存也可以持久化的key-value數(shù)據(jù)庫,并提供多種語言的API
2. Memcached

memcached是一套分布式的高速緩存系統(tǒng),由LiveJournal的Brad Fitzpatrick開發(fā),但被許多網(wǎng)站使用。這是一套開放源代碼軟件,以BSD license授權(quán)發(fā)布。

四、內(nèi)存網(wǎng)格

  1. Hazelcast
  2. lgnite

五、緩存常見問題

1. 緩存穿透

問題描述:大量并發(fā)查詢不存在的KEY,導致都直接把壓力透傳到數(shù)據(jù)庫上。

分析:因為數(shù)據(jù)庫里沒有值,所以沒有建立緩存,導致一直打到數(shù)據(jù)庫上。

解決辦法:

  1. 緩存空值的KEY
  2. Bloom過濾或RoaringBitmap判斷KEY是否存在
  3. 完全以緩存為準,使用延遲異步加載的方式去加載數(shù)據(jù)庫數(shù)據(jù)到緩存。

Bloom過濾器示例:
(引入guava依賴)

public static void main(String[] args) {
        BloomFilter<CharSequence> filter = BloomFilter.create(
                Funnels.stringFunnel(Charsets.UTF_8),//Funnels.integerFunnel(), //數(shù)據(jù)格式
                1000000,//預計存入數(shù)據(jù)量
                0.01);//誤判率

        System.out.println(filter.mightContain("abcdefg"));
        filter.put("abcdefg");
        System.out.println(filter.mightContain("abcdefg"));
    }

RoaringBitmap示例:
引入依賴:

<dependency>
			<groupId>org.roaringbitmap</groupId>
			<artifactId>RoaringBitmap</artifactId>
			<version>0.8.1</version>
		</dependency>
public static void test3(){
        Roaring64NavigableMap roaring64NavigableMap = Roaring64NavigableMap.bitmapOf(3, 4, 5, 90);
        //是否包含
        boolean contains = roaring64NavigableMap.contains(3);
        long l = roaring64NavigableMap.rankLong(3);
        System.out.println(l);
        System.out.println(contains);
    }

2. 緩存擊穿

問題:當某個KEY失效的時候,正好有大量并發(fā)請求訪問這個KEY

分析:跟緩存穿透比較像,這個是屬于偶然的

解決辦法:

  1. KEY的更新的時候添加全局互斥鎖
  2. 完全以緩存為準,使用延遲異步加載的策略

3. 緩存雪崩

問題:當某一個時刻發(fā)生大規(guī)模的緩存失效的情況,會有大量請求打到數(shù)據(jù)庫,導致數(shù)據(jù)庫壓力過大而宕機

分析:一般來說,由于更新策略、或者數(shù)據(jù)熱點、緩存服務宕機等原因,導致緩存數(shù)據(jù)同時大規(guī)模不可以。

解決辦法:

  1. 緩存更新、失效策略在時間上做到比較均勻
  2. 使用的熱數(shù)據(jù)盡量分散到不同機器上
  3. 多臺機器做主從復制,實現(xiàn)高可用
  4. 實現(xiàn)熔斷限流機制,對系統(tǒng)進行負載能力控制
  5. 使用本地緩存兜底

番外:

布隆過濾器:

目標就是要基于過濾器已存儲生成的原始元數(shù)據(jù),進行比較過濾,如果是在原始元數(shù)據(jù)集合里面的,一定會被發(fā)現(xiàn)。也有可能不是里面的被誤殺。

BloomFilter 會開辟一個m位的bitArray(位數(shù)組),開始所有數(shù)據(jù)都部署為0,當一個元素過來的時候,通過多個hash函數(shù)計算出不同的值,然后根據(jù)hash值找到對應的下標處,將里面的值改為1.

優(yōu)點:使用計算,節(jié)省存儲空間。

缺點:有失誤率。不是在過濾器原始表里的數(shù)據(jù)也會被誤算進去。

使用場景:目標就是要基于過濾器已存儲生成的原始元數(shù)據(jù),進行比較過濾,如果是在原始元數(shù)據(jù)集合里面的,一定會被發(fā)現(xiàn)。布隆過濾器核心正確的使用就是進行過濾禁止,進行正確的否定。

舉例:如我們有100萬個黑名單的url地址,過來一個地址我們算出來不在里面,那就肯定可以放行。

BitMap:

BitMap的基本思想是用一個bit位來標記某個元素對應的值,這樣就可以大大節(jié)省空間。

在Java中一個int占4個字節(jié),也就是32bit。按int存儲和按位存儲的大小差距是32倍。

那么怎么表示一個數(shù)呢?可以使用1表示存在,0表示不存在。

如下面:表示{2,6}

一個byte只有8個位置,如果想表示13怎么辦呢?只能再用一個byte了,就成了一個二維數(shù)組了

1個int占32位,那么我們只需要申請一個int數(shù)組長度為 int tmp[1+N/32] 即可存儲,其中N表示要存儲的這些數(shù)中的最大值

使用場景:

  • 1.快速排序

把數(shù)放進去之后,遍歷一遍,把值是1的都取出來就排好序了。

  • 2.快速去重

20億個整數(shù)中找出不重復的整數(shù)的個數(shù)?

內(nèi)存不足以容納這20億個整數(shù)。我們怎么表示數(shù)字的狀態(tài)呢?一個數(shù)的狀態(tài)可以分為3種,不存在、存在一次、存在兩次及以上。這就需要兩個bit來表示。00代表不存在,01代表一次,11代表兩次及以上。

接下來我們就把這20億個整數(shù)放進去,如果狀態(tài)為00,就改為01,如果狀態(tài)為01就改為11.如果狀態(tài)為11,就不動了。都放完后,遍歷取出值為01的,就是不重復的數(shù)據(jù)的個數(shù)。。

  • 3. 快速查找

給定一個整數(shù)M,M/32就能得到int數(shù)組的下標,M%32就知道在這個下標里面的具體位置。

如13,就能算出在int[0]里面的第13個

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

相關(guān)文章

  • Spring注解@Configuration與@Bean注冊組件的使用詳解

    Spring注解@Configuration與@Bean注冊組件的使用詳解

    這篇文章主要介紹了SpringBoot中的注解@Configuration與@Bean注冊組件的使用,具有很好的參考價值,希望對大家有所幫助
    2022-06-06
  • IntelliJ IDEA中ajax開發(fā)實現(xiàn)分頁查詢示例

    IntelliJ IDEA中ajax開發(fā)實現(xiàn)分頁查詢示例

    這篇文章主要介紹了IntelliJ IDEA中ajax開發(fā)實現(xiàn)分頁查詢,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Spring Cloud Gateway層限流實現(xiàn)過程

    Spring Cloud Gateway層限流實現(xiàn)過程

    這篇文章主要介紹了Spring Cloud Gateway層限流實現(xiàn)過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 開發(fā)工具EesyCode使用方法解析

    開發(fā)工具EesyCode使用方法解析

    這篇文章主要介紹了開發(fā)工具EesyCode使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot+Redis實現(xiàn)查找附近用戶的示例代碼

    SpringBoot+Redis實現(xiàn)查找附近用戶的示例代碼

    SpringDataRedis提供了十分簡單的地理位置定位的功能,本文主要介紹了SpringBoot+Redis實現(xiàn)查找附近用戶的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • FilenameUtils.getName?函數(shù)源碼分析

    FilenameUtils.getName?函數(shù)源碼分析

    這篇文章主要為大家介紹了FilenameUtils.getName?函數(shù)源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Java基礎(chǔ)之查找文本特定內(nèi)容后進行修改

    Java基礎(chǔ)之查找文本特定內(nèi)容后進行修改

    這篇文章主要介紹了Java基礎(chǔ)之查找文本特定內(nèi)容后進行修改,文中有非常詳細的代碼示例,對正在學習java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Spring中@Autowired注解的原理詳解

    Spring中@Autowired注解的原理詳解

    這篇文章主要介紹了Spring中@Autowired注解的原理詳解,對于spring配置一個bean時,如果需要給該bean提供一些初始化參數(shù),則需要通過依賴注入方式,所謂的依賴注入就是通過spring將bean所需要的一些參數(shù)傳遞到bean實例對象的過程,需要的朋友可以參考下
    2023-11-11
  • Mybatis攔截器實現(xiàn)分頁

    Mybatis攔截器實現(xiàn)分頁

    本文介紹使用Mybatis攔截器,實現(xiàn)分頁;并且在dao層,直接返回自定義的分頁對象。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • JavaFX實現(xiàn)簡單日歷效果

    JavaFX實現(xiàn)簡單日歷效果

    這篇文章主要為大家詳細介紹了JavaFX實現(xiàn)簡單日歷效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評論

开封县| 西乡县| 樟树市| 浪卡子县| 洛川县| 彰化县| 华蓥市| 万宁市| 分宜县| 额济纳旗| 芮城县| 渭源县| 陈巴尔虎旗| 彭水| 威信县| 军事| 慈溪市| 广德县| 龙山县| 富顺县| 南木林县| 湟中县| 平泉县| 方山县| 南陵县| 龙南县| 扶沟县| 昌邑市| 株洲县| 灌云县| 同江市| 安泽县| 金昌市| 万宁市| 蒙城县| 集贤县| 连山| 红原县| 平远县| 青冈县| 澎湖县|