03 高性能IO模型:採用多路復用機制的「單線程」Redis
本篇重點
三個問題:
「Redis真的只有單線程嗎?」
「為什麼用單線程?」
「單線程為什麼這麼快?」
- 「Redis真的只有單線程嗎?」
- 否,「單線程」指的是Redis的網絡IO和鍵值對讀寫是由一個線程完成的[1]
- Redis的其他功能由額外線程完成:持久化、異步刪除、集群數據同步等
- 網絡IO和鍵值對讀寫即Socket編程中的如下步驟
- 網絡IO:bind/listen、accept、parse、send/recv
- KV讀寫:GET/PUT…
- 「Redis為什麼用單線程?」
- 多線程的開銷:共享資源的並發訪問控制,互斥鎖等待,導致並轉串
- 「單線程Redis為什麼那麼快?」
- 大部分操作在內存完成(硬件速度)
- 高效數據結構(哈希表、跳錶等)
- IO多路復用機制:使其在網絡IO中能並發處理大量客戶端請求,實現高吞吐率
- 多路復用機制
網絡操作的基本IO模型、潛在阻塞點(Redis採用單線程IO,若被阻塞將無法進行多路復用)
-
基本IO模型:
-
阻塞點:
accept()、recv()、send()
-
Socket網絡模型本身支持非阻塞模式
調用方法 | 返回套接字類型 | 非阻塞模式 | 效果 |
---|---|---|---|
socket() | 主動套接字 | ||
listen() | 監聽套接字 | 可設置 | accept()非阻塞 |
accept() | 已連接套接字 | 可設置 | send()/recv()非阻塞 |
- 基於多路復用的高性能IO模型
- Linux多路復用機制——一個線程處理多個IO流,如
select/epoll
- 基於多路復用的Redis高性能IO模型
- 在請求到達時,如何通知到Redis線程?
基於事件的回調機制(select/epoll提供)
事件被放入事件隊列,Redis單線程對該事件隊列進行處理。
QA
「Redis基本IO模型」中的潛在性能瓶頸?
圖片來源於極客時間專欄《Redis核心技術與實戰》
-
Redis6.0開始,將網絡IO和鍵值對讀寫分開處理——網絡請求解析線程(支持網絡快速讀寫)、讀寫處理(主線程) ↩︎