亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis中線程IO模型是什么

發布時間:2021-12-21 10:33:01 來源:億速云 閱讀:276 作者:小新 欄目:關系型數據庫

這篇文章將為大家詳細講解有關Redis中線程IO模型是什么,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

Redis是一個單線程的應用程序,NodeJs、Nginx都是單線程,它們都屬于服務器高性能的典范。

Redis之所以是單線程還能這么快的原因:

其一是因為它所有的數據都在內存當中,所有的運算都是內存級別的運算,所以使用redis時,要注意時間復雜度為O(n)的指令,因為是單線程的,如果數據量太大,會讓其他指令被阻塞等待;

其二是因為redis使用非阻塞IO與多路復用處理大量的客戶端連接。

非阻塞IO

當我們使用套接字的讀寫方法時,默認是阻塞的,

即調用read方法傳遞一個參數n,表示最多讀取n個字節后返回,如果一個字節都沒有,線程就會在read方法這里持續等待,直到有數據過來或者連接被關閉,read方法此時返回,線程才能執行下面的邏輯,

write方法一般不會阻塞,除非內核為套接字分配的寫緩沖區滿了,write方法才會阻塞,一直到緩存區中有空間閑出來。

下圖是套接字讀寫的細節流程。

Redis中線程IO模型是什么

非阻塞IO在使用套接字時提供了一個選項Non_Blocking,當這個選項打開時,讀寫方法不會阻塞,而是能讀多少讀多少,能寫多少寫多少,

能讀多少取決與內核為套接字分配的讀緩沖區的數據字節數,能寫多少取決于內核為套接字寫緩沖區分配的數據字節數,

讀寫方法都會通過返回值告訴程序讀寫了多少字節數。

非阻塞IO意味著讀寫時,線程不必再被阻塞著,讀寫可以瞬間完成,線程可以繼續往下做別的事情。

多路復用(事件輪詢)

非阻塞IO雖然很快,但是也帶來一個問題,線程讀數據,讀了一部分就返回了,沒有讀完,剩下的數據何時繼續讀?,寫數據,緩沖區滿了,沒有寫完,剩下的數據何時繼續寫?

當可以繼續讀或者可以繼續寫時,應該給應用程序一個通知,告訴應用程序可以繼續讀或者繼續寫,事件輪詢API就是用來處理這個問題的。

select

操作系統提供了一個select函數給用戶程序,輸入是讀寫描述符列表 read_fds & write_fds,輸出是與之對應的可讀可寫事件,

同時還提供了timeout參數,線程最多等待timeout的時間,在這期間有事件過來,方法立刻返回,線程往下處理,如果超過timeout時間,方法也會返回,

如果拿到事件了,線程即可挨個處理相應的事件,處理完了以后繼續調用 select api 輪詢,所以該線程其實是一個死循環,不停的 select,不停的處理,來回這樣,這個死循環被稱之為事件循環,一個循環即一個周期。

Redis中線程IO模型是什么

事件循環偽代碼:

while True
    read_events, write_events = select(read_fds, write_fds, timeout)
    for event in read_events:
        handle_read(event.fd)
    for event in write_events:
        handle_write(event.fd)
    handle_others() # 做其他的邏輯處理,處理定時任務等等

通過select函數我們可以處理多個通道描述符的讀寫事件,所以將select這類的系統函數調用稱之為多路復用API,

現代操作系統的多路復用API已經不使用select系統調用,改用epoll(linux)和kqueue(FreeBSD、macosx),

select的性能在描述符變多時會變得很差,epoll與select使用起來略有差異,不過都可以用上面的偽代碼理解,都是當描述符發生事件時,循環對描述符的事件做出處理,

serversocket對象的讀操作是指調用accept接受客戶端新連接,何時有連接來臨,也是通過select調用的讀事件通知的。

Java中的NIO技術就是事件輪詢,其他語言也有這個技術。

指令隊列

Redis為每一個客戶端套接字關聯一個指令隊列,客戶端發來的指令通過隊列進行先進先出的順序處理。

響應隊列

同樣Redis返回的結果也通過為每個客戶端關聯的一個隊列返回,如果隊列為空,則暫時不需要去獲取寫事件,

此時會將該客戶端描述符從write_fds里移除,等隊列有數據的時候,再將描述符放進去,這樣可以避免select系統調用返回寫事件時,發現沒數據可寫,造成空輪詢、無用輪詢,對機器CPU的消耗。

定時任務

服務器不單要響應IO事件,有些其他的事情也需要處理,例如應用程序自身的定時任務,如果線程阻塞在select調用上,等待select的返回,這會造成有些定時任務到期了,卻沒有執行,

Redis的定時任務記錄在一個稱為 最小堆 的數據結構中,這個堆中,最快要執行的任務排在最上方,每個循環周期里,redis會對堆中已經到時間點的任務進行處理,

處理完畢后,將堆中即將要執行的任務還需要的時間記錄下來,再次調用select時,這個時間就是timeout的值,在這期間內不會有其他任務需要執行了,redis可以放心的最多阻塞這么久,然后到時間后進行相應的處理。

NodeJs和Nginx的事件處理原理和Redis也是類似的形式。

關于“Redis中線程IO模型是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昌邑市| 沧源| 南川市| 赣榆县| 博客| 千阳县| 丘北县| 乐至县| 望都县| 鄂伦春自治旗| 宝兴县| 池州市| 盐山县| 平利县| 莱西市| 长岭县| 乌拉特中旗| 伊宁县| 神池县| 武山县| 汉沽区| 五华县| 贺兰县| 靖宇县| 商城县| 喀什市| 大港区| 辽宁省| 鹿泉市| 朝阳市| 桐城市| 安溪县| 孙吴县| 辽中县| 巍山| 沅陵县| 青冈县| 鹤庆县| 泸溪县| 涿州市| 伊川县|