亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

一、緩存設(shè)計(jì)

1、緩存的作用

在業(yè)務(wù)系統(tǒng)中,查詢時(shí)最容易出現(xiàn)性能問(wèn)題的模塊,查詢面對(duì)的數(shù)據(jù)量大,篩選條件復(fù)雜,所以在系統(tǒng)架構(gòu)中引入緩存層,則是非常必要的,用來(lái)緩存熱點(diǎn)數(shù)據(jù),達(dá)到快速響應(yīng)的目的。

緩存使用的基本原則:

  • 所有緩存數(shù)據(jù),必須設(shè)置過(guò)期時(shí)間;
  • 核心業(yè)務(wù)流程不通過(guò)緩存層;
  • 緩存層移除,不影響現(xiàn)有流程;
  • 系統(tǒng)各個(gè)端首頁(yè)數(shù)據(jù)不實(shí)時(shí)查詢;
  • 報(bào)表數(shù)據(jù)不實(shí)時(shí)查詢加載;
  • 歸檔數(shù)據(jù)(定時(shí)統(tǒng)計(jì)的結(jié)果數(shù)據(jù))不實(shí)時(shí)查詢;

這里是業(yè)務(wù)架構(gòu)中常用的緩存策略,緩存通過(guò)犧牲強(qiáng)一致性來(lái)提高性能,所以并不是所有的業(yè)務(wù)都適合用緩存,實(shí)際考量都會(huì)針對(duì)具體的業(yè)務(wù),比如用戶相關(guān)維度的數(shù)據(jù)修改頻率低,會(huì)使用緩存,但是用戶權(quán)限數(shù)據(jù)(比如:免費(fèi)次數(shù))會(huì)考慮實(shí)時(shí)校驗(yàn),緩存層使用的相對(duì)較少。

2、緩存設(shè)計(jì)模式

Cache-Aside模式

業(yè)務(wù)中最常用的緩存層設(shè)計(jì)模式,基本實(shí)現(xiàn)邏輯和相關(guān)概念如下:

架構(gòu)設(shè)計(jì) | 緩存管理模式,監(jiān)控和內(nèi)存回收策略

 

  • 緩存命中:直接查詢緩存且命中,返回?cái)?shù)據(jù);
  • 緩存加載:查詢緩存未命中,從數(shù)據(jù)庫(kù)中查詢數(shù)據(jù),獲取數(shù)據(jù)后并加載到緩存;
  • 緩存失效:數(shù)據(jù)更新寫(xiě)到數(shù)據(jù)庫(kù),操作成功后,讓緩存失效,查詢時(shí)候再重新加載;
  • 緩存穿透:查詢數(shù)據(jù)庫(kù)不存在的對(duì)象,也就不存在緩存層的命中;
  • 緩存擊穿:熱點(diǎn)key在失效的瞬間,高并發(fā)查詢這個(gè)key,擊穿緩存,直接請(qǐng)求數(shù)據(jù)庫(kù);
  • 緩存雪崩:緩存Key大批量到過(guò)期時(shí)間,導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大;
  • 命中率:緩存設(shè)計(jì)的是否合理要看命中率,命中率高說(shuō)明緩存有效抗住了大部分請(qǐng)求,命中率可以通過(guò)redis監(jiān)控信息計(jì)算,一般來(lái)說(shuō)命中率在(70-80)%都算合理。 并發(fā)問(wèn)題

執(zhí)行讀操作未命中緩存,然后查詢數(shù)據(jù)庫(kù)中取數(shù)據(jù),數(shù)據(jù)已經(jīng)查詢到還沒(méi)放入緩存,同時(shí)一個(gè)更新寫(xiě)操作讓緩存失效,然后讀操作再把查詢到數(shù)據(jù)加載緩存,導(dǎo)致緩存的臟數(shù)據(jù)。

在遵守緩存使用原則下出現(xiàn)該情況概率非常低,可以通過(guò)復(fù)雜的Paxos協(xié)議保證一致性,一般情況是不考量該場(chǎng)景的處理,如果緩存管理過(guò)于復(fù)雜,會(huì)和緩存層核心理念相悖。

基本描述代碼:

@Service
public class KeyValueServiceImpl extends ServiceImpl<KeyValueMApper, KeyValueEntity> implements KeyValueService {

    @Resource
    private RedisService redisService ;

    @Override
    public KeyValueEntity select(Integer id) {
        // 查詢緩存
        String redisKey = RedisKeyUtil.getObectKey(id) ;
        String value = redisService.get(redisKey) ;
        if (!StringUtils.isEmpty(value) && !value.equals("null")){
            return JSON.parseobject(value,KeyValueEntity.class);
        }
        // 查詢庫(kù)
        KeyValueEntity keyValueEntity = this.getById(id) ;
        if (keyValueEntity != null){
            // 緩存寫(xiě)入
            redisService.set(redisKey,JSON.toJSONString(keyValueEntity)) ;
        }
        // 返回值
        return keyValueEntity ;
    }

    @Override
    public boolean update(KeyValueEntity keyValueEntity) {
        // 更新數(shù)據(jù)
        boolean updateFlag = this.updateById(keyValueEntity) ;
        // 清除緩存
        if (updateFlag){
            redisService.delete(RedisKeyUtil.getObectKey(keyValueEntity.getId()));
        }
        return updateFlag ;
    }
}

Read-Throug模式

當(dāng)應(yīng)用系統(tǒng)向緩存系統(tǒng)請(qǐng)求數(shù)據(jù)時(shí),如果緩存中并沒(méi)有對(duì)應(yīng)的數(shù)據(jù)存在,緩存系統(tǒng)將向底層數(shù)據(jù)源的讀取數(shù)據(jù)。如果數(shù)據(jù)在緩存中存在,則直接返回緩存中存在的數(shù)據(jù)。把更新數(shù)據(jù)庫(kù)的操作由緩存層代勞了。

Write-Through模式

更新寫(xiě)數(shù)據(jù)時(shí),如果沒(méi)有命中緩存,則直接更新數(shù)據(jù)庫(kù),如果命中了緩存,則先更新緩存,然后由緩存系統(tǒng)自行更新數(shù)據(jù)庫(kù)。

Write-Behind模式

應(yīng)用系統(tǒng)對(duì)緩存中的數(shù)據(jù)進(jìn)行更新時(shí),只更新緩存,不更新數(shù)據(jù)庫(kù),緩存系統(tǒng)會(huì)異步批量向底層數(shù)據(jù)源更新數(shù)據(jù)。

二、數(shù)據(jù)一致問(wèn)題

業(yè)務(wù)開(kāi)發(fā)模式中,會(huì)涉及到一個(gè)問(wèn)題:如何最大限度保證數(shù)據(jù)庫(kù)和Redis緩存的數(shù)據(jù)一致性?

首先說(shuō)明一下:數(shù)據(jù)庫(kù)和緩存強(qiáng)一致性同步成本太高,如果追求強(qiáng)一致,緩存層存在的價(jià)值就會(huì)很低,如上緩存模式一中幾乎可以解決大部分業(yè)務(wù)場(chǎng)景問(wèn)題。

解決這個(gè)問(wèn)題的方式很多:

架構(gòu)設(shè)計(jì) | 緩存管理模式,監(jiān)控和內(nèi)存回收策略

 

方案一說(shuō)明:

  • 數(shù)據(jù)庫(kù)更新寫(xiě)入數(shù)據(jù)成功;
  • 準(zhǔn)備一個(gè)先進(jìn)先出模式的消息隊(duì)列;
  • 把更新的數(shù)據(jù)包裝為一個(gè)消息放入隊(duì)列;
  • 基于消息消費(fèi)服務(wù)更新Redis緩存;

分析:消息隊(duì)列的穩(wěn)定和可靠性,操作層面數(shù)據(jù)庫(kù)和緩存層解耦。

方案二說(shuō)明:

  • 提供一個(gè)數(shù)據(jù)庫(kù)Binlog訂閱服務(wù),并解析修改日志;
  • 服務(wù)獲取修改數(shù)據(jù),并向Redis服務(wù)發(fā)送消息;
  • Redis數(shù)據(jù)進(jìn)行修改,類(lèi)似MySQL的主從同步機(jī)制;

分析:系統(tǒng)架構(gòu)層面多出一個(gè)服務(wù),且需要解析MySQL日志,操作難度較大,但流程上更為合理。

總結(jié)描述

分布式架構(gòu)中,緩存層面的基本需求就是提高響應(yīng)速度,不斷優(yōu)化,追求數(shù)據(jù)庫(kù)和Redis緩存的數(shù)據(jù)快速一致性,從提供的各種方案中都可以看出,這也在增加緩存層面處理的復(fù)雜性,架構(gòu)邏輯復(fù)雜,就容易導(dǎo)致程序錯(cuò)誤,所以針對(duì)業(yè)務(wù)選擇合理的處理邏輯,這點(diǎn)很關(guān)鍵。

三、緩存監(jiān)控

1、Redis服務(wù)監(jiān)控

通過(guò)info命令查看Redis服務(wù)的參數(shù)信息,可以通過(guò)傳參查看指定分類(lèi)配置。通過(guò)config..set設(shè)置具體配置參數(shù)。例如:

@Override
public Properties info(String var) {
    if (StringUtils.isEmpty(var)){
        return redisTemplate.getRequiredConnectionFactory().getConnection().info();
    }
    return redisTemplate.getRequiredConnectionFactory().getConnection().info(var);
}

傳參說(shuō)明:

  • memory:內(nèi)存消耗相關(guān)信息
  • server:有關(guān)Redis服務(wù)器的常規(guī)信息
  • clients:客戶端連接部分
  • stats:一般統(tǒng)計(jì)
  • cpu:CPU消耗統(tǒng)計(jì)信息

應(yīng)用案例:

@RestController
public class MonitorController {

    @Resource
    private RedisService redisService ;

    private static final String[] monitorParam = new String[]{"memory","server","clients","stats","cpu"} ;

    @GetMapping("/monitor")
    public List<MonitorEntity> monitor (){
        List<MonitorEntity> monitorEntityList = new ArrayList<>() ;
        for (String param:monitorParam){
            Properties properties = redisService.info(param) ;
            MonitorEntity monitorEntity = new MonitorEntity () ;
            monitorEntity.setMonitorParam(param);
            monitorEntity.setProperties(properties);
            monitorEntityList.add(monitorEntity);
        }
        return monitorEntityList ;
    }

}

通過(guò)上述參數(shù)組合,把Redis相關(guān)配置參數(shù)打印出來(lái),然后可視化輸出,儼然一副高端的感覺(jué)。

配置參數(shù)說(shuō)明:

這里只對(duì)兩個(gè)參數(shù)說(shuō)明一下,計(jì)算命中率的關(guān)鍵信息:

  • keyspace_misses:查找緩存Key失敗的次數(shù);
  • keyspace_hits:查找緩存Key命中的次數(shù);

公式:命中率=命中次數(shù)/(hits+misses)查找總次數(shù)。

2、LRU算法說(shuō)明

Redis的數(shù)據(jù)是放在內(nèi)存中的,所以速度快,自然也就受到內(nèi)存大小的限制,如果內(nèi)存使用超過(guò)配置,Redis有不同的回收處理策略。

內(nèi)存模塊參數(shù):maxmemory_policy

  • noenviction:不回收數(shù)據(jù),查詢直接返回錯(cuò)誤,但可以執(zhí)行刪除;
  • allkeys-lru:從所有的數(shù)據(jù)中挑選最近最少使用的數(shù)據(jù)淘汰;
  • volatile-lru:已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)中挑選最近最少使用的數(shù)據(jù)淘汰;
  • allkeys-random:從所有數(shù)據(jù)中任意選擇數(shù)據(jù)淘汰;
  • volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)中任意選擇數(shù)據(jù)淘汰;
  • volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)中挑選將要過(guò)期的數(shù)據(jù)淘汰;

大部分情況下,業(yè)務(wù)都是希望最熱點(diǎn)數(shù)據(jù)可以被緩存,所以相對(duì)使用allkeys-lru策略偏多。這里要根據(jù)業(yè)務(wù)模式特點(diǎn)衡量。

分享到:
標(biāo)簽:緩存 管理
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定