偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Redis能抗住百萬并發(fā)的秘密

數(shù)據(jù)庫 Redis
有些小伙伴在工作中可能遇到過這樣的場景:系統(tǒng)訪問量一上來,數(shù)據(jù)庫就扛不住了,這時候大家第一時間想到的就是Redis。但你有沒有想過,為什么Redis能夠承受如此高的并發(fā)量?它的底層到底做了什么優(yōu)化?

今天想和大家深入聊聊Redis為什么能夠輕松抗住百萬級別的并發(fā)請求。

有些小伙伴在工作中可能遇到過這樣的場景:系統(tǒng)訪問量一上來,數(shù)據(jù)庫就扛不住了,這時候大家第一時間想到的就是Redis。

但你有沒有想過,為什么Redis能夠承受如此高的并發(fā)量?它的底層到底做了什么優(yōu)化?

今天我們就從淺入深,一步步揭開Redis高性能的神秘面紗。

1. Redis高并發(fā)的核心架構(gòu)

1.1 單線程模型的威力

有些小伙伴可能會疑惑:Redis是單線程的,為什么還能支持這么高的并發(fā)?

這里需要澄清一個概念,Redis的"單線程"指的是網(wǎng)絡(luò)IO和鍵值對讀寫是由一個線程來完成的,但Redis的整個系統(tǒng)并不是只有一個線程。

圖片圖片

為什么單線程反而更快?

  • 避免了線程切換的開銷:多線程環(huán)境下,CPU需要在不同線程間切換,這個過程需要保存和恢復(fù)線程上下文,開銷很大。
  • 避免了鎖競爭:單線程模型下,不需要考慮線程安全問題,避免了各種鎖的開銷。
  • CPU緩存友好:單線程執(zhí)行時,CPU緩存命中率更高,減少了內(nèi)存訪問延遲。

讓我們看一個簡單的對比:

// 多線程模式下的偽代碼
public class MultiThreadRedis {
    private final Object lock = new Object();
    private Map<String, String> data = new HashMap<>();
    
    public String get(String key) {
        synchronized(lock) {  // 需要加鎖
            return data.get(key);
        }
    }
    
    public void set(String key, String value) {
        synchronized(lock) {  // 需要加鎖
            data.put(key, value);
        }
    }
}

// Redis單線程模式下的偽代碼
public class SingleThreadRedis {
    private Map<String, String> data = new HashMap<>();
    
    public String get(String key) {
        return data.get(key);  // 無需加鎖
    }
    
    public void set(String key, String value) {
        data.put(key, value);  // 無需加鎖
    }
}

1.2 事件驅(qū)動模型

Redis采用了事件驅(qū)動的架構(gòu),基于Reactor模式實現(xiàn)。

這種模式的核心思想是:用一個線程來處理多個連接的IO事件。

圖片圖片

事件驅(qū)動的優(yōu)勢:

  • 高效的IO多路復(fù)用:一個線程可以同時監(jiān)聽多個socket連接
  • 非阻塞IO:不會因為某個連接的IO操作而阻塞整個程序
  • 內(nèi)存占用少:相比多線程模型,節(jié)省了大量線程??臻g

2. 內(nèi)存數(shù)據(jù)結(jié)構(gòu)的極致優(yōu)化

2.1 高效的數(shù)據(jù)結(jié)構(gòu)設(shè)計

Redis的高性能很大程度上得益于其精心設(shè)計的內(nèi)存數(shù)據(jù)結(jié)構(gòu)。

每種數(shù)據(jù)類型都有多種底層實現(xiàn),Redis會根據(jù)數(shù)據(jù)的特點自動選擇最優(yōu)的存儲方式。

圖片

讓我們深入了解幾個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu):

2.1.1 SDS (Simple Dynamic String)

有些小伙伴可能不知道,Redis并沒有直接使用C語言的字符串,而是自己實現(xiàn)了SDS。

// Redis SDS結(jié)構(gòu)
struct sdshdr {
    int len;        // 字符串長度
    int free;       // 未使用空間長度
    char buf[];     // 字符串內(nèi)容
};

SDS的優(yōu)勢:

  • O(1)時間復(fù)雜度獲取長度:直接讀取len字段
  • 預(yù)分配空間:減少內(nèi)存重新分配次數(shù)
  • 二進(jìn)制安全:可以存儲任意二進(jìn)制數(shù)據(jù)
  • 兼容C字符串函數(shù):以空字符結(jié)尾

2.1.2 跳躍表 (Skip List)

跳躍表是Redis中有序集合的核心數(shù)據(jù)結(jié)構(gòu),它的查找效率可以達(dá)到O(log N)。

圖片圖片

跳躍表的查找過程:

// 跳躍表查找偽代碼
public Node search(int target) {
    Node current = header;
    
    // 從最高層開始查找
    for (int level = maxLevel; level >= 0; level--) {
        // 在當(dāng)前層向右移動,直到下一個節(jié)點大于目標(biāo)值
        while (current.forward[level] != null && 
               current.forward[level].value < target) {
            current = current.forward[level];
        }
    }
    
    // 移動到下一個節(jié)點
    current = current.forward[0];
    
    if (current != null && current.value == target) {
        return current;
    }
    returnnull;
}

2.2 內(nèi)存優(yōu)化策略

2.2.1 壓縮列表 (ziplist)

當(dāng)Hash、List、ZSet的元素較少時,Redis會使用壓縮列表來節(jié)省內(nèi)存。

圖片圖片

壓縮列表的優(yōu)勢:

  • 內(nèi)存緊湊:所有元素連續(xù)存儲,減少內(nèi)存碎片
  • 緩存友好:連續(xù)內(nèi)存訪問,CPU緩存命中率高
  • 節(jié)省指針開銷:不需要存儲指向下一個元素的指針

2.2.2 整數(shù)集合 (intset)

當(dāng)Set中只包含整數(shù)元素時,Redis使用整數(shù)集合來存儲。

// 整數(shù)集合結(jié)構(gòu)
typedef struct intset {
    uint32_t encoding;  // 編碼方式
    uint32_t length;    // 元素數(shù)量
    int8_t contents[];  // 元素數(shù)組
} intset;

編碼方式自動升級:

// 整數(shù)集合編碼升級示例
public class IntSetExample {
    // 初始狀態(tài):所有元素都是16位整數(shù)
    // encoding = INTSET_ENC_INT16
    // contents = [1, 2, 3, 4, 5]
    
    // 添加一個32位整數(shù)
    public void addLargeNumber() {
        // 自動升級為32位編碼
        // encoding = INTSET_ENC_INT32
        // 重新分配內(nèi)存,轉(zhuǎn)換所有現(xiàn)有元素
    }
}

3. 網(wǎng)絡(luò)IO優(yōu)化

3.1 IO多路復(fù)用技術(shù)

Redis在不同操作系統(tǒng)上使用不同的IO多路復(fù)用技術(shù):

  • Linux: epoll
  • macOS/FreeBSD: kqueue
  • Windows: select

圖片圖片

epoll的優(yōu)勢:

  • 事件驅(qū)動:只有當(dāng)socket有事件時才會通知應(yīng)用程序
  • 高效輪詢:不需要遍歷所有文件描述符
  • 支持邊緣觸發(fā):減少系統(tǒng)調(diào)用次數(shù)

3.2 客戶端輸出緩沖區(qū)

Redis為每個客戶端維護(hù)輸出緩沖區(qū),避免慢客戶端影響整體性能。

圖片圖片

緩沖區(qū)配置示例:

# redis.conf配置
# 普通客戶端緩沖區(qū)限制
client-output-buffer-limit normal 0 0 0

# 從服務(wù)器緩沖區(qū)限制  
client-output-buffer-limit replica 256mb 64mb 60

# 發(fā)布訂閱客戶端緩沖區(qū)限制
client-output-buffer-limit pubsub 32mb 8mb 60

4. 內(nèi)存管理優(yōu)化

4.1 內(nèi)存分配器選擇

Redis支持多種內(nèi)存分配器,默認(rèn)使用jemalloc,這是一個專門為多線程應(yīng)用優(yōu)化的內(nèi)存分配器。

圖片圖片

4.2 過期鍵刪除策略

Redis采用惰性刪除和定期刪除相結(jié)合的策略來處理過期鍵。

圖片圖片

定期刪除算法:

// Redis定期刪除偽代碼
public void activeExpireCycle() {
    int maxIterations = 16; // 最大檢查數(shù)據(jù)庫數(shù)
    int maxChecks = 20;     // 每個數(shù)據(jù)庫最大檢查鍵數(shù)
    
    for (int i = 0; i < maxIterations; i++) {
        RedisDb db = server.db[i];
        int expired = 0;
        
        for (int j = 0; j < maxChecks; j++) {
            String key = db.expires.randomKey();
            if (key != null && isExpired(key)) {
                deleteKey(key);
                expired++;
            }
        }
        
        // 如果過期鍵比例小于25%,跳出循環(huán)
        if (expired < maxChecks / 4) {
            break;
        }
    }
}

5. 持久化優(yōu)化

5.1 RDB持久化

RDB是Redis的默認(rèn)持久化方式,它會在指定的時間間隔內(nèi)生成數(shù)據(jù)集的時點快照。

圖片圖片

RDB的優(yōu)勢:

  • 緊湊的文件格式:適合備份和災(zāi)難恢復(fù)
  • 快速重啟:恢復(fù)速度比AOF快
  • 對性能影響小:使用子進(jìn)程進(jìn)行持久化

5.2 AOF持久化

AOF通過記錄服務(wù)器執(zhí)行的所有寫操作命令來實現(xiàn)持久化。

圖片圖片

AOF重寫優(yōu)化:

// AOF重寫示例
public class AOFRewrite {
    // 原始AOF文件可能包含:
    // SET key1 value1
    // SET key1 value2  
    // SET key1 value3
    // DEL key2
    // SET key2 newvalue
    // LPUSH list a
    // LPUSH list b
    // LPUSH list c
    
    // 重寫后的AOF文件:
    // SET key1 value3
    // SET key2 newvalue  
    // LPUSH list c b a
    
    public void rewriteAOF() {
        // 遍歷所有數(shù)據(jù)庫
        for (RedisDb db : server.databases) {
            // 遍歷所有鍵
            for (String key : db.dict.keys()) {
                Object value = db.dict.get(key);
                // 根據(jù)值的類型生成對應(yīng)的命令
                generateCommand(key, value);
            }
        }
    }
}

6. 集群和分片優(yōu)化

6.1 Redis Cluster

Redis Cluster是Redis的官方集群解決方案,采用無中心化的架構(gòu)。

圖片圖片

哈希槽分配算法:

public class RedisClusterSlot {
    private static final int CLUSTER_SLOTS = 16384;
    
    public int calculateSlot(String key) {
        // 檢查是否有哈希標(biāo)簽
        int start = key.indexOf('{');
        if (start != -1) {
            int end = key.indexOf('}', start + 1);
            if (end != -1 && end != start + 1) {
                key = key.substring(start + 1, end);
            }
        }
        
        // 計算CRC16校驗和
        int crc = crc16(key.getBytes());
        return crc % CLUSTER_SLOTS;
    }
    
    // CRC16算法實現(xiàn)
    private int crc16(byte[] data) {
        int crc = 0x0000;
        for (byte b : data) {
            crc ^= (b & 0xFF);
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) != 0) {
                    crc = (crc >> 1) ^ 0xA001;
                } else {
                    crc = crc >> 1;
                }
            }
        }
        return crc & 0xFFFF;
    }
}

6.2 分片策略

有些小伙伴在設(shè)計分片策略時,可能會遇到數(shù)據(jù)傾斜的問題。

Redis提供了多種分片方式:

圖片圖片

7. 性能監(jiān)控和調(diào)優(yōu)

7.1 關(guān)鍵性能指標(biāo)

圖片圖片

性能監(jiān)控命令:

# 查看Redis信息
INFO all

# 監(jiān)控實時命令
MONITOR

# 查看慢查詢?nèi)罩?SLOWLOG GET 10

# 查看客戶端連接
CLIENT LIST

# 查看內(nèi)存使用情況
MEMORY USAGE keyname

# 查看延遲統(tǒng)計
LATENCY LATEST

7.2 性能調(diào)優(yōu)建議

內(nèi)存優(yōu)化:

# redis.conf優(yōu)化配置

# 啟用內(nèi)存壓縮
hash-max-ziplist-entries 512
hash-max-ziplist-value 64

list-max-ziplist-size -2
list-compress-depth 0

set-max-intset-entries 512

zset-max-ziplist-entries 128
zset-max-ziplist-value 64

# 內(nèi)存淘汰策略
maxmemory-policy allkeys-lru

# 啟用內(nèi)存壓縮
rdbcompression yes

網(wǎng)絡(luò)優(yōu)化:

# TCP相關(guān)優(yōu)化
tcp-keepalive 300
tcp-backlog 511

# 客戶端超時
timeout 0

# 輸出緩沖區(qū)限制
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

8. 故障處理和高可用

8.1 故障檢測機(jī)制

8.2 數(shù)據(jù)一致性保證

主從復(fù)制機(jī)制:

// Redis主從復(fù)制流程
public class RedisReplication {
    
    // 全量同步
    public void fullResync() {
        // 1. 從服務(wù)器發(fā)送PSYNC命令
        // 2. 主服務(wù)器執(zhí)行BGSAVE生成RDB文件
        // 3. 主服務(wù)器將RDB文件發(fā)送給從服務(wù)器
        // 4. 從服務(wù)器載入RDB文件
        // 5. 主服務(wù)器將緩沖區(qū)的寫命令發(fā)送給從服務(wù)器
    }
    
    // 增量同步
    public void partialResync() {
        // 1. 從服務(wù)器發(fā)送PSYNC runid offset
        // 2. 主服務(wù)器檢查復(fù)制偏移量
        // 3. 如果偏移量在復(fù)制積壓緩沖區(qū)內(nèi),執(zhí)行增量同步
        // 4. 主服務(wù)器將緩沖區(qū)中的數(shù)據(jù)發(fā)送給從服務(wù)器
    }
}

總結(jié)

通過以上深入分析,我們可以看到Redis能夠抗住10萬并發(fā)的核心原因包括:

架構(gòu)層面

  • 單線程模型:避免了線程切換和鎖競爭的開銷
  • 事件驅(qū)動:基于epoll的IO多路復(fù)用,高效處理大量連接
  • 內(nèi)存存儲:所有數(shù)據(jù)存儲在內(nèi)存中,訪問速度極快

數(shù)據(jù)結(jié)構(gòu)層面

  • 高效的數(shù)據(jù)結(jié)構(gòu):針對不同場景優(yōu)化的數(shù)據(jù)結(jié)構(gòu)
  • 內(nèi)存優(yōu)化:壓縮列表、整數(shù)集合等節(jié)省內(nèi)存的設(shè)計
  • 智能編碼:根據(jù)數(shù)據(jù)特點自動選擇最優(yōu)存儲方式

網(wǎng)絡(luò)層面

  • IO多路復(fù)用:單線程處理多個連接
  • 客戶端緩沖區(qū):避免慢客戶端影響整體性能
  • 協(xié)議優(yōu)化:簡單高效的RESP協(xié)議

持久化層面

  • 異步持久化:不阻塞主線程的持久化機(jī)制
  • 多種策略:RDB和AOF滿足不同場景需求
  • 增量同步:高效的主從復(fù)制機(jī)制

集群層面

  • 水平擴(kuò)展:通過分片支持更大規(guī)模
  • 高可用:主從復(fù)制和故障轉(zhuǎn)移
  • 負(fù)載均衡:智能的數(shù)據(jù)分布算法

有些小伙伴在工作中可能會問:"既然Redis這么強(qiáng)大,是不是可以完全替代數(shù)據(jù)庫?"答案是否定的。

Redis更適合作為緩存和高速數(shù)據(jù)存儲,而不是主要的數(shù)據(jù)存儲。

正確的做法是將Redis與傳統(tǒng)數(shù)據(jù)庫結(jié)合使用,發(fā)揮各自的優(yōu)勢。

最后,要想真正發(fā)揮Redis的性能,不僅要了解其原理,更要在實際項目中不斷實踐和優(yōu)化。

希望這篇文章能夠幫助大家更好地理解和使用Redis。

責(zé)任編輯:武曉燕 來源: 蘇三說技術(shù)
相關(guān)推薦

2025-06-05 01:22:00

SpringGateway高并發(fā)

2023-04-13 08:00:45

Redis底層性能

2025-01-12 13:06:45

2024-07-04 11:06:47

2025-07-09 04:00:00

Kafka億級流量高并發(fā)

2025-08-20 09:17:41

2025-02-14 03:00:00

2022-08-04 20:41:42

高并發(fā)流量SQL

2019-11-12 09:32:35

高并發(fā)流量協(xié)議

2023-01-28 08:24:28

MySQL索引B+樹

2019-11-18 08:21:04

秒殺系統(tǒng)高性能

2025-01-20 08:31:31

Redis多線程網(wǎng)絡(luò)模型

2013-06-18 13:36:19

用友UAP宅急送開發(fā)平臺

2021-08-26 11:10:42

架構(gòu)運(yùn)維技術(shù)

2023-02-13 08:18:15

數(shù)據(jù)庫索引,

2024-12-26 09:15:28

2025-10-16 02:11:00

SpingCloudGateway

2024-04-29 06:41:04

項目面試官QPS

2019-10-09 10:00:02

集群故障場景

2019-10-09 09:39:15

PythonHDFS大數(shù)據(jù)
點贊
收藏

51CTO技術(shù)棧公眾號