Redis 大 Key 與熱 Key:生產環境的風險與解決方案

🔥 Redis 大 Key 與熱 Key:生產環境的風險與解決方案

文章目錄

  • 🔥 Redis 大 Key 與熱 Key:生產環境的風險與解決方案
  • 🧠 一、問題定義與識別
    • 💡 什么是大 Key?
    • 🔥 什么是熱 Key?
    • 📊 大 Key 與熱 Key 對比
  • ?? 二、風險深度分析
    • 💥 大 Key 的風險與影響
    • 🔥 熱 Key 的風險與影響
    • 📈 綜合影響分析
  • 🔍 三、定位與診斷方法
    • 🛠? 內置工具診斷
    • 📊 熱 Key 診斷方法
    • 🔧 第三方工具集成
  • 🛠? 四、解決方案與實戰
    • 🔨 大 Key 解決方案
    • 🔥 熱 Key 解決方案
    • 🛡? 綜合防護方案
  • 💡 五、最佳實踐與預防
    • 📋 日常監控預防策略
    • 🏗? 架構優化建議
    • 📊 性能對比評估
    • 🚀 全鏈路優化體系

🧠 一、問題定義與識別

💡 什么是大 Key?

??大 Key(Big Key)?? 是指存儲值過大的 Redis Key,通常有以下特征:

45%25%20%10%大 Key 類型分布String大ValueHash大FieldList/Set元素過多ZSet元素過多

??大 Key 判斷標準??:

# 大Key的量化標準
String類型:value > 10KB
Hash/Set/ZSet類型:元素數量 > 1000
List類型:元素數量 > 1000
所有類型:整體大小 > 1MB

🔥 什么是熱 Key?

??熱 Key(Hot Key)?? 是指訪問頻率異常高的 Key,通常具有以下特征:

熱Key特征
QPS異常高
集中訪問
單節點壓力
容易成為瓶頸
通常QPS > 1000
80%請求集中在20%的Key
導致數據傾斜
可能引發雪崩

??熱 Key 判斷標準??:

# 熱Key的量化標準
單個Key的QPS > 1000
占用總請求量的 > 5%
導致節點負載比其他節點高50%+

📊 大 Key 與熱 Key 對比

特征大 Key (Big Key)熱 Key (Hot Key)
定義Value尺寸過大訪問頻率過高
問題本質數據存儲問題數據訪問問題
主要影響阻塞、網絡延遲性能瓶頸、數據傾斜
檢測方式內存分析、掃描監控、流量分析
解決方案數據拆分、壓縮多級緩存、分片

?? 二、風險深度分析

💥 大 Key 的風險與影響

??1. 阻塞風險??:

sequenceDiagramparticipant C as Clientparticipant R as Redisparticipant N as NetworkC->>R: 發送大Key操作請求R->>R: 處理大量數據(阻塞)Note over R: 單線程阻塞其他命令R->>N: 傳輸大數據量N->>C: 響應延遲高style R fill:#f99,stroke:#333

??2. 網絡壓力??:

# 示例:一個10MB的Key
# 每秒100次訪問產生的網絡流量
10MB * 100 = 1000MB/s = 8Gbps
# 這可能會占滿萬兆網卡!

??3. 內存不均??:

# 內存分布示例
Node1: 10GB (包含8GB的大Key)
Node2: 2GB
Node3: 2GB
# 導致節點負載嚴重不均衡

??4. 持久化問題??:

// BGSAVE時fork操作可能阻塞
// 如果一個大Key占用了8GB內存
// fork需要復制8GB內存頁表,可能導致長時間阻塞

🔥 熱 Key 的風險與影響

??1. 單點瓶頸??:

客戶端1
Redis節點
客戶端2
客戶端3
客戶端4
客戶端5
熱Key

??2. 數據傾斜??:

# 集群環境下的數據傾斜
節點1: QPS 50,000 (包含熱Key)
節點2: QPS 800
節點3: QPS 750
節點4: QPS 700
# 一個熱Key導致整個集群負載不均

??3. 緩存擊穿??:

// 熱Key過期時的大量并發請求
public Object getHotKey(String key) {Object value = redis.get(key);if (value == null) {// 大量請求同時到達數據庫value = loadFromDB(key);redis.setex(key, 300, value);}return value;
}

??4. 資源競爭??:

# CPU競爭:處理熱Key的線程占用大量CPU
# 網絡競爭:熱Key的網絡流量擠占其他請求
# 連接競爭:大量客戶端連接等待同一個Key

📈 綜合影響分析

大Key
阻塞延遲
網絡擁塞
內存壓力
熱Key
單點瓶頸
數據傾斜
緩存擊穿
系統不穩定
業務故障

🔍 三、定位與診斷方法

🛠? 內置工具診斷

??1. redis-cli --bigkeys 分析??:

# 執行大Key分析
redis-cli --bigkeys# 輸出示例:
# Biggest string found so far 'big:string:key' with 10240000 bytes
# Biggest hash found so far 'big:hash:key' with 100000 fields
# Biggest list found so far 'big:list:key' with 50000 items
# Biggest set found so far 'big:set:key' with 80000 members
# Biggest zset found so far 'big:zset:key' with 60000 members# 定期執行分析腳本
#!/bin/bash
echo "開始大Key分析: $(date)"
redis-cli --bigkeys -i 0.1 | grep -E "(Biggest|bytes|fields|items|members)"
echo "分析完成: $(date)"

??2. memory usage 命令??:

# 精確查詢Key的內存使用
redis-cli memory usage user:profile:1234# 批量采樣分析
for key in $(redis-cli keys "user:profile:*" | head -100); dosize=$(redis-cli memory usage $key)echo "$key: $size bytes"
done | sort -n -k2 -r | head -10

??3. monitor 命令抓包??:

# 實時監控命令請求
redis-cli monitor | grep -E "(GET|HGET|SMEMBERS|LRANGE)" | head -1000# 分析命令頻率
redis-cli monitor | awk '{print $4}' | sort | uniq -c | sort -nr | head -10

📊 熱 Key 診斷方法

??1. 實時流量分析??:

# 使用monitor統計熱Key
redis-cli monitor | awk '
BEGIN { count=0 }
{if ($4 ~ /"(GET|HGET|SMEMBERS|LRANGE)"/) {key = $5;keys[key]++;count++;}if (count > 10000) exit;
}
END {for (key in keys) {print keys[key], key;}
}' | sort -nr | head -20

??2. Lua 腳本統計??:

-- 熱Key統計腳本
local function track_hot_keys()local key = KEYS[1]local now = tonumber(ARGV[1])local window = 60 -- 統計窗口60秒-- 使用有序集合統計熱度redis.call('ZADD', 'hotkey:tracking', now, key)redis.call('ZREMRANGEBYSCORE', 'hotkey:tracking', 0, now - window)local count = redis.call('ZCARD', 'hotkey:tracking')if count > 1000 thenredis.log(redis.LOG_WARNING, "熱Key detected: " .. key)end
end

🔧 第三方工具集成

??1. Prometheus + Redis Exporter??:

# docker-compose.yml 監控棧
version: '3'
services:redis-exporter:image: oliver006/redis_exporterports:- "9121:9121"environment:- REDIS_ADDR=redis://redis:6379command:- '--redis.addr=redis://redis:6379'- '--redis.password=${REDIS_PASSWORD}'prometheus:image: prom/prometheusports:- "9090:9090"volumes:- ./prometheus.yml:/etc/prometheus/prometheus.ymlgrafana:image: grafana/grafanaports:- "3000:3000"

??2. 自定義監控腳本??:

#!/usr/bin/env python3
# hotkey_detector.py
import redis
import time
from collections import defaultdictclass HotKeyDetector:def __init__(self, host='localhost', port=6379):self.r = redis.Redis(host=host, port=port)self.key_stats = defaultdict(int)self.start_time = time.time()def monitor_keys(self, duration=60):"""監控指定時間內的Key訪問"""end_time = time.time() + durationpubsub = self.r.pubsub()pubsub.psubscribe('__keyspace@0__:*')for message in pubsub.listen():if time.time() > end_time:breakif message['type'] == 'pmessage':key = message['channel'].split(':', 1)[1]self.key_stats[key] += 1# 輸出熱Key報告self.generate_report()def generate_report(self):"""生成熱Key報告"""total_ops = sum(self.key_stats.values())print(f"監控時間: {time.time() - self.start_time:.2f}秒")print(f"總操作數: {total_ops}")print("熱Key排名TOP10:")for key, count in sorted(self.key_stats.items(), key=lambda x: x[1], reverse=True)[:10]:percentage = (count / total_ops) * 100print(f"  {key}: {count}次 ({percentage:.2f}%)")if __name__ == "__main__":detector = HotKeyDetector()detector.monitor_keys(300)  # 監控5分鐘

🛠? 四、解決方案與實戰

🔨 大 Key 解決方案

??1. 數據拆分??:

// 原始大Hash拆分示例
public class BigHashSplitter {// 原始大Keypublic void saveUserProfile(String userId, Map<String, String> profile) {// 反例:所有數據存到一個Hashjedis.hmset("user:profile:" + userId, profile);}// 拆分方案:按業務維度拆分public void saveUserProfileSplit(String userId, Map<String, String> profile) {// 基礎信息Map<String, String> basicInfo = new HashMap<>();basicInfo.put("name", profile.get("name"));basicInfo.put("email", profile.get("email"));jedis.hmset("user:basic:" + userId, basicInfo);// 擴展信息Map<String, String> extendedInfo = new HashMap<>();extendedInfo.put("address", profile.get("address"));extendedInfo.put("preferences", profile.get("preferences"));jedis.hmset("user:extended:" + userId, extendedInfo);// 統計信息Map<String, String> statsInfo = new HashMap<>();statsInfo.put("login_count", profile.get("login_count"));statsInfo.put("last_login", profile.get("last_login"));jedis.hmset("user:stats:" + userId, statsInfo);}
}

??2. 數據壓縮??:

// 數據壓縮方案
public class DataCompressor {public void saveCompressedData(String key, Object data) {try {// 序列化數據byte[] serialized = serialize(data);// 使用GZIP壓縮ByteArrayOutputStream baos = new ByteArrayOutputStream();GZIPOutputStream gzip = new GZIPOutputStream(baos);gzip.write(serialized);gzip.close();byte[] compressed = baos.toByteArray();// 存儲壓縮數據jedis.set(key.getBytes(), compressed);} catch (IOException e) {throw new RuntimeException("壓縮失敗", e);}}public Object getCompressedData(String key) {byte[] compressed = jedis.get(key.getBytes());if (compressed == null) return null;try {// 解壓數據GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(compressed));ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len;while ((len = gzip.read(buffer)) > 0) {baos.write(buffer, 0, len);}gzip.close();byte[] serialized = baos.toByteArray();return deserialize(serialized);} catch (IOException e) {throw new RuntimeException("解壓失敗", e);}}
}

??3. 數據歸檔??:

// 冷熱數據分離方案
public class DataArchiver {public Object getData(String key) {// 首先從Redis查詢Object data = jedis.get(key);if (data != null) {return data;}// Redis中沒有,從歸檔存儲查詢data = archiveStorage.get(key);if (data != null) {// 異步回填Redis(短期緩存)jedis.setex(key, 3600, serialize(data)); // 緩存1小時}return data;}public void archiveOldData() {// 定期將舊數據遷移到歸檔存儲Set<String> oldKeys = findOldKeys();for (String key : oldKeys) {Object data = jedis.get(key);if (data != null) {archiveStorage.put(key, data);jedis.del(key);}}}
}

🔥 熱 Key 解決方案

??1. 本地緩存 + 刷新策略??:

public class HotKeyCache {private final LoadingCache<String, Object> localCache;private final Jedis jedis;public HotKeyCache() {this.localCache = Caffeine.newBuilder().maximumSize(1000).expireAfterWrite(5, TimeUnit.SECONDS) // 短期緩存.refreshAfterWrite(1, TimeUnit.SECONDS) // 主動刷新.build(this::loadFromRedis);}public Object get(String key) {try {return localCache.get(key);} catch (Exception e) {return loadFromRedis(key);}}private Object loadFromRedis(String key) {return jedis.get(key);}
}

??2. 多副本分散??:

// 熱Key多副本方案
public class HotKeyReplication {private static final int REPLICA_COUNT = 5;public void set(String key, Object value) {// 主副本jedis.set(key, serialize(value));// 創建多個副本for (int i = 1; i <= REPLICA_COUNT; i++) {String replicaKey = key + ":replica:" + i;jedis.set(replicaKey, serialize(value));jedis.expire(replicaKey, 3600); // 設置過期時間}}public Object get(String key) {// 隨機選擇副本int replicaNum = ThreadLocalRandom.current().nextInt(1, REPLICA_COUNT + 1);String replicaKey = key + ":replica:" + replicaNum;Object value = jedis.get(replicaKey);if (value == null) {// 副本不存在,回退到主Keyvalue = jedis.get(key);if (value != null) {// 重建副本set(key, value);}}return value;}
}

??3. 代理層分片??:

// 基于代理的熱Key分片
public class HotKeyProxy {private List<Jedis> redisNodes;private int nodeCount;public HotKeyProxy(List<Jedis> nodes) {this.redisNodes = nodes;this.nodeCount = nodes.size();}public void set(String key, Object value) {// 寫入所有節點for (Jedis node : redisNodes) {node.set(key, serialize(value));}}public Object get(String key) {// 根據Key哈希選擇節點int nodeIndex = Math.abs(key.hashCode()) % nodeCount;return redisNodes.get(nodeIndex).get(key);}// 特別熱門的Key:在所有節點都存儲public void setHotKey(String key, Object value) {for (Jedis node : redisNodes) {node.set(key, serialize(value));}}public Object getHotKey(String key) {// 隨機選擇節點,分散壓力int randomNode = ThreadLocalRandom.current().nextInt(nodeCount);return redisNodes.get(randomNode).get(key);}
}

🛡? 綜合防護方案

??多級緩存架構??:

緩存命中
負載均衡
緩存擊穿
客戶端
本地緩存
代理層
Redis集群
數據庫

??降級策略??:

public class CircuitBreaker {private final CircuitBreakerConfig config;private int failureCount = 0;private long lastFailureTime = 0;public Object getWithCircuitBreaker(String key) {if (isOpen()) {// 熔斷狀態:直接返回降級結果return getFallbackValue(key);}try {Object value = jedis.get(key);reset(); // 成功則重置熔斷器return value;} catch (Exception e) {recordFailure();return getFallbackValue(key);}}private boolean isOpen() {if (failureCount >= config.getThreshold()) {long now = System.currentTimeMillis();if (now - lastFailureTime < config.getTimeout()) {return true;}// 超時后嘗試半開reset();}return false;}private void recordFailure() {failureCount++;lastFailureTime = System.currentTimeMillis();}private void reset() {failureCount = 0;}
}

💡 五、最佳實踐與預防

📋 日常監控預防策略

??1. 定期健康檢查??:

#!/bin/bash
# daily_redis_check.sh# 1.Key檢查
echo "=== 大Key檢查 ==="
redis-cli --bigkeys -i 0.1 | grep -E "(Biggest|bytes|fields|items)"# 2. 內存分析
echo "=== 內存分析 ==="
redis-cli info memory | grep -E "(used_memory|mem_fragmentation_ratio)"# 3.Key檢查
echo "=== 熱Key檢查 ==="
redis-cli monitor | head -1000 | awk '
{ counts[$4]++ }
END {for (cmd in counts) {print counts[cmd], cmd;}
}' | sort -nr | head -5# 4. 生成報告
echo "檢查完成時間: $(date)"

??2. 自動化告警規則??:

# alert_rules.yml
groups:
- name: redis_alertsrules:- alert: RedisBigKeyDetectedexpr: redis_key_size_bytes > 1048576  # 1MBfor: 5mlabels:severity: warningannotations:summary: "發現大Key: {{ $labels.key }}"description: "Key {{ $labels.key }} 大小 {{ $value }} bytes"- alert: RedisHotKeyDetectedexpr: rate(redis_command_count{key=~".+"}[5m]) > 1000for: 2mlabels:severity: criticalannotations:summary: "發現熱Key: {{ $labels.key }}"description: "Key {{ $labels.key }} QPS {{ $value }}"- alert: RedisMemoryFragmentationexpr: redis_mem_fragmentation_ratio > 1.5for: 10mlabels:severity: warningannotations:summary: "內存碎片率過高"description: "當前碎片率 {{ $value }}"

🏗? 架構優化建議

??1. Proxy 層優化??:

// 基于代理的Key治理
public class KeyGovernanceProxy {private Map<String, KeyInfo> keyMetadata = new ConcurrentHashMap<>();public Object get(String key) {KeyInfo info = keyMetadata.computeIfAbsent(key, this::analyzeKey);if (info.isHotKey()) {// 熱Key特殊處理return getHotKey(key);} else if (info.isBigKey()) {// 大Key特殊處理return getBigKey(key);} else {// 正常處理return jedis.get(key);}}private KeyInfo analyzeKey(String key) {// 分析Key的特征long size = jedis.memoryUsage(key);long accessCount = getAccessCount(key);return new KeyInfo(size, accessCount);}
}

??2. 集群優化配置??:

# redis.conf 優化配置
# 內存管理
maxmemory 16gb
maxmemory-policy allkeys-lru
activedefrag yes# 持久化優化
aof-use-rdb-preamble yes
aof-rewrite-incremental-fsync yes# 網絡優化
tcp-backlog 65535
maxclients 10000

📊 性能對比評估

方案實施復雜度效果適用場景風險
數據拆分效果好大Key問題業務改造量大
數據壓縮效果中等值類型大KeyCPU開銷增加
多副本緩存效果很好熱Key問題數據一致性風險
本地緩存效果極好極端熱Key緩存一致性問題
代理分片效果極好集群環境架構復雜度高

🚀 全鏈路優化體系

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96807.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96807.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96807.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++算法題中的輸入輸出形式(I/O)

本文主要幫助刷leetcode題型快速適應完整帶輸入輸出的題&#xff08;機試、考試、比賽等&#xff09;接收能用cin就用cin 。cin 自動分割單詞 的特性&#xff08;cin 讀取字符串時會自動跳過空格 / 換行&#xff0c;將連續非空格字符作為一個 “單詞”&#xff09;一、單組輸入…

【左程云算法09】棧的入門題目-最小棧

目錄 棧的入門題目-最小棧 代碼演示 視頻鏈接 算法講解015【入門】棧的入門題目-最小棧 Leecode155 棧的入門題目-最小棧 實現一個getmin方法&#xff08;高效方法&#xff0c;即不用遍歷&#xff09;&#xff0c;希望能實現O&#xff08;1&#xff09; 做法&#xff1a…

Grafana與Prometheus實戰

&#x1f31f;Grafana的Dashboard的權限管理 創建團隊 創建用戶 設置團隊權限 &#x1f31f;Prometheus啟用https及認證功能 自建ca的證書 準備證書目錄 mkdir /app/tools/prometheus-2.53.4.linux-amd64/certs cd /app/tools/prometheus-2.53.4.linux-amd64/certs生成ca的…

FPGA交通燈設計報告(源碼+管腳約束+實物圖+設計報告)

基于FPGA的交通燈設計 摘要 本設計采用FPGA技術實現了一個智能交通燈控制系統。系統以Verilog HDL為設計語言,在FPGA平臺上實現了交通燈的自動控制、數碼管倒計時顯示、緊急情況處理等功能。通過合理的狀態機設計和模塊化編程,系統具有良好的實時性、可靠性和可擴展性,能夠…

技術論文分析分析論文《計算機病毒判定專家系統原理與設計》思考其在游戲中的應用

論文原文的引言主要有兩大部分的內容&#xff1a;介紹計算機病毒&#xff0c;明確本文使用的病毒分類方式&#xff1b;分析傳統計算機病毒檢測存在的弊端。對于計算機病毒的定義&#xff0c;文中給出的定義比較嚴謹&#xff0c;我自己查了一下現在百度百科的定義&#xff0c;兩…

《Unity項目實戰:動態加載引發的顯存危機全鏈路排查與重構實踐》

從動態光影那流光溢彩、仿佛賦予虛擬世界真實質感的絢麗效果—這得益于Unity引擎強大的HDRP管線對光照路徑的精準模擬,到物理引擎驅動的物體碰撞精準到毫厘的物理反饋—依托Unity Physics模塊對剛體動力學的毫秒級計算,再到能夠依據不同設備性能自動適配的畫質表現—通過Unit…

智慧水庫綜合管理系統平臺御控物聯網解決方案

一、行業背景與痛點分析水庫作為防洪、灌溉、供水、發電及生態保護的核心基礎設施&#xff0c;其管理效率直接關系到區域水資源安全與可持續發展。然而&#xff0c;傳統水庫管理模式存在四大核心痛點&#xff1a;數據孤島嚴重&#xff1a;水位、雨量、水質、設備狀態等數據分散…

使用nvm安裝Node.js18以下報錯解決方案——The system cannot find the file specified.

使用 nvm 安裝 Node.js 18以下 報錯解決方案 在前端開發過程中&#xff0c;常常需要針對不同項目切換 Node.js 版本。nvm&#xff08;Node Version Manager&#xff09;是最常用的工具。但最近在嘗試安裝 Node.js 14 版本時&#xff0c;遇到了奇怪的錯誤。 問題描述 使用 nv…

在Excel和WPS表格中快速復制上一行內容

有的時候我們在Excel和WPS表格中想復制上一行對應單元格、連續區域或整行的內容&#xff0c;只需要在當前行拖動鼠標左鍵選中相關區域&#xff0c;然后按CtrlD鍵即可將上一行對應位置的內容復制過來——需要注意的是&#xff0c;如果當前行有數據&#xff0c;這些數據會直接被覆…

408學習之c語言(遞歸與函數)

今天主要學習了遞歸與函數的相關內容&#xff0c;下面將我今天所學知識與所寫代碼分享給大家 遞歸核心要點 遞歸三要素 基準條件&#xff08;明確終止條件&#xff09; 遞歸調用&#xff08;逐步分解問題&#xff09; 收斂性&#xff08;確保每次遞歸都向基準條件靠近&#xff…

swVBA自學筆記016、Solidworks API Help 幫助文檔的(三大版塊)

目錄1. Namespace (命名空間) 版塊2. Interface (接口) 版塊3. Members (接口成員) 版塊4、總結關系5、如果你感覺上面說的過于簡單&#xff0c;請往下看!6、示例鏈接→SOLIDWORKS API Help 20197、需要注意的是&#xff0c;帶“I”的對象表示&#xff1a;接口1. Namespace (命…

通俗易懂地講解JAVA的BIO、NIO、AIO

理解Java的I/O模型&#xff08;BIO、NIO、AIO&#xff09;對于構建高性能網絡應用至關重要 &#x1f9e0; 通俗理解&#xff1a;快遞站的故事 想象一個快遞站&#xff1a; ? BIO&#xff1a;就像快遞站為每一個包裹都安排一位專員。專員從接到包裹到處理完&#xff08;簽收、…

LabVIEW 泵輪檢測系統

在汽車行業&#xff0c;泵輪作為液力變矩器關鍵部件&#xff0c;其質量檢測極為重要。傳統手工檢測泵輪效率低且誤差大&#xff0c;為此構建基于 LabVIEW 與西門子硬件結合的泵輪檢測系統。 應用場景 聚焦汽車零部件生產車間&#xff0c;對泵輪總成進行出廠前檢測。在液力變矩…

2025年8月月賽 T2 T3

一. 七天假日 T2原思路&#xff1a;直接計算左右括號的數量&#xff0c;然后直接輸出他們的差改進思路&#xff1a; 用d值記錄截止到當前位置&#xff0c;還需要多少個右括號可以滿足非法要求cur&#xff1a;截止到當前位置&#xff0c;已經有多少個右括號sum是右括號位置的前綴…

數據結構----棧的順序存儲(順序棧)

棧的特點&#xff1a;先進后出棧的操作&#xff1a;用數組進行存儲&#xff08;1&#xff09;初始化&#xff1a;//棧 typedef struct {int *data;//指針模擬分配數組int top;//棧“頂”指針 }Stack; //初始化 Stack InitStack(){Stack s;//給數組分配空間s.data (int*)malloc…

React Hooks原理深度解析與高級應用模式

React Hooks原理深度解析與高級應用模式 引言 React Hooks自16.8版本引入以來&#xff0c;徹底改變了我們編寫React組件的方式。然而&#xff0c;很多開發者僅僅停留在使用層面&#xff0c;對Hooks的實現原理和高級應用模式了解不深。本文將深入探討Hooks的工作原理、自定義Hoo…

兼職網|基于SpringBoot和Vue的蝸牛兼職網(源碼+數據庫+文檔)

項目介紹 : SpringbootMavenMybatis PlusVue Element UIMysql 開發的前后端分離的蝸牛兼職網&#xff0c;項目分為管理端和用戶端和企業端。 項目演示: 基于SpringBoot和Vue的蝸牛兼職網 運行環境: 最好是java jdk 1.8&#xff0c;我們在這個平臺上運行的。其他版本理論上也可…

TDengine 聚合函數 LEASTSQUARES 用戶手冊

LEASTSQUARES 函數用戶手冊 函數定義 LEASTSQUARES(expr, start_val, step_val)功能說明 LEASTSQUARES() 函數對指定列的數據進行最小二乘法線性擬合&#xff0c;返回擬合直線的斜率&#xff08;slope&#xff09;和截距&#xff08;intercept&#xff09;。該函數基于線性回…

Redis最佳實踐——安全與穩定性保障之高可用架構詳解

全面詳解 Java 中 Redis 在電商應用的高可用架構設計一、高可用架構核心模型 1. 多層級高可用體系 #mermaid-svg-anJ3iQ0ymhr025Jn {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-anJ3iQ0ymhr025Jn .error-icon{fil…

ABAP 屏幕在自定義容器寫多行文本框

文章目錄變量定義容器等邏輯屏幕效果變量定義 CONSTANTS: GC_TEXT_LINE_LENGTH TYPE I VALUE 72. TYPES: TEXT_TABLE_TYPE(GC_TEXT_LINE_LENGTH) TYPE C OCCURS 0. DATA: GV_SPLITTER TYPE REF TO CL_GUI_EASY_SPLITTER_CONTAINER. DATA: GV_CUSTOM_CONTAINER TYPE REF TO CL_…