一句話回答:
Redis 是單線程處理客戶端命令,但可以通過 多實例部署、I/O 多路復用、后臺線程 + Redis 6 的 I/O Thread 支持,來充分利用多核 CPU。
?
一、Redis 單線程 ≠ 整個 Redis 都是單線程!
Redis 主要的 網絡事件 + 命令執行 是單線程的(主線程),但它其實有多線程參與的場景👇
模塊 | 多線程嗎? | 說明 |
---|---|---|
? 網絡 I/O 處理(Redis 6 起) | ? 可啟用 I/O 線程并發讀寫 | |
? 命令執行(SET/GET) | ? 仍是主線程執行 | |
? 持久化(RDB/AOF寫盤) | ? 后臺子進程執行 | |
? 異步刪除 / 釋放內存 | ? lazyfree 用線程池處理 | |
? Key 鎖 / 數據結構操作 | ? 主線程,避免加鎖開銷 |
二、Redis 利用多核的方式有哪些?
1. 啟用 Redis 6+ 的 I/O 多線程
Redis 6 開始支持 I/O 多線程(僅限網絡讀寫,命令仍在主線程):
# redis.conf 中配置io-threads 4io-threads-do-reads yes
-
原理:接收多個客戶端的請求數據,可并行讀取 socket → 提高吞吐量
-
適合場景:客戶端很多、網絡收發慢(不是 CPU 密集型命令)
2. 多 Redis 實例部署(橫向擴展)
-
在一臺服務器上跑多個 Redis 實例(每個實例單線程)
-
不同實例綁定不同 CPU 核心(
taskset
) -
適合多核機器,配合客戶端做 分庫分槽 分流訪問
💡 適合寫多、熱點分散的業務,比如電商、用戶數據分庫等
Redis分片
Redis 分片(Sharding)是把全量數據按一定規則(如 key 的 hash 值)分配到多個 Redis 實例中,每個實例負責一部分 key。
為什么分片能提升多核利用率?
特性 | 說明 |
---|---|
每個 Redis 實例是單線程 | 所以單實例最多利用 1 核 CPU ? |
多實例部署 | 可以跑在多個 CPU 核心上 ? |
客戶端路由 | 每次只訪問一個實例,減輕單點壓力 ? |
3. 使用 Redis Cluster(集群)
-
多 Redis 實例組成分布式集群,每個節點負責部分 key
-
多節點 = 多核多機并發,天然并行處理
💡 適合大規模分布式部署,自動分片 + 故障轉移
4. 后臺任務異步多線程(系統內建)
Redis 內部本身就會用多線程處理一些后臺任務,例如:
操作 | 說明 |
---|---|
異步刪除大 key | UNLINK 、FLUSHDB ASYNC 用線程釋放內存 |
RDB 保存 / AOF rewrite | 用子進程執行,避免阻塞主線程 |
key 過期處理 | 一部分定時觸發,一部分惰性刪除(在主線程) |
三、Redis 單線程的好處
你可能會問:為啥不多線程執行命令呢?
因為 Redis 的核心數據結構很復雜(如 ziplist、skiplist、hashtable),加鎖會帶來:
-
? 上下文切換成本
-
? 鎖競爭
-
? 不可預測的并發 Bug
👉 單線程讓它保持 高性能 + 數據一致性 + 代碼極簡
?