溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis安全策略實例分析

發(fā)布時間:2022-07-28 09:59:19 來源:億速云 閱讀:108 作者:iii 欄目:開發(fā)技術

本文小編為大家詳細介紹“Redis安全策略實例分析”,內容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“Redis安全策略實例分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

緩存穿透

高并發(fā)情況下查詢一個不存在的key

產生的背景(原因):

緩存穿透是指使用不存在的key進行大量的高并發(fā)查詢,導致緩存無法命中,每次請求都要都要穿透到后端數(shù)據(jù)庫查詢,使得數(shù)據(jù)庫的壓力非常大,甚至導致數(shù)據(jù)庫服務壓死;

解決方案:

  1. 接口層實現(xiàn)api限流、用戶授權、id檢查等;

  2. 從緩存和數(shù)據(jù)庫都取不到數(shù)據(jù)的話,一樣將數(shù)據(jù)庫空值放入緩存中,設置30s有效期避免使用同一個id對數(shù)據(jù)庫攻擊壓力大;

  3. 布隆過濾器

緩存擊穿

高并發(fā)情況下查詢的一個key突然過期

產生背景(原因):

在高并發(fā)的情況下,當一個緩存key過期時,因為訪問該key請求較大,多個請求同時發(fā)現(xiàn)緩存過期,因此對多個請求同時數(shù)據(jù)庫查詢、同時向Redis寫入緩存數(shù)據(jù),這樣會導致數(shù)據(jù)庫的壓力非常大;

解決方案:

  1. 使用分布式鎖

保證在分布式情況下,使用分布式鎖保證對于每個key同時只允許只有一個線程查詢到后端服務,其他沒有獲取到鎖的權限,只需要等待即可;這種高并發(fā)壓力直接轉移到分布式鎖上,對分布式鎖的壓力非常大。

  1. 使用本地鎖

使用本地鎖與分布式鎖機制一樣,只不過分布式鎖適應于服務集群、本地鎖僅限于單個服務使用。

  1. 軟過過期

設置熱點數(shù)據(jù)永不過期或者異步延長過期時間;

緩存雪崩

高并發(fā)情況下大量的key 集中失效

產生背景(原因):

緩存雪崩指緩存服務器重啟或者大量的緩存集中在某個時間段失效,突然給數(shù)據(jù)庫產生了巨大的壓力,甚至擊垮數(shù)據(jù)庫的情況。

解決思路:對不用的數(shù)據(jù)使用不同的失效時間,加上隨機數(shù)

布隆過濾器

布隆過濾器適用于判斷某個數(shù)據(jù)是否在集合中存在,不一定百分百準備, Bloom Filter基本實現(xiàn)原理采用位數(shù)組與聯(lián)合函數(shù)一起實現(xiàn);

布隆過濾器最大的問題:就是可能會存在一個誤判的問題,如果向誤判概率越低,則二進制數(shù)組會越大,同時也會非常占用空間

基于布隆過濾器解決緩存穿透問題

maven依賴

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>22.0</version>
</dependency>

測試代碼

public class BlongTest {
    /**
     * 在布隆中存放100萬條數(shù)據(jù)
     */
    private static Integer size = 1000000;
    public static void main(String[] args) {
        BloomFilter<Integer> integerBloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, 0.01);
        for (int i = 0; i < size; i++) {
            integerBloomFilter.put(i);
        }
        // 從布隆中查詢數(shù)據(jù)是否存在
        ArrayList<Integer> strings = new ArrayList<>();
        for (int j = size; j < size + 10000; j++) {
            if (integerBloomFilter.mightContain(j)) {
                strings.add(j);
            }
        }
        System.out.println("誤判數(shù)量:" + strings.size());
    }
}

解決緩存擊穿代碼

@RequestMapping("/getOrder")
public OrderEntity getOrder(Integer orderId) {
    if (integerBloomFilter != null) {
        if (!integerBloomFilter.mightContain(orderId)) {
            System.out.println("從布隆過濾器中檢測到該key不存在");
            return null;
        }
    }
    // 1.先查詢Redis中數(shù)據(jù)是否存在
    OrderEntity orderRedisEntity = (OrderEntity) redisTemplateUtils.getObject(orderId + "");
    if (orderRedisEntity != null) {
        System.out.println("直接從Redis中返回數(shù)據(jù)");
        return orderRedisEntity;
    }
    // 2. 查詢數(shù)據(jù)庫的內容
    System.out.println("從DB查詢數(shù)據(jù)");
    OrderEntity orderDBEntity = orderMapper.getOrderById(orderId);
    if (orderDBEntity != null) {
        System.out.println("將Db數(shù)據(jù)放入到Redis中");
        redisTemplateUtils.setObject(orderId + "", orderDBEntity);
    }
    return orderDBEntity;
}
/**
* 添加訂單id到布隆過濾器中
*/
@RequestMapping("/dbToBulong")
public String dbToBulong() {
    List<Integer> orderIds = orderMapper.getOrderIds();
    integerBloomFilter = BloomFilter.create(Funnels.integerFunnel(), orderIds.size(), 0.01);
    for (int i = 0; i < orderIds.size(); i++) {
        integerBloomFilter.put(orderIds.get(i));
    }
    return "success";
}

讀到這里,這篇“Redis安全策略實例分析”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI