宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動態(tài)
精選推薦

淺談Redis緩存的穿透、擊穿和雪崩

管理 管理 編輯 刪除

Redis是一種流行的內(nèi)存緩存解決方案,但在實(shí)際使用中,會遇到一些緩存相關(guān)的問題,其中最主要的就是緩存穿透,擊穿和雪崩問題。

一、緩存穿透

緩存穿透是指當(dāng)查詢一個不存在的緩存時,由于緩存中沒有相應(yīng)的數(shù)據(jù),而數(shù)據(jù)庫中也不存在對應(yīng)的數(shù)據(jù),導(dǎo)致每次查詢都必須訪問數(shù)據(jù)庫,這會導(dǎo)致數(shù)據(jù)庫的負(fù)載過高。攻擊者可以利用這個漏洞進(jìn)行惡意攻擊,通過不斷查詢不存在的緩存,來使緩存服務(wù)器或者數(shù)據(jù)庫癱瘓。

關(guān)于緩存穿透常用的的有兩種解決辦法:

第一種,緩存空數(shù)據(jù),當(dāng)查詢一個不存在的數(shù)據(jù)時,可以將這個查詢結(jié)果緩存起來,以空對象的形式存儲在緩存中。這樣,在下一次查詢時,如果緩存中存在這個空對象,就可以直接返回,而不會再次查詢數(shù)據(jù)庫或接口。

第二種,使用布隆過濾器

<?php

/**
 * 布隆過濾器類
 */
class BloomFilter {
    private $redis; // Redis對象
    private $bitmapSize; // 位圖大小
    private $hashCount; // 哈希函數(shù)數(shù)量

    /**
     * 構(gòu)造函數(shù)
     * @param int $bitmapSize 位圖大小,默認(rèn)為1024
     * @param int $hashCount 哈希函數(shù)數(shù)量,默認(rèn)為3
     */
    public function __construct($bitmapSize = 1024, $hashCount = 3) {
        // 實(shí)例化Redis對象并連接到Redis服務(wù)器
		$redis = new Redis();
		$redis->connect('127.0.0.1', 6379);
		$this->redis = $redis;
        $this->bitmapSize = $bitmapSize;
        $this->hashCount = $hashCount;
    }

    /**
     * 插入元素到布隆過濾器中
     * @param string $element 要插入的元素
     */
    public function insert($element) {
        // 對元素進(jìn)行多次哈希,并在位圖中設(shè)置相應(yīng)位置為1
        for ($i = 1; $i <= $this->hashCount; $i++) {
            $hash = md5($element . $i);
            $position = hexdec(substr($hash, 0, 6)) % $this->bitmapSize;
            $this->redis->setBit('bloom_filter', $position, 1);
        }
    }

    /**
     * 判斷元素是否存在于布隆過濾器中
     * @param string $element 要判斷的元素
     * @return bool 如果存在返回true,否則返回false
     */
    public function contains($element) {
        // 對元素進(jìn)行多次哈希,并檢查位圖相應(yīng)位置是否為1
        for ($i = 1; $i <= $this->hashCount; $i++) {
            $hash = md5($element . $i);
            $position = hexdec(substr($hash, 0, 6)) % $this->bitmapSize;
            if (!$this->redis->getBit('bloom_filter', $position)) {
                // 如果任意一個位置為0,則表示元素不存在于布隆過濾器中
                return false;
            }
        }
        // 如果所有位置都為1,則表示元素可能存在于布隆過濾器中
        return true;
    }
}

// 緩存穿透解決方案
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 實(shí)例化布隆過濾器對象
$bloomFilter = new BloomFilter($redis);
$cacheKey = 'product_info_123';
if ($bloomFilter->contains($cacheKey)) {
    $productInfo = $redis->get($cacheKey);
    if ($productInfo) {
        return $productInfo;
    }
} else {
    // 如果布隆過濾器中不存在該鍵,則直接返回空結(jié)果
    return null;
}

// 如果緩存中不存在該鍵,則從數(shù)據(jù)庫中查詢并存入緩存和布隆過濾器中
$productInfo = $database->queryProductInfoById(123);
if (!$productInfo) {
    // 如果數(shù)據(jù)庫中也不存在該記錄,則插入一個空記錄,防止緩存穿透攻擊
    $productInfo = '';
    $redis->set($cacheKey, 60, $productInfo);
} else {
    $redis->set($cacheKey, 60, $productInfo);
    $bloomFilter->insert($cacheKey);
}
return $productInfo;

二、緩存擊穿

緩存擊穿是指當(dāng)某個熱點(diǎn)數(shù)據(jù)失效時,大量的并發(fā)請求訪問這個熱點(diǎn)數(shù)據(jù),導(dǎo)致所有請求都訪問數(shù)據(jù)庫,從而使數(shù)據(jù)庫的負(fù)載急劇增加。為了避免這種情況發(fā)生,可以將熱點(diǎn)數(shù)據(jù)的緩存時間設(shè)置為永不過期,或者設(shè)置一個較長的過期時間。

$redis->set($key, $value, -1) 和$redis->set($key, $value) 都可以用來設(shè)置緩存數(shù)據(jù),并且讓緩存永不過期。

三、緩存雪崩

緩存雪崩是指當(dāng)某一時刻緩存中的大量數(shù)據(jù)同時失效時,大量的并發(fā)請求訪問這些失效的數(shù)據(jù),導(dǎo)致所有請求都訪問數(shù)據(jù)庫,從而使數(shù)據(jù)庫的負(fù)載急劇增加。為了避免這個問題,我們可以設(shè)置緩存的過期時間隨機(jī)化,使緩存的失效時間不同,避免大量數(shù)據(jù)同時失效。此外,我們也可以采用緩存預(yù)熱的方式,提前將熱點(diǎn)數(shù)據(jù)加載到緩存中,以減少緩存的失效率。

在實(shí)際應(yīng)用中,可以通過設(shè)置一個隨機(jī)數(shù)生成器,隨機(jī)生成一個緩存時間偏移量,然后將緩存時間加上偏移量作為實(shí)際緩存時間。例如,在一個緩存時間為60秒的基礎(chǔ)上,可以隨機(jī)生成一個0到10秒的偏移量,然后將緩存時間設(shè)置為60秒加上該偏移量,即在60到70秒之間隨機(jī)。

// 緩存時間
$cache_time = 60;

// 生成隨機(jī)偏移量
$offset = rand(0, 10);

// 設(shè)置緩存時間
$expire_time = $cache_time + $offset;

// 設(shè)置緩存
$redis->set($key, $value, $expire_time);



請登錄后查看

徐斗明 最后編輯于2023-09-13 14:10:07

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
2183
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動態(tài) 精選推薦 首頁頭條 首頁動態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動獲取的帖子內(nèi)容,不準(zhǔn)確時需要手動修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊

切換手機(jī)號登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服