最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis之BigKey與HotKey問題詳解

 更新時間:2026年02月28日 09:19:25   作者:d3y1  
在Redis的實際使用過程中,BigKey和 HotKey是兩個常見且可能導(dǎo)致嚴重性能問題的問題,它們可能導(dǎo)致 Redis 實例響應(yīng)變慢、內(nèi)存使用不均、甚至服務(wù)不可用,下面就來介紹一下這兩個的問題

概述

在 Redis 的實際使用過程中,BigKey(大鍵)和 HotKey(熱鍵)是兩個常見且可能導(dǎo)致嚴重性能問題的問題。它們可能導(dǎo)致 Redis 實例響應(yīng)變慢、內(nèi)存使用不均、甚至服務(wù)不可用。

BigKey 指的是單個鍵值對占用內(nèi)存過大的情況。

HotKey 指的是某個鍵的訪問頻率遠高于其他鍵的情況。

這兩個問題往往同時出現(xiàn),相互影響,需要系統(tǒng)性地進行預(yù)防和處理。

BigKey 問題

什么是 BigKey

BigKey 是指單個鍵值對占用內(nèi)存過大的鍵。Redis 官方建議:

  • String 類型:單個 value 不超過 10KB
  • Hash、List、Set、ZSet 類型:元素個數(shù)不超過 5000

超過這些閾值的鍵可以被視為 BigKey。

BigKey 的危害

1. 內(nèi)存占用不均

BigKey 會占用大量內(nèi)存,可能導(dǎo)致 Redis 實例內(nèi)存使用不均衡。在 Redis Cluster 中,這會導(dǎo)致某些節(jié)點的內(nèi)存使用率遠高于其他節(jié)點,引發(fā)內(nèi)存傾斜。

2. 阻塞主線程

Redis 是單線程模型,BigKey 的操作會阻塞主線程:

操作影響說明
DEL刪除大鍵會阻塞主線程,時間復(fù)雜度 O(N)
HGETALL獲取所有字段會阻塞主線程
LRANGE大范圍獲取列表元素會阻塞
KEYS遍歷所有鍵會嚴重阻塞
FLUSHDB/FLUSHALL清空數(shù)據(jù)庫會長時間阻塞

3. 網(wǎng)絡(luò)帶寬消耗

BigKey 的讀寫操作會消耗大量網(wǎng)絡(luò)帶寬,影響其他請求的響應(yīng)速度。

4. 持久化問題

  • RDB:生成 RDB 文件時,BigKey 會導(dǎo)致 fork 子進程時內(nèi)存占用翻倍
  • AOF:BigKey 的寫入會導(dǎo)致 AOF 文件膨脹,重寫時耗時較長

5. 主從同步延遲

BigKey 的同步會導(dǎo)致主從復(fù)制延遲增加,影響數(shù)據(jù)一致性。

BigKey 的檢測

1. 使用 redis-cli --bigkeys

Redis 自帶的 --bigkeys 命令可以掃描并統(tǒng)計大鍵:

redis-cli --bigkeys -i 0.1

參數(shù)說明:

  • -i 0.1:每次掃描間隔 0.1 秒,避免阻塞

輸出示例:

-------- summary -------
Sampled 506 keys in the keyspace!
Total key length in bytes is 1885 (avg len 3.73)

Biggest string found 'user:1001:profile' has 10240 bytes
Biggest   list found 'order:queue' has 10003 items
Biggest    set found 'online:users' has 8005 items
Biggest   hash found 'product:info' has 5012 fields

506 keys with 506 types

2. 使用 SCAN 命令

編寫腳本使用 SCAN 命令遍歷所有鍵并檢查大?。?/p>

#!/bin/bash
redis-cli --scan --pattern "*" | while read key; do
    size=$(redis-cli memory usage "$key")
    if [ $size -gt 10240 ]; then
        echo "BigKey: $key, Size: $size bytes"
    fi
done

3. 使用 MEMORY USAGE 命令

redis-cli memory usage your_key

4. 使用 Redis 慢查詢?nèi)罩?/h4>

配置慢查詢閾值:

redis-cli config set slowlog-log-slower-than 10000  # 10ms
redis-cli slowlog get 10

5. 使用 Redis 模塊

  • Redis Modules:如 RedisJSON、RedisTimeSeries 等模塊提供更詳細的內(nèi)存分析
  • Redis Insight:官方可視化工具,可以查看內(nèi)存分布

BigKey 的解決方案

1. 拆分 BigKey

Hash 拆分示例

原始結(jié)構(gòu):

user:1001:info -> {name: "張三", age: 30, address: "...", ...} (5000+ fields)

拆分后:

user:1001:info:base -> {name: "張三", age: 30}
user:1001:info:contact -> {phone: "...", email: "..."}
user:1001:info:address -> {province: "...", city: "..."}

List 拆分示例

原始結(jié)構(gòu):

order:queue -> [order1, order2, ..., order10000]

拆分后:

order:queue:0 -> [order1, ..., order1000]
order:queue:1 -> [order1001, ..., order2000]
...
order:queue:9 -> [order9001, ..., order10000]

2. 使用合適的數(shù)據(jù)結(jié)構(gòu)

場景推薦數(shù)據(jù)結(jié)構(gòu)避免使用
簡單鍵值對StringHash (少量字段時)
對象屬性HashString (JSON)
去重集合SetList
排序集合ZSetSet + 排序
計數(shù)器String (INCR)Hash

3. 壓縮數(shù)據(jù)

  • 使用更緊湊的序列化格式(如 MessagePack、Protobuf)
  • 對 String 類型的值進行壓縮
  • 使用 Hash 的 ziplist 編碼(元素較少時)

4. 異步刪除 BigKey

使用 UNLINK 命令替代 DEL

redis-cli unlink your_big_key

UNLINK 會在后臺線程中刪除鍵,不會阻塞主線程。

5. 分批次操作

對于大集合的操作,分批次進行:

# 原始方式(會阻塞)
redis.hgetall("big_hash")

# 改進方式(分批次)
cursor = 0
while True:
    cursor, data = redis.hscan("big_hash", cursor, count=100)
    process(data)
    if cursor == 0:
        break

6. 設(shè)置過期時間

為 BigKey 設(shè)置合理的過期時間,避免數(shù)據(jù)無限累積:

redis-cli expire your_key 3600

HotKey 問題

什么是 HotKey

HotKey 是指某個鍵的訪問頻率遠高于其他鍵的鍵。通常表現(xiàn)為:

  • 某個鍵的 QPS 遠超其他鍵
  • 某個鍵的讀寫請求集中在短時間內(nèi)爆發(fā)
  • 某個鍵的訪問量占整個 Redis 實例的很大比例

HotKey 的危害

1. CPU 負載不均

在 Redis Cluster 中,HotKey 所在節(jié)點的 CPU 負載會遠高于其他節(jié)點:

節(jié)點 A: CPU 95% (包含 HotKey)
節(jié)點 B: CPU 20%
節(jié)點 C: CPU 15%

2. 網(wǎng)絡(luò)帶寬瓶頸

HotKey 的高頻訪問會消耗大量網(wǎng)絡(luò)帶寬,影響其他請求。

3. 緩存擊穿

當 HotKey 過期時,大量請求會同時穿透到后端數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫壓力驟增。

4. 請求堆積

由于 Redis 是單線程,HotKey 的處理會導(dǎo)致其他請求排隊等待。

5. 主從同步壓力

HotKey 的頻繁更新會增加主從同步的負擔。

HotKey 的檢測

1. 使用 Redis INFO 命令

redis-cli info stats

關(guān)注 keyspace_hitskeyspace_misses 指標。

2. 使用 MONITOR 命令(謹慎使用)

redis-cli monitor | grep "your_key"

注意MONITOR 會嚴重影響性能,僅用于調(diào)試,不要在生產(chǎn)環(huán)境使用。

3. 使用 Redis 慢查詢?nèi)罩?/h4>
redis-cli config set slowlog-log-slower-than 0
redis-cli slowlog get 100

4. 使用客戶端統(tǒng)計

在應(yīng)用層記錄每個鍵的訪問頻率:

from collections import defaultdict

access_stats = defaultdict(int)

def get_redis(key):
    access_stats[key] += 1
    return redis.get(key)

# 定期打印統(tǒng)計
def print_stats():
    for key, count in sorted(access_stats.items(), key=lambda x: x[1], reverse=True)[:10]:
        print(f"{key}: {count}")

5. 使用 Redis 4.0+ 的 LFU 淘汰策略

配置 LFU(Least Frequently Used)淘汰策略:

redis-cli config set maxmemory-policy allkeys-lfu

然后使用 OBJECT FREQ 命令查看訪問頻率:

redis-cli object freq your_key

6. 使用第三方工具

  • Redis Exporter + Prometheus + Grafana:監(jiān)控 Redis 指標
  • 阿里云 Redis:提供 HotKey 分析功能
  • 騰訊云 Redis:提供熱 Key 監(jiān)控

HotKey 的解決方案

1. 本地緩存

在應(yīng)用層使用本地緩存(如 Guava Cache、Caffeine)緩存 HotKey:

// 使用 Caffeine 本地緩存
Cache<String, String> localCache = Caffeine.newBuilder()
    .maximumSize(1000)
    .expireAfterWrite(1, TimeUnit.MINUTES)
    .build();

public String get(String key) {
    // 先查本地緩存
    String value = localCache.getIfPresent(key);
    if (value != null) {
        return value;
    }
    // 再查 Redis
    value = redis.get(key);
    if (value != null) {
        localCache.put(key, value);
    }
    return value;
}

2. 讀寫分離

對于讀多寫少的 HotKey,使用讀寫分離:

應(yīng)用 -> 讀請求 -> Redis 從節(jié)點
應(yīng)用 -> 寫請求 -> Redis 主節(jié)點

3. Key 分片

將 HotKey 拆分成多個 Key:

原始方式

hot_product:1001 -> 商品信息

分片方式

hot_product:1001:0 -> 商品信息
hot_product:1001:1 -> 商品信息(副本)
hot_product:1001:2 -> 商品信息(副本)

訪問時隨機選擇一個分片:

import random

def get_hot_product(product_id):
    shard = random.randint(0, 2)
    return redis.get(f"hot_product:{product_id}:{shard}")

4. 備份 Key

為 HotKey 創(chuàng)建多個備份,分散請求:

# 寫入時同步更新所有備份
def set_hot_key(key, value):
    pipe = redis.pipeline()
    for i in range(3):
        pipe.set(f"{key}:backup:{i}", value)
    pipe.execute()

# 讀取時隨機選擇一個備份
def get_hot_key(key):
    backup = random.randint(0, 2)
    return redis.get(f"{key}:backup:{backup}")

5. 使用 Redis Cluster

在 Redis Cluster 中,HotKey 會分散到不同的節(jié)點,但需要注意:

  • 確保數(shù)據(jù)分片均勻
  • 避免使用 Hash Tag 導(dǎo)致數(shù)據(jù)集中

Hash Tag 示例(會導(dǎo)致數(shù)據(jù)集中):

user:{1001}:profile
user:{1001}:orders
user:{1001}:cart

這些鍵會被分配到同一個節(jié)點。

6. 限流保護

對 HotKey 的訪問進行限流:

from functools import wraps
import time

class RateLimiter:
    def __init__(self, max_calls, period):
        self.max_calls = max_calls
        self.period = period
        self.calls = {}
    
    def allow(self, key):
        now = time.time()
        if key not in self.calls:
            self.calls[key] = []
        # 清理過期記錄
        self.calls[key] = [t for t in self.calls[key] if now - t < self.period]
        if len(self.calls[key]) >= self.max_calls:
            return False
        self.calls[key].append(now)
        return True

limiter = RateLimiter(max_calls=1000, period=1)  # 每秒最多 1000 次

def rate_limit(func):
    @wraps(func)
    def wrapper(key, *args, **kwargs):
        if not limiter.allow(key):
            raise Exception("Rate limit exceeded")
        return func(key, *args, **kwargs)
    return wrapper

@rate_limit
def get_hot_key(key):
    return redis.get(key)

7. 緩存預(yù)熱

在系統(tǒng)啟動或低峰期,提前加載 HotKey 到緩存:

def warm_up_cache():
    hot_keys = get_hot_keys_from_db()  # 從數(shù)據(jù)庫獲取熱點鍵列表
    for key in hot_keys:
        value = db.get(key)
        redis.set(key, value, ex=3600)

8. 使用多級緩存

構(gòu)建多級緩存架構(gòu):

應(yīng)用 -> 本地緩存 -> Redis -> 數(shù)據(jù)庫

9. 消息隊列削峰

對于寫請求較多的 HotKey,使用消息隊列削峰:

應(yīng)用 -> 消息隊列 -> 消費者 -> Redis

最佳實踐

1. 設(shè)計階段

  • 合理設(shè)計 Key 的命名和結(jié)構(gòu):避免產(chǎn)生 BigKey
  • 預(yù)估數(shù)據(jù)量:提前規(guī)劃數(shù)據(jù)規(guī)模,選擇合適的數(shù)據(jù)結(jié)構(gòu)
  • 設(shè)置過期時間:為所有 Key 設(shè)置合理的過期時間

2. 開發(fā)階段

  • 使用 Pipeline:批量操作減少網(wǎng)絡(luò)開銷
  • 避免使用 KEYS:使用 SCAN 替代 KEYS
  • 監(jiān)控 Key 大小:定期檢查是否有 BigKey 產(chǎn)生

3. 運維階段

  • 定期巡檢:使用工具定期檢查 BigKey 和 HotKey
  • 設(shè)置告警:對內(nèi)存使用、慢查詢等指標設(shè)置告警
  • 容量規(guī)劃:根據(jù)業(yè)務(wù)增長提前規(guī)劃容量

4. 應(yīng)急處理

  • 緊急擴容:當發(fā)現(xiàn)問題時,及時擴容
  • 限流降級:對異常請求進行限流和降級
  • 數(shù)據(jù)遷移:將 BigKey 遷移到獨立實例

工具推薦

1. Redis 官方工具

工具用途
redis-cli --bigkeys檢測 BigKey
redis-cli --memkeys檢測占用內(nèi)存最多的鍵
redis-cli --hotkeys檢測 HotKey(LFU 模式下)
Redis Insight可視化管理工具

2. 第三方工具

工具特點
redis-rdb-tools分析 RDB 文件,找出 BigKey
redis-faina分析 MONITOR 輸出,統(tǒng)計訪問頻率
Redis ExporterPrometheus 指標導(dǎo)出器
Redis CommanderWeb 管理界面
MedisMac 平臺的 Redis 客戶端

3. 云服務(wù)

  • 阿里云 Redis:提供 BigKey 和 HotKey 分析
  • 騰訊云 Redis:提供熱 Key 監(jiān)控
  • AWS ElastiCache:提供 CloudWatch 監(jiān)控

總結(jié)

BigKey 和 HotKey 是 Redis 使用中的常見問題,但通過合理的設(shè)計、有效的監(jiān)控和及時的優(yōu)化,可以很好地避免和解決這些問題。

核心要點

  1. 預(yù)防為主:在設(shè)計階段就考慮避免 BigKey 和 HotKey
  2. 定期巡檢:使用工具定期檢查,及時發(fā)現(xiàn)問題
  3. 合理拆分:對 BigKey 進行拆分,對 HotKey 進行分散
  4. 多級緩存:構(gòu)建多級緩存架構(gòu),減輕 Redis 壓力
  5. 監(jiān)控告警:建立完善的監(jiān)控和告警機制

到此這篇關(guān)于Redis之BigKey與HotKey問題詳解的文章就介紹到這了,更多相關(guān)Redis BigKey與HotKey內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于linux redis安裝及安裝遇到的問題

    關(guān)于linux redis安裝及安裝遇到的問題

    這篇文章主要介紹了關(guān)于linux redis安裝及安裝遇到的問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 基于Redis的3種分布式ID生成策略

    基于Redis的3種分布式ID生成策略

    在分布式系統(tǒng)設(shè)計中,全局唯一ID是一個基礎(chǔ)而關(guān)鍵的組件,隨著業(yè)務(wù)規(guī)模擴大和系統(tǒng)架構(gòu)向微服務(wù)演進,傳統(tǒng)的單機自增ID已無法滿足需求,高并發(fā)、高可用的分布式ID生成方案成為構(gòu)建可靠分布式系統(tǒng)的必要條件,
    2025-08-08
  • Redis Hash沖突的10種解決方法

    Redis Hash沖突的10種解決方法

    在高并發(fā)的分布式系統(tǒng)中,Redis的Hash表(如Hash類型、數(shù)據(jù)庫鍵空間)是核心數(shù)據(jù)結(jié)構(gòu),但當多個鍵的哈希值沖突時,性能可能驟降——這是開發(fā)者必須直面的挑戰(zhàn),本文將深入Redis源碼邏輯,給大家介紹了Redis Hash沖突的10種解決方法,需要的朋友可以參考下
    2025-08-08
  • Redis事務(wù)機制與Springboot項目中的使用方式

    Redis事務(wù)機制與Springboot項目中的使用方式

    Redis事務(wù)機制允許將多個命令打包在一起,作為一個原子操作來執(zhí)行,開啟事務(wù)使用MULTI命令,執(zhí)行事務(wù)使用EXEC命令,取消事務(wù)使用DISCARD命令,監(jiān)視一個或多個鍵使用WATCH命令,Redis事務(wù)的核心思想是將多個命令放入一個隊列中
    2025-03-03
  • Redis筆記點贊排行榜的實現(xiàn)示例

    Redis筆記點贊排行榜的實現(xiàn)示例

    探店筆記類似點評網(wǎng)站的評價,本文主要介紹了Redis筆記點贊排行榜的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • redis服務(wù)如何啟動

    redis服務(wù)如何啟動

    這篇文章主要介紹了redis服務(wù)如何啟動問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Redis哨兵模式在Spring Boot項目中的使用與實踐完全指南

    Redis哨兵模式在Spring Boot項目中的使用與實踐完全指南

    Redis哨兵模式為SpringBoot項目提供高可用Redis管理,實現(xiàn)自動故障轉(zhuǎn)移與監(jiān)控,通過配置依賴、參數(shù)及最佳實踐(如哨兵節(jié)點數(shù)量、網(wǎng)絡(luò)規(guī)劃),可提升系統(tǒng)穩(wěn)定性與可靠性,本文給大家介紹Redis哨兵模式在Spring Boot項目中的使用與實踐,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • redis-cli -p 6379 info命令詳解

    redis-cli -p 6379 info命令詳解

    這篇文章主要介紹了redis-cli -p 6379 info命令詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Redis批量刪除Key的三種方式小結(jié)

    Redis批量刪除Key的三種方式小結(jié)

    本文主要介紹了Redis批量刪除Key的三種方式小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 解決redis修改requirepass后不生效的問題

    解決redis修改requirepass后不生效的問題

    今天小編就為大家分享一篇解決redis修改requirepass后不生效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05

最新評論

新丰县| 莒南县| 汉中市| 太仆寺旗| 原平市| 裕民县| 沂水县| 木里| 高安市| 丰宁| 孝感市| 抚松县| 安龙县| 怀安县| 罗源县| 黔西县| 高阳县| 时尚| 黑龙江省| 扎囊县| 子洲县| 客服| 邵武市| 利川市| 会同县| 罗定市| 武定县| 永平县| 徐水县| 和田县| 文昌市| 博兴县| 望江县| 昌吉市| 辰溪县| 黄平县| 黑龙江省| 克什克腾旗| 鲜城| 涪陵区| 通榆县|