溫馨提示×

溫馨提示×

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

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

Redis緩存穿透、緩存擊穿、緩存雪崩、熱點Key的示例分析

發布時間:2021-12-20 10:44:50 來源:億速云 閱讀:183 作者:小新 欄目:大數據
# Redis緩存穿透、緩存擊穿、緩存雪崩、熱點Key的示例分析

## 一、緩存穿透(Cache Penetration)

### 1.1 概念與場景
緩存穿透指**查詢不存在的數據**,導致請求直接穿透緩存層到達數據庫。常見場景:
- 惡意攻擊:故意請求不存在的ID(如負值、超大數值)
- 業務誤操作:前端傳遞無效參數(如已刪除的商品ID)

### 1.2 示例代碼
```java
// 錯誤示例:未做空值校驗
public Product getProduct(Long id) {
    // 1. 先查緩存
    Product product = redisTemplate.opsForValue().get("product:" + id);
    if (product == null) {
        // 2. 緩存未命中,直接查庫
        product = productMapper.selectById(id); // 可能返回null
        redisTemplate.opsForValue().set("product:" + id, product);
    }
    return product;
}

1.3 解決方案

  1. 空值緩存:對不存在的數據也緩存空對象(需設置較短TTL)
// 改進代碼
if (product == null) {
    product = productMapper.selectById(id);
    if (product == null) {
        redisTemplate.opsForValue().set("product:" + id, "NULL", 5, TimeUnit.MINUTES);
        return null;
    }
    redisTemplate.opsForValue().set("product:" + id, product);
}
  1. 布隆過濾器:預加載有效Key到布隆過濾器,先校驗再查詢
# Python示例
from pybloom_live import ScalableBloomFilter
bf = ScalableBloomFilter(initial_capacity=1000)

# 預熱階段加載所有有效ID
for id in valid_ids:
    bf.add(id)

# 查詢前校驗
if not id in bf:
    return None

二、緩存擊穿(Cache Breakdown)

2.1 概念與場景

某個熱點Key突然過期時,大量并發請求直接擊穿到數據庫。典型場景: - 秒殺商品緩存過期 - 首頁熱門資訊緩存失效

2.2 示例現象

  • 監控顯示QPS突然飆升
  • 數據庫CPU占用率陡增
  • 響應時間從毫秒級升至秒級

2.3 解決方案

  1. 互斥鎖(Mutex Lock)
public Product getProductWithLock(Long id) {
    String lockKey = "lock:product:" + id;
    try {
        // 嘗試獲取分布式鎖
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
        if (locked) {
            Product product = productMapper.selectById(id);
            redisTemplate.opsForValue().set("product:" + id, product, 1, TimeUnit.HOURS);
            return product;
        } else {
            Thread.sleep(100); // 短暫等待后重試
            return getProductWithLock(id);
        }
    } finally {
        redisTemplate.delete(lockKey);
    }
}
  1. 邏輯過期:實際緩存永不過期,通過額外字段控制邏輯過期時間
// 緩存數據結構
{
  "value": "真實數據",
  "expire_time": 1672502400 // 邏輯過期時間戳
}

三、緩存雪崩(Cache Avalanche)

3.1 概念與場景

大量Key同時過期或Redis集群宕機,導致請求全部涌向數據庫。典型案例: - 凌晨批量任務刷新所有緩存 - Redis主從切換期間

3.2 解決方案

  1. 差異化過期時間
// 設置基礎過期時間+隨機偏移量
int baseExpire = 3600;
int randomExpire = new Random().nextInt(300);
redisTemplate.opsForValue().set(key, value, baseExpire + randomExpire, TimeUnit.SECONDS);
  1. 多級緩存架構
請求 → CDN → 本地緩存(Caffeine) → Redis → DB
  1. 熔斷降級機制
# 偽代碼示例
def get_data(key):
    if circuit_breaker.is_open():
        return get_data_from_backup()
    try:
        data = redis.get(key)
        if not data:
            data = db.query(key)
            redis.setex(key, ttl, data)
        return data
    except Exception as e:
        circuit_breaker.record_failure()
        raise e

四、熱點Key(Hot Key)

4.1 識別方法

  • 監控發現某些Key的QPS異常高(如>10萬/秒)
  • Redis節點出現CPU負載傾斜

4.2 解決方案

  1. 本地緩存+Redis多副本
// Guava本地緩存
LoadingCache<String, Product> localCache = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .expireAfterWrite(10, TimeUnit.SECONDS)
    .build(new CacheLoader<String, Product>() {
        @Override
        public Product load(String key) {
            return getFromRedis(key); // 從Redis集群讀取
        }
    });
  1. Key分片
# 將hot_key拆分為hot_key_1, hot_key_2...
shard_id = hash(user_id) % 4
real_key = f"hot_key_{shard_id}"
redis.get(real_key)

五、總結對比

問題類型 核心特征 典型解決方案
緩存穿透 查詢不存在數據 布隆過濾器、空值緩存
緩存擊穿 單熱點Key失效 互斥鎖、邏輯過期
緩存雪崩 大量Key同時失效 差異化TTL、多級緩存
熱點Key 單Key訪問量極高 本地緩存、Key分片

實際生產環境中,建議結合監控系統(如Prometheus)和動態配置中心實現策略的實時調整。 “`

向AI問一下細節

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

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女