03 高性能IO模型:採用多路復用機制的「單線程」Redis

本篇重點

三個問題:

「Redis真的只有單線程嗎?」
「為什麼用單線程?」
「單線程為什麼這麼快?」

  1. 「Redis真的只有單線程嗎?」
  • 否,「單線程」指的是Redis的網絡IO和鍵值對讀寫是由一個線程完成的[1]
  • Redis的其他功能由額外線程完成:持久化、異步刪除、集群數據同步等
  • 網絡IO和鍵值對讀寫即Socket編程中的如下步驟
    • 網絡IO:bind/listen、accept、parse、send/recv
    • KV讀寫:GET/PUT…
      basicIO
  1. 「Redis為什麼用單線程?」
  • 多線程的開銷:共享資源的並發訪問控制,互斥鎖等待,導致並轉串
  1. 「單線程Redis為什麼那麼快?」
  • 大部分操作在內存完成(硬件速度)
  • 高效數據結構(哈希表、跳錶等)
  • IO多路復用機制:使其在網絡IO中能並發處理大量客戶端請求,實現高吞吐率
  1. 多路復用機制

網絡操作的基本IO模型、潛在阻塞點(Redis採用單線程IO,若被阻塞將無法進行多路復用)

  • 基本IO模型:
    basicIO

  • 阻塞點:accept()、recv()、send()

  • Socket網絡模型本身支持非阻塞模式

調用方法 返回套接字類型 非阻塞模式 效果
socket() 主動套接字
listen() 監聽套接字 可設置 accept()非阻塞
accept() 已連接套接字 可設置 send()/recv()非阻塞
  1. 基於多路復用的高性能IO模型
  • Linux多路復用機制——一個線程處理多個IO流,如select/epoll
  • 基於多路復用的Redis高性能IO模型
    RedisIO
  • 在請求到達時,如何通知到Redis線程?

    基於事件的回調機制(select/epoll提供)
    事件被放入事件隊列,Redis單線程對該事件隊列進行處理。

QA

「Redis基本IO模型」中的潛在性能瓶頸?

圖片來源於極客時間專欄《Redis核心技術與實戰》


  1. Redis6.0開始,將網絡IO和鍵值對讀寫分開處理——網絡請求解析線程(支持網絡快速讀寫)、讀寫處理(主線程) ↩︎

Tags: