Redis 在互聯網高并發場景下的應用--個人總結

在現代互聯網系統中,高并發已經成為常態。無論是電商的秒殺場景、社交平臺的熱點推薦,還是支付接口的風控,系統需要同時應對成千上萬的請求。這時候,Redis 作為一個高性能的內存數據庫,憑借其極快的讀寫速度和豐富的數據結構,成為解決高并發問題的利器。

1. 緩存熱點數據 —— 緩解數據庫壓力

問題背景:數據庫在高并發場景下容易成為瓶頸,特別是熱點數據的訪問會導致 QPS 瞬間飆升。
Redis 解決方案

  • 使用 StringHash 緩存熱點數據。

  • 采用 Cache Aside 模式:先查緩存,緩存未命中再查數據庫并回填。

示例代碼

import redisr = redis.Redis(host='localhost', port=6379, db=0)def get_data_from_db(key):print("查詢數據庫")return {"id": key, "value": f"data_{key}"}def get_data(key):cache_key = f"cache:{key}"val = r.get(cache_key)if val:print("命中緩存")return eval(val)data = get_data_from_db(key)r.setex(cache_key, 60, str(data))return dataprint(get_data(1))
print(get_data(1))

在高并發場景下使用 Cache-Aside(旁路緩存) 模式,確實需要特別注意一些坑點和邊界情況。主要有以下幾個方面:

1. 緩存擊穿(Cache Miss Under High Concurrency)

  • 問題:某個熱點 key 過期瞬間,大量請求并發打到數據庫,造成瞬時壓力飆升。

  • 解決

    • 互斥鎖(分布式鎖) 控制只允許一個請求回源數據庫并更新緩存。

    • 或者使用 邏輯過期:緩存里放置過期時間戳,過期時先返回舊值,再異步刷新。

2. 緩存穿透(Cache Penetration)

  • 問題:請求的數據在數據庫中不存在,每次都會查詢 DB,導致 DB 壓力大。

  • 解決

    • 緩存空對象(短 TTL),避免重復訪問 DB。

    • 增加 布隆過濾器前置攔截機制,快速判斷 key 是否可能存在。

3. 緩存雪崩(Cache Avalanche)

  • 問題:大量緩存 key 在同一時間點同時過期,引發請求全部打到 DB。

  • 解決

    • 給 key 設置 隨機過期時間,避免同時失效。

    • 使用 多級緩存(L1/L2) 減輕瞬時壓力。

4. 數據一致性(Consistency)

  • 問題:Cache-Aside 是 最終一致性,更新邏輯里 “先寫 DB 再刪緩存” 會有時間窗口問題。

  • 解決

    • 常見策略是 先更新 DB,再刪除緩存(推薦),避免臟讀。

    • 或者使用 延時雙刪(寫 DB → 刪緩存 → 延遲一小段時間再刪一次緩存)。

    • 若業務對一致性要求極高,可能需要 訂閱 binlog(如 Canal)異步更新緩存

5. 熱點 Key 與大 Value

  • 熱點 Key:可能被頻繁訪問,甚至成為單點瓶頸。可通過 分片/多副本 緩解。

  • 大 Value:更新頻率低但體積大時,更新緩存成本高,可以考慮 局部字段緩存拆分存儲

6. 并發控制 & 原子性

  • 多線程并發下需要注意 讀寫競爭:避免多個線程同時回源刷新。

  • 分布式場景下要用 原子操作(如 Redis 的 setnx + expire) 做鎖和限流。

7. 監控與降級

  • 監控緩存命中率、請求 QPS、DB 壓力。

  • 當緩存大面積失效時,可以考慮:

    • 啟動 限流/熔斷

    • 提供 降級數據(兜底邏輯)

應用場景:用戶信息、商品詳情頁、首頁推薦數據等。

2. 限流 —— 防止接口過載

問題背景:突發流量可能會壓垮下游服務,例如秒殺、登錄、支付接口。
Redis 解決方案

  • 使用 String 作為計數器:INCR + EXPIRE 實現固定時間窗口限流。

  • 使用 Sorted Set 存儲時間戳:實現滑動窗口限流,更加精細化。

  • 可以配合 Lua 腳本保證原子性操作。

應用場景:API 調用限流、防止刷單、短信/驗證碼接口保護。

示例代碼(滑動窗口限流)

import time
import redisr = redis.Redis(host='localhost', port=6379, db=0)def is_allowed_sliding_window(user_id, action, period=60, max_count=5):key = f"rate_limit:{user_id}:{action}"now = time.time()pipeline = r.pipeline()pipeline.zadd(key, {now: now})pipeline.zremrangebyscore(key, 0, now - period)pipeline.zcard(key)pipeline.expire(key, period)_, _, count, _ = pipeline.execute()return count <= max_countfor i in range(10):if is_allowed_sliding_window("u1001", "login"):print(i, "允許")else:print(i, "拒絕")time.sleep(0.5)

或者 使用 String 作為計數器

import redis
import timer = redis.Redis(host='localhost', port=6379, db=0)def is_allowed(user_id, action, period=60, max_count=5):"""在 period 時間內最多允許 max_count 次操作"""key = f"rate_limit:{user_id}:{action}"count = r.incr(key)if count == 1:r.expire(key, period)  # 設置過期時間if count > max_count:return Falsereturn True# 測試
for i in range(10):if is_allowed("u1001", "login"):print(i, "允許")else:print(i, "拒絕")time.sleep(0.5)

3. 分布式隊列 —— 異步削峰

問題背景:大量請求直接打到數據庫或下游服務,可能會瞬間撐爆系統。
Redis 解決方案

  • 使用 ListLPUSH + BRPOP)作為簡單任務隊列。

  • 使用 Stream 實現類似 Kafka 的消息隊列:支持消費組、消息確認和持久化。

  • 常見用途:削峰填谷,將請求轉為異步任務,讓系統有更多緩沖時間。

應用場景:訂單處理、日志收集、消息通知、秒殺排隊。

示例代碼(Stream 隊列)

import redisr = redis.Redis(host='localhost', port=6379, db=0)
stream_key = "order_stream"# 生產者
def produce():for i in range(5):r.xadd(stream_key, {"order": f"order_{i}"})print("生產訂單:", f"order_{i}")# 消費者
def consume():last_id = "0-0"while True:messages = r.xread({stream_key: last_id}, block=2000, count=2)if not messages:breakfor _, msgs in messages:for msg_id, data in msgs:print("消費訂單:", msg_id, data)last_id = msg_idproduce()
consume()

4. 分布式鎖 —— 保證數據一致性

問題背景:在分布式環境中,多實例同時修改同一資源,可能造成數據沖突。
Redis 解決方案

  • 使用 String 類型:

    • SET key value NX PX timeout 實現加鎖,避免重復設置。

    • 校驗 value 防止誤刪鎖。

  • 高級方案:使用 RedLock 算法 提升可靠性,避免單點故障。

應用場景:庫存扣減、任務調度、并發下的冪等操作。

示例代碼

import redis
import uuid
import timer = redis.Redis(host='localhost', port=6379, db=0)def acquire_lock(lock_key, expire=5):lock_id = str(uuid.uuid4())result = r.set(lock_key, lock_id, nx=True, ex=expire)return lock_id if result else Nonedef release_lock(lock_key, lock_id):script = """if redis.call('get', KEYS[1]) == ARGV[1] thenreturn redis.call('del', KEYS[1])elsereturn 0end"""return r.eval(script, 1, lock_key, lock_id)lock_id = acquire_lock("my_lock", expire=3)
if lock_id:print("獲得鎖,執行業務邏輯...")time.sleep(2)print("釋放鎖:", release_lock("my_lock", lock_id))
else:print("未獲得鎖")

5. 實時統計與排行榜

問題背景:高并發下,需要對訪問量、點贊數、排名進行實時計算。
Redis 解決方案

  • 使用 INCR / HINCRBY 做計數器。

  • 使用 Sorted Set 實現排行榜,支持按分數排序。

應用場景:網站 PV/UV 統計、熱搜榜、積分排名、點贊排行榜。

示例代碼

import redisr = redis.Redis(host='localhost', port=6379, db=0)# 統計 PV
r.incr("page_view")
print("頁面訪問量:", r.get("page_view").decode())# 排行榜
leaderboard = "game_rank"
r.zincrby(leaderboard, 10, "user1")
r.zincrby(leaderboard, 20, "user2")print("排行榜:", r.zrevrange(leaderboard, 0, -1, withscores=True))

總結

在互聯網高并發場景下,Redis 可以解決以下核心問題:

  1. 緩存熱點數據 → 緩解數據庫壓力,提升響應速度。

  2. 限流 → 防止突發流量沖擊系統。

  3. 分布式隊列 → 實現削峰填谷,支撐異步處理。

  4. 分布式鎖 → 保證數據一致性,防止并發沖突。

  5. 實時統計與排行榜 → 提供快速的聚合計算能力。

Redis 不僅僅是一個緩存,更是一個 高并發場景下的基礎設施。合理利用其數據結構與特性,可以極大提升系統的可擴展性與穩定性。

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

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

相關文章

C++筆記之軟件設計原則總結

C++筆記之軟件設計原則總結 code review 文章目錄 C++筆記之軟件設計原則總結 1.軟件設計的六大原則 2.高內聚與低耦合 2.1.高內聚(High Cohesion) 2.2.低耦合(Low Coupling) 2.3.高內聚與低耦合的關系與重要性 3.DRY(Dont Repeat Yourself)原則 3.1.定義 3.2.好處 3.3.示…

ThreadLocal 深度解析:原理、應用場景與最佳實踐

一、ThreadLocal 核心概念與設計哲學?1.1 ThreadLocal 的基本概念?ThreadLocal 是 Java 中提供線程局部變量的類&#xff0c;它允許每個線程創建自己的變量副本&#xff0c;從而實現線程封閉&#xff08;Thread Confinement&#xff09;。簡單來說&#xff0c;ThreadLocal 為…

AMD顯卡運行GPT-OSS全攻略

AMD顯卡運行GPT-OSS全攻略 本文介紹如何在Windows系統上使用AMD顯卡&#xff08;以RX 7900XTX為例&#xff09;運行開源GPT-OSS模型。 前置要求 硬件&#xff1a;AMD顯卡&#xff08;如RX 7900XTX&#xff0c;具體支持型號參考ROCm文檔&#xff09;。軟件&#xff1a; Ollam…

【Sharding-JDBC】?Spring/Spring Boot 集成 Sharding-JDBC,分表策略與 API、YAML 配置實踐?

文章目錄環境準備Spring框架Sharding-JDBC 4.x版本api實現Sharding-JDBC 5.4.x版本yaml實現Springboot框架Sharding-JDBC 5.4.x版本yaml實現分庫、加密、讀寫分離基于yaml的配置示例更多相關內容可查看需求&#xff1a;按月分區&#xff0c;按年分表&#xff0c;找不到對應年份…

單片機和PLC有哪些區別?揭秘單片機MCU的常見應用

單片機&#xff08;MCU&#xff09;和可編程邏輯控制器&#xff08;PLC&#xff09;作為電子控制系統中的兩大核心組件&#xff0c;分別在不同的領域發揮著重要作用。然而&#xff0c;盡管它們都屬于自動化控制領域的關鍵設備&#xff0c;但它們的設計理念、應用場景和性能特點…

ElementUI之Upload 上傳的使用

文章目錄說明SSM使用引入依賴在spring-mvc.xml中加入配置創建上傳工具類AliOssUtil響應工具類ResultJSON編寫controller自動上傳代碼編寫結果如下演示手動上傳前端代碼編寫后端代碼編寫結果演示如下說明 為了方便演示&#xff0c;前后端代碼一起寫了 關于對象存儲請看我另一篇博…

Langchain4j 整合MongoDB 實現會話持久化存儲詳解

目錄 一、前言 二、大模型會話記憶介紹 2.1 AI 大模型會話記憶是什么 2.2 大模型會話記憶常用實現方案 2.3 LangChain4j 會話記憶介紹 三、大模型常用會話存儲數據庫介紹 3.1 常用的會話存儲數據庫 3.2 MongoDB 簡介 3.2.1 MongoDB 是什么 3.3 為什么選擇MongoDB 作為…

SQL 常用 OVER() 窗口函數介紹

1. sum() over() 做組內數據累加在 SQL 中想實現不同分組內數據累加&#xff0c;可以通過 sum() over() PARTITION BY ORDER BY 結合實現。這種方式能同時滿足多維度分組且組內累加的需求&#xff0c;示例如下&#xff1a;假設我們有一張 sales 表&#xff0c;表中存儲著…

OpenRouter:一站式 AI 模型調用平臺,免費暢享千問、DeepSeek 等頂級模型

歡迎來到我的博客&#xff0c;代碼的世界里&#xff0c;每一行都是一個故事&#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交給時間 &#x1f3e0; &#xff1a;小破站 OpenRouter&#xff1a;一站式 AI 模型調用平臺&#xff0c;免費暢享千問、DeepSeek 等頂級模型前…

SpringBoot 整合 Kafka 的實戰指南

引言&#xff1a; 本文總字數&#xff1a;約 9800 字預計閱讀時間&#xff1a;40 分鐘 為什么 Kafka 是高吞吐場景的首選&#xff1f; 在當今的分布式系統中&#xff0c;消息隊列已成為不可或缺的基礎設施。面對不同的業務場景&#xff0c;選擇合適的消息隊列至關重要。目前…

OpenCV 實戰篇——如何測算出任一副圖片中的物體的實際尺寸?傳感器尺寸與像元尺寸的關系?

文章目錄1 如何測算出任一副圖片中的物體的實際尺寸2 傳感器尺寸與像元尺寸的關系3 Max Frame Rate最大幀率4 為什么要進行相機標定?相機標定有何意義?5 基于相機模型的單目測距--普通相機1 如何測算出任一副圖片中的物體的實際尺寸 物體尺寸測量的思路是找一個確定尺寸的物…

Java并發鎖相關

鎖相關 ?1. 什么是可重入鎖&#xff1f;Java 中如何實現&#xff1f;?? ?答?&#xff1a; 可重入鎖允許一個線程多次獲取同一把鎖&#xff08;即遞歸調用時無需重新競爭鎖&#xff09;。 ?關鍵點?&#xff1a;防止死鎖&#xff0c;避免線程因重復請求已持有的鎖而阻塞。…

Pie Menu Editor V1.18.7.exe 怎么安裝?詳細安裝教程(附安裝包)?

??Pie Menu Editor V1.18.7.exe? 是一款用于創建和編輯 ?餅圖菜單&#xff08;Pie Menu&#xff09;?? 的工具軟件&#xff0c;通常用于游戲開發、UI設計、3D建模&#xff08;如 Blender 等&#xff09;、或自定義軟件操作界面。 一、準備工作 ?下載文件? 下載了 ?Pi…

基于Spark的中文文本情感分析系統研究

引言 1.1 研究背景與意義 隨著互聯網的普及和社交媒體的興起、特別是自媒體時代的來臨&#xff0c;網絡文本數據呈現爆炸式增長。這些文本數據蘊含著豐富的用戶情感信息&#xff0c;如何有效地挖掘和利用這些信息&#xff0c;對于了解輿情動態、改進客戶服務、輔助決策分析具…

Simulink子系統、變體子系統及封裝知識

1.引言 文章三相新能源并網系統序阻抗模型——序阻抗分析器IMAnalyzer介紹了一種用于分析和掃描序阻抗的軟件。其中&#xff0c;在序阻抗掃頻操作過程中&#xff0c;用到了一個擾動注入、測量和運算工具【IMtool】&#xff0c;它外表長這樣&#xff1a; 內部長這樣&#xff1a…

高階組件介紹

高階組件約定俗成以with開頭 import React, { useEffect } from react; import { TouchableOpacity, Image, StyleSheet } from react-native;type IReactComponent React.ClassicComponentClass| React.ComponentClass| React.FunctionComponent| React.ForwardRefExoticComp…

C++ STL系列-02.泛型入門

C STL系列-02.泛型入門C中的泛型編程主要通過模板&#xff08;template&#xff09;實現。模板允許我們編寫與類型無關的代碼&#xff0c;是一種將類型作為參數進行編程的方式。在C中&#xff0c;模板分為函數模板和類模板。 1. 函數模板函數模板允許我們定義一個函數&#xff…

高效管理網絡段和端口集合的工具之ipset

目錄 1. 核心命令速查 2. 集合類型 3. 實戰案例&#xff1a;使用 ipset 封禁 IP 案例 1&#xff1a;基礎黑名單封禁&#xff08;手動添加&#xff09; 案例 2&#xff1a;自動過期和解封 案例 3&#xff1a;封禁 IP 和端口組合 案例 4&#xff1a;白名單模式 案例 5&am…

實例和對象的區別

對象&#xff08;Object&#xff09;是一個概念&#xff0c;它表示“某個類的一個成員”&#xff0c;是“邏輯上的個體”。實例&#xff08;Instance&#xff09;是一個現實&#xff0c;指的是在內存中真正分配了空間的對象。實例一定是對象&#xff0c;但對象不一定是實例。例…

Win10 Chrome認不出新Emoji?兩個擴展搞定顯示與輸入

前言 用Win10電腦在Chrome里發消息、刷網頁時&#xff0c;你是否遇到過這樣的尷尬&#xff1a;別人發的、或者頁面顯示的 Emoji&#xff0c;在你屏幕上變成了空白方框&#xff0c;像“文字里缺了一塊拼圖”&#xff1f;其實這不是Chrome的錯&#xff0c;也不用換電腦&#xff0…