【Redis破障之路】三:Redis單線程架構

      網友投稿 588 2025-04-01

      眾所周知,Redis是一個單線程架構的NoSQL數據庫,但是是單線程模型的Redis為什么性能如此之高?這就是我們接下來要探究學習的內容。

      1、Redis的單線程架構

      1.1、Redis單線程簡介

      首先要明白,Redis的單線程指的是執行命令時的單線程。

      Redis客戶端與服務端的模型可以簡化成下圖,每次客戶端調用都經歷了發送命令、執行命令、返回結果三個過程。

      我們說的單線程就是在第二步執行命令,一條命令從從客戶端達到服務端不會立刻被執行,而是會進入一個隊列中等待,每次只會有一條指令被選中執行。

      發送命令、返回結果、命令排隊這些就不是那么簡單了,例如Redis使用了I/O多路復用技術來解決I/O的問題。

      1.2、Redis為什么要使用單線程

      這是官方的解釋:https://redis.io/topics/faq

      官方FAQ表示,因為Redis是基于內存的操作,CPU成為Redis的瓶頸的情況很少見,Redis的瓶頸最有可能是內存的大小或者網絡限制。

      如果想要最大程度利用CPU,可以在一臺機器上啟動多個Redis實例。

      值得一提的,網絡上存在這樣的觀點:吐槽官方的解釋有些敷衍,其實就是歷史原因,開發者嫌多線程麻煩,后來這個CPU的利用問題就被拋給了使用者。

      同時FAQ里還提到了, Redis 4.0 之后開始變成多線程,除了主線程外,它也有后臺線程在處理一些較為緩慢的操作,例如清理臟數據、無用連接的釋放、大 Key 的刪除等等。

      1.3、為什么單線程還能這么快

      通常來講,單線程處理能力要比多線程差,那么為什么Redis使用單線程模型會達到每秒萬級別的處理能力呢?可以將其歸結為三點:

      第一:純內存訪問,Redis將所有數據放在內存中,內存的響應時長大約為100納秒,這是Redis達到每秒萬級別訪問的最重要的基礎。

      【Redis破障之路】三:Redis單線程架構

      第二:非阻塞I/O,Redis使用epoll作為I/O多路復用技術的實現,再加上Redis自身的事件處理模型將epoll中的連接、讀寫、關閉都轉換為事件,不在網絡I/O上浪費過多的時間

      這里再擴展一下I/O多路復用:

      引用知乎上一個高贊的回答來解釋什么是I/O多路復用。假設你是一個老師,讓30個學生解答一道題目,然后檢查學生做的是否正確,你有下面幾個選擇:

      第一種選擇:按順序逐個檢查,先檢查A,然后是B,之后是C、D。。。這中間如果有一個學生卡主,全班都會被耽誤。這種模式就好比,你用循環挨個處理socket,根本不具有并發能力。

      第二種選擇:你創建30個分身,每個分身檢查一個學生的答案是否正確。 這種類似于為每一個用戶創建一個進程或者線程處理連接。

      第三種選擇,你站在講臺上等,誰解答完誰舉手。這時C、D舉手,表示他們解答問題完畢,你下去依次檢查C、D的答案,然后繼續回到講臺上等。此時E、A又舉手,然后去處理E和A。

      第一種就是阻塞IO模型,第三種就是I/O復用模型,Linux下的select、poll和epoll就是干這個的。將用戶socket對應的fd注冊進epoll,然后epoll幫你監聽哪些socket上有消息到達,這樣就避免了大量的無用操作。此時的socket應該采用非阻塞模式。

      這樣,整個過程只在調用select、poll、epoll這些調用的時候才會阻塞,收發客戶消息是不會阻塞的,整個進程或者線程就被充分利用起來,這就是事件驅動,所謂的reactor模式。

      第三:單線程避免了線程切換和競態產生的消耗。

      我們繼續來看Redis單線程卻很快的最后一條原因,在多線程開發中,存在線程的切換和競爭,這樣一來,是有時間的消耗的。對于需要磁盤I/O的程序來講,磁盤I/O是一個比較耗時的操作,所以對于需要進行磁盤I/O的程序,我們可以使用多線程,在某個線程進行I/O時,CPU切換到當前程序的其他線程執行,以此減少CPU的等待時間。

      那么問題來了。Redis的數據存放在內存中,將內存中的數據讀入CPU時,CPU不是依然需要等待嗎,為什么不能在等待數據從內存讀入CPU期間執行其他線程,以此提高CPU的使用率呢?這個問題的答案很簡單,內存的讀些速度雖然比CPU慢很多,但是也是非常快的。CPU切換線程需要花費一定的時間,而多次切換線程所花費的時間,可能比直接使用單線程執行相同的任務,花費的時間要更多,這是非常不劃算的。

      單線程也會有一個問題:對于每個命令的執行時間是有要求的。如果某個命令執行過長,會造成其他命令的阻塞,對于Redis這種高性能的服務來說是致命的,所以Redis是面向快速執行場景的數據庫

      2、支持多線程的Redis6.0

      “Redis不是單線程嗎?怎么又支持多線程了?”

      相信學到了這里,這已經不是一個問題了。

      Redis6.0引入了多線程的特性,這個多線程是在哪里呢?——是對處理網絡請求過程采用了多線程。

      Redis 6.0采用多個IO線程來處理網絡請求,網絡請求的解析可以由其他線程完成,然后把解析后的請求交由主線程進行實際的內存讀寫。提升網絡請求處理的并行度,進而提升整體性能。

      那么多并發的線程安全問題存在嗎?——當然不存在。

      Redis 的多 IO 線程只是用來處理網絡請求的,對于命令的執行,Redis 仍然使用單線程來處理。

      參考:

      【1】:《Redis開發與運維》

      【2】:支持多線程的Redis6.0來了

      【3】:為什么 Redis 選擇單線程模型

      【4】:Redis 和 I/O 多路復用

      【5】:I/O多路復用技術(multiplexing)是什么?

      【6】:一文搞懂I/O多路復用及其技術

      【7】:Redis為什么是單線程的

      Redis 任務調度 數據庫

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:自動駕駛已在來路上,汽車芯片“零缺陷”的根基在哪里?
      下一篇:擁抱互聯、融入智能,開啟智能制造新未來
      相關文章
      国精无码欧精品亚洲一区| 亚洲人成无码网站| 亚洲av不卡一区二区三区| 亚洲综合色在线观看亚洲| 亚洲精品高清在线| 18禁亚洲深夜福利人口| 亚洲精品乱码久久久久久蜜桃图片| 亚洲神级电影国语版| 亚洲成人网在线观看| 亚洲尤码不卡AV麻豆| 亚洲综合另类小说色区| 在线看亚洲十八禁网站| 久久无码av亚洲精品色午夜| 亚洲AV无码一区二区三区性色| 亚洲乱码av中文一区二区| 久久久久亚洲AV无码去区首| 亚洲AV无码一区二区三区久久精品 | 久久亚洲av无码精品浪潮| 国产亚洲美女精品久久久久| 最新亚洲人成无码网www电影| 亚洲Av永久无码精品一区二区| 亚洲爆乳AAA无码专区| 欧美亚洲精品一区二区| 国产精品亚洲专区在线播放 | 韩国亚洲伊人久久综合影院| 精品亚洲av无码一区二区柚蜜| 成人精品国产亚洲欧洲| 亚洲国产精品无码久久久久久曰| 亚洲无码精品浪潮| 在线观看亚洲天天一三视| 国产精品亚洲精品日韩已满| 亚洲国产国产综合一区首页| 亚洲精品综合一二三区在线| 亚洲欧洲日产国码二区首页| 亚洲av永久无码精品天堂久久| 亚洲精品国产日韩| 亚洲精品中文字幕麻豆| 亚洲天堂免费在线| 日韩国产欧美亚洲v片| 久久亚洲中文字幕精品一区| 欧洲亚洲国产清在高|