03.執行緒模型

navyum發表於2024-10-28

誤解:redis只有一個執行緒

  • Redis 的網路IO鍵值對讀寫是由一個執行緒(主執行緒)來完成的(Redis6.0 網路IO改為多執行緒模型)
  • Redis的其他功能,比如持久化非同步刪除叢集資料同步等,其實是由額外的執行緒執行的。

為什麼用單執行緒:

  1. 多執行緒開銷問題
  2. 多執行緒併發競爭問題,需要引入同步原語或者鎖機制(主要是一些寫操作) (此處沒有很好解釋原因,而是用多執行緒缺點來闡述,不夠嚴謹)

為什麼用單執行緒還這麼快:

  1. 大部分操作在記憶體
  2. 使用了IO多路複用(Redis6.0之後採用多執行緒模型處理網路IO請求)

redis常見的效能瓶頸問題:

  1. 請求耗時嚴重時,會影響整個server的效能。例如:
    • 操作bigkey:寫入一個bigkey在分配記憶體時需要消耗更多的時間,同樣,刪除bigkey釋放記憶體同樣會產生耗時
    • 使用複雜度過高的命令:例如一次查詢全量資料;
    • 大量key集中過期:Redis的過期機制也是在主執行緒中執行的,大量key集中過期會導致處理一個請求時,耗時都在刪除過期key,耗時變長;
    • 淘汰策略:淘汰策略也是在主執行緒執行的,當記憶體超過Redis記憶體上限後,每次寫入都需要淘汰一些key,也會造成耗時變長;
    • AOF刷盤開啟always機制:每次寫入都需要把這個操作刷到磁碟。寫磁碟的速度遠比寫記憶體慢,會拖慢Redis的效能;
    • 主從全量同步生成RDB:雖然採用fork子程序生成資料快照,但fork這一瞬間也是會阻塞整個執行緒的,例項越大阻塞時間越久;
  2. 併發請求量非常大時,單執行緒讀寫客戶端IO資料存在效能瓶頸
    • 雖然採用IO多路複用機制,但是讀寫客戶端資料依舊是同步IO,只能單執行緒依次讀取客戶端的資料,無法利用到CPU多核。

瓶頸問題解決方案:

  • 針對問題1:
    • 透過業務人員規避
    • Redis4.0 推出了lazy-free機制,把bigkey釋放記憶體的耗時操作放在了非同步執行緒中執行,降低對主執行緒的影響。
  • 針對問題2:
    • Redis6.0 推出了多執行緒網路IO模型,可以在高併發場景下利用CPU多核多執行緒讀寫客戶端資料。但只針對客戶端的讀寫是並行的,每個命令的真正操作依舊是單執行緒的。

相關文章