天天看點

redis6.4 多線程

resid要處理指令,則redis必須完整地接收用戶端的請求,并将指令解析出來,再将結果讀出來,通過網絡回寫到用戶端。整個工序分為以下幾個部分:

  • 接收。通過TCP接收到指令,可能會曆經多次TCP包、ack、IO操作
  • 解析。将指令取出來
  • 執行。到對應的地方将value讀出來
  • 傳回。将value通過TCP傳回給用戶端,如果value較大,則IO負荷會更重

異步的效率更高,要實作高并發必須要異步,因為同步有太多時間浪費在等待上了,遇到網絡不好的用戶端直接就被拖垮。異步的政策簡單可總結如下:

  • 網絡包有資料了,就去讀一下放到緩沖區,讀完立馬切到其他事情上,不等下一個包
  • 解析下緩沖區資料是否完整。如完整則執行指令,不完整切到其他事情上
  • 資料完整了,立即執行指令,将執行結果放到緩沖區
  • 将資料給用戶端,如果一次給不完,就等下次能給時再給,不等,直到全部給完

事件驅動

異步沒有零散的等待,但有個問題是,如果redis不一直阻塞等指令來,咋個知道“網絡包有資料了”、“下次能給時”這兩個時機? 如果一直去輪訓問肯定效率很低,要有個高效的機制,來通知redis這兩個時刻,由這些時刻來觸發動作。 這就是事件驅動。

一個tcp包來了、有資料可以寫給用戶端 這兩個時機都是事件。與之對應的就是redis和用戶端之間socket的可讀、可寫事件[1] ,就像微信聊天中新消息提醒一樣。 linux中的epoll就是幹這個事的,redis基于epoll等機制抽象出了一套事件驅動架構[2],整個server完全由事件驅動,有事件發生就處理,沒有就空閑等待。

redis6多線程主要解決 socket 可讀可寫的網絡IO等待,指令的執行還是單線程處理