亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Redis與本地緩存的結合實現(xiàn)

 更新時間:2022年07月14日 10:13:11   作者:熱黃油啤酒  
我們開發(fā)中經(jīng)常用到Redis作為緩存,本文主要介紹了Redis與本地緩存的結合實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

  • 我們開發(fā)中經(jīng)常用到Redis作為緩存,將高頻數(shù)據(jù)放在Redis中能夠提高業(yè)務性能,降低MySQL等關系型數(shù)據(jù)庫壓力,甚至一些系統(tǒng)使用Redis進行數(shù)據(jù)持久化,Redis松散的文檔結構非常適合業(yè)務系統(tǒng)開發(fā),在精確查詢,數(shù)據(jù)統(tǒng)計業(yè)務有著很大的優(yōu)勢。但是高頻數(shù)據(jù)流處理系統(tǒng)中,Redis的壓力也會很大,同時I/0開銷才是耗時的主要原因,這時候為了降低Redis讀寫壓力我們可以用到本地緩存,Guava為我們提供了優(yōu)秀的本地緩存API,包含了過期策略等等,編碼難度低,個人非常推薦。

設計示例

Redis懶加載緩存

數(shù)據(jù)在新增到MySQL不進行緩存,在精確查找進行緩存,做到查詢即緩存,不查詢不緩存

流程圖

代碼示例

// 偽代碼示例 Xx代表你的的業(yè)務對象 如User Goods等等
public class XxLazyCache {

    @Autowired
    private RedisTemplate<String, Xx> redisTemplate;
    
    @Autowired
    private XxService xxService;// 你的業(yè)務service
    
    /**
     * 查詢 通過查詢緩存是否存在驅動緩存加載 建議在前置業(yè)務保證id對應數(shù)據(jù)是絕對存在于數(shù)據(jù)庫中的
     */
    public Xx getXx(int id) {
        // 1.查詢緩存里面有沒有數(shù)據(jù)
        Xx xxCache = getXxFromCache(id);
        if(xxCache != null) {
            return xxCache;// 衛(wèi)語句使代碼更有利于閱讀
        }
        // 2.查詢數(shù)據(jù)庫獲取數(shù)據(jù) 我們假定到業(yè)務這一步,傳過來的id都在數(shù)據(jù)庫中有對應數(shù)據(jù)
        Xx xx = xxService.getXxById(id);
        // 3.設置緩存、這一步相當于Redis緩存懶加載,下次再查詢此id,則會走緩存
        setXxFromCache(xx);
        return xx;
        }
    }
    
    /**
     * 對xx數(shù)據(jù)進行修改或者刪除操作 操作數(shù)據(jù)庫成功后 刪除緩存
     * 刪除請求 - 刪除數(shù)據(jù)庫數(shù)據(jù) 刪除緩存
     * 修改請求 - 更新數(shù)據(jù)庫數(shù)據(jù) 刪除緩存 下次在查詢時候就會從數(shù)據(jù)庫拉取新的數(shù)據(jù)到緩存中
     */
    public void deleteXxFromCache(long id) {
        String key = "Xx:" + xx.getId();
        redisTemplate.delete(key);
    }
    
    private void setXxFromCache(Xx xx) {
        String key = "Xx:" + xx.getId();
        redisTemplate.opsForValue().set(key, xx);
    }
    
    private Xx getXxFromCache(int id) {
        // 通過緩存前綴拼裝唯一主鍵作為緩存Key 如Xxx信息 就是Xxx:id
        String key = "Xx:" + id;
        return redisTemplate.opsForValue().get(key);
    }
    
}
// 業(yè)務類
public class XxServie {
    @Autowired
    private XxLazyCache xxLazyCache;
    // 查詢數(shù)據(jù)庫
    public Xx getXxById(long id) {
        // 省略實現(xiàn)
        return xx;
    }
    
    public void updateXx(Xx xx) {
        // 更新MySQL數(shù)據(jù) 省略
        // 刪除緩存
        xxLazyCache.deleteXxFromCache(xx.getId());
    }
    
    public void deleteXx(long id) {
        // 刪除MySQL數(shù)據(jù) 省略
        // 刪除緩存
        xxLazyCache.deleteXxFromCache(xx.getId());
    }
}
// 實體類
@Data
public class Xx {
    // 業(yè)務主鍵
    private Long id;
    // ...省略
}
復制代碼

優(yōu)點

  • 保證最小的緩存量滿足精確查詢業(yè)務,避免冷數(shù)據(jù)占用寶貴的內存空間
  • 對增刪改查業(yè)務入侵小、刪除即同步
  • 可插拔,對于老系統(tǒng)升級,歷史數(shù)據(jù)無需在啟動時初始化緩存

缺點

  • 數(shù)據(jù)量需可控,在無限增長業(yè)務場景不適用
  • 在微服務場景不利于全局緩存應用

總結

  • 空間最小化
  • 滿足精確查詢場景
  • 總數(shù)據(jù)量可控推薦使用
  • 微服務場景不適用

Redis結合本地緩存

微服務場景下,多個微服務使用一個大緩存,流數(shù)據(jù)業(yè)務下,高頻讀取緩存對Redis壓力很大,我們使用本地緩存結合Redis緩存使用,降低Redis壓力,同時本地緩存沒有連接開銷,性能更優(yōu)

流程圖

業(yè)務場景

在流處數(shù)處理過程中,微服務對多個設備上傳的數(shù)據(jù)進行處理,每個設備有一個code,流數(shù)據(jù)的頻率高,在消息隊列發(fā)送過程中使用分區(qū)發(fā)送,我們需要為設備code生成對應的自增號,用自增號對kafka中topic分區(qū)數(shù)進行取模,這樣如果有10000臺設備,自增號就是0~9999,在取模后就進行分區(qū)發(fā)送就可以做到每個分區(qū)均勻分布,這個自增號我們使用redis的自增數(shù)生成,生成后放到redis的hash結構進行緩存,每次來一個設備,我們就去這個hash緩存中取,沒有取到就使用自增數(shù)生成一個,然后放到redis的hash緩存中,這時候每個設備的自增數(shù)一經(jīng)生成是不會再發(fā)生改變的,我們就想到使用本地緩存進行優(yōu)化,避免高頻的調用redis去獲取,降低redis壓力,下面鏈接為我寫的關于kafka分區(qū)消費的文章,大家可以去看看 Kafka分區(qū)發(fā)送及消費實戰(zhàn)

代碼示例

/**
 * 此緩存演示如何結合redis自增數(shù) hash 本地緩存使用進行設備自增數(shù)的生成、緩存、本地緩存
 * 本地緩存使用Guava Cache
 */
public class DeviceIncCache {

    /**
     * 本地緩存
     */
    private Cache<String, Integer> localCache = CacheBuilder.newBuilder()
        .concurrencyLevel(16) // 并發(fā)級別
        .initialCapacity(1000) // 初始容量
        .maximumSize(10000) // 緩存最大長度
        .expireAfterAccess(1, TimeUnit.HOURS) // 緩存1小時沒被使用就過期
        .build();

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;
    
    /**
     * redis自增數(shù)緩存的key
     */
    private static final String DEVICE_INC_COUNT = "device_inc_count";
    
    /**
     * redis設備編碼對應自增數(shù)的hash緩存key
     */
    private static final String DEVICE_INC_VALUE = "device_inc_value";
    
    /**
     * 獲取設備自增數(shù)
     */
    public int getInc(String deviceCode){
        // 1.從本地緩存獲取
        Integer inc = localCache.get(deviceCode);
        if(inc != null) {
            return inc;
        }
        // 2.本地緩存未命中,從redis的hash緩存獲取
        inc = (Integer)redisTemplate.opsForHash().get(DEVICE_INC_VALUE, deviceCode);
        // 3. redis的hash緩存中沒有,說明是新設備,先為設備生成一個自增號
        if(inc == null) {
            inc = redisTemplate.opsForValue().increment(DEVICE_INC_COUNT).intValue;
            // 添加到redis hash緩存
            redisTemplate.opsForHash().put(DEVICE_INC_VALUE, deviceCode, inc);
        }
        // 4.添加到本地緩存
        localCache.put(deviceCode, inc);
        // 4.返回自增數(shù)
        return inc;
    }
    
}

優(yōu)點

  • redis保證數(shù)據(jù)可持久,本地緩存保證超高的讀取性能,微服務共用redis大緩存的場景能有效降低redis壓力
  • guava作為本地緩存,提供了豐富的api,過期策略,最大容量,保證服務內存可控,冷數(shù)據(jù)不會長期占據(jù)內存空間
  • 服務重啟導致的本地緩存清空不會影響業(yè)務進行
  • 微服務及分布式場景使用,分布式情況下每個服務實例只會緩存自己接入的那一部分設備的自增號,本地內存空間最優(yōu)
  • 在示例業(yè)務中,自增數(shù)滿足了分布區(qū)發(fā)送的均勻分布需求,也可以滿足統(tǒng)計設備接入數(shù)目的業(yè)務場景,一舉兩得

缺點

  • 增加編碼復雜度,不直接
  • 只適用于緩存內容只增不改的場景

總結

  • 本地緩存空間可控,過期策略優(yōu)
  • 適用于微服務及分布式場景
  • 緩存內容不能發(fā)生改變
  • 性能優(yōu)

后記

redis提供了豐富的數(shù)據(jù)類型及api,非常適合業(yè)務系統(tǒng)開發(fā),統(tǒng)計計數(shù)(increment,decrement),標記位(bitmap),松散數(shù)據(jù)(hash),先進先出、隊列式讀?。╨ist);guava緩存作為本地緩存,能夠高效的讀取的同時,提供了大量api方便我們控制本地緩存的數(shù)據(jù)量及冷數(shù)據(jù)淘汰;我們充分的學習這些特性能夠幫助我們在業(yè)務開發(fā)中更加輕松靈活,在空間與時間上找到一個平衡點。

到此這篇關于Redis與本地緩存的結合實現(xiàn)的文章就介紹到這了,更多相關Redis本地緩存內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解決redis sentinel 頻繁主備切換的問題

    解決redis sentinel 頻繁主備切換的問題

    這篇文章主要介紹了解決redis sentinel 頻繁主備切換的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Redis搶單預熱的實現(xiàn)示例

    Redis搶單預熱的實現(xiàn)示例

    本文主要介紹了Redis搶單預熱的實現(xiàn)示例,以應對搶單活動帶來的高并發(fā)訪問壓力,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • MyBatis緩存和二級緩存整合Redis的解決方案

    MyBatis緩存和二級緩存整合Redis的解決方案

    這篇文章主要介紹了MyBatis緩存和二級緩存整合Redis,將MyBatis緩存和二級緩存整合Redis,可以提高查詢效率,同時也能保證數(shù)據(jù)的可靠性和一致性,需要的朋友可以參考下
    2023-07-07
  • Redis簡單動態(tài)字符串SDS的實現(xiàn)示例

    Redis簡單動態(tài)字符串SDS的實現(xiàn)示例

    Redis沒有直接復用C語言的字符串,而是新建了SDS,本文主要介紹了Redis簡單動態(tài)字符串SDS的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Redis實現(xiàn)排行榜及相同積分按時間排序功能的實現(xiàn)

    Redis實現(xiàn)排行榜及相同積分按時間排序功能的實現(xiàn)

    這篇文章主要介紹了Redis實現(xiàn)排行榜及相同積分按時間排序,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • Redis實現(xiàn)好友關注的示例代碼

    Redis實現(xiàn)好友關注的示例代碼

    本文主要介紹了Redis實現(xiàn)好友關注的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • Windows下搭建Redis集群的方法步驟

    Windows下搭建Redis集群的方法步驟

    本文主要介紹了Windows下搭建Redis集群的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • redis中zSet實現(xiàn)排行榜的使用示例

    redis中zSet實現(xiàn)排行榜的使用示例

    在工作中,有時候需要實現(xiàn)排行榜功能,本文主要介紹了redis中zSet實現(xiàn)排行榜的使用示例,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • Redis設置database不生效的解決方案

    Redis設置database不生效的解決方案

    最近在做redis緩存設置的時候,發(fā)現(xiàn)即使已經(jīng)設置了database, 但是存數(shù)據(jù)的時候還是用的默認0數(shù)據(jù)庫,所以本文就給大家介紹了Redis設置database不生效的解決方案,需要的朋友可以參考下
    2023-08-08
  • Linux下redis密碼和遠程連接方式

    Linux下redis密碼和遠程連接方式

    這篇文章主要介紹了Linux下redis密碼和遠程連接方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論