久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

redis屬于單線程還是多線程

139次閱讀
沒有評論

共計 3514 個字符,預計需要花費 9 分鐘才能閱讀完成。

自動寫代碼機器人,免費開通

丸趣 TV 小編給大家分享一下 redis 屬于單線程還是多線程,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Redis4.0 之前是單線程運行的;Redis4.0 后開始支持多線程。Redis4.0 之前使用單線程的原因:1、單線程模式方便開發和調試;2、Redis 內部使用了基于 epoll 的多路復用;3、Redis 主要的性能瓶頸是內存或網絡帶寬。

不同版本的 Redis 是不同的,在 Redis4.0 之前,Redis 是單線程運行的,但單線程并不代表效率低,像 Nginx、Nodejs 也是單線程程序,但是它們的效率并不低。

原因是 Redis 是基于內存的,它的瓶頸在于機器的內存、網絡帶寬,而不是 CPU,在 CPU 還沒達到瓶頸時機器內存可能就滿了、或者帶寬達到瓶頸了。因此 CPU 不是主要原因,那么自然就采用單線程了,況且使用多線程比較麻煩。

但是在 Redis4.0 的時候,已經開始支持多線程了,比如后臺刪除等功能。

簡單來說,Redis 在 4.0 之前使用單線程的模式是因為以下三個原因:

使用單線程模式的 Redis,其開發和維護更簡單,因為單線程模式方便開發和調試。

即使使用單線程模型也能夠并發地處理多客戶端的請求,主要是因為 Redis 內部使用了基于 epoll 的多路復用。

對于 Redis 來說,主要的性能瓶頸是內存或網絡帶寬,而非 CPU。

但 Redis 在 4.0 以及之后的版本中引入了惰性刪除(也叫異步刪除),意思就是我們可以使用異步的方式對 Redis 中的數據進行刪除操作,例如:

unlink key:和 del key 類似,刪除指定的 key,若 key 不存在則 key 被跳過。但是 del 會產生阻塞,而 unlink 命令會在另一個線程中回收內存,即它是非阻塞的【http://www.redis.cn/commands/unlink.html】;

flushdb async:刪除當前數據庫的所有數據【http://www.redis.cn/commands/flushdb.html】;

flushall async:刪除所有庫中的數據【http://www.redis.cn/commands/flushall.html】。

這樣處理的好處是不會使 Redis 的主線程卡頓,會把這些操作交給后臺線程來執行。

【通常情況下使用 del 指令可以很快的刪除數據,但是當被刪除的 key 是一個非常大的對象時,例如:刪除的時包含成千上萬個元素的 hash 集合時,那么 del 指令就會造成 Redis 主線程卡頓,因此使用惰性刪除可以有效避免 Redis 卡頓問題。】

考點分析:

關于 Redis 線程模型的問題(單線程或多線程)幾乎是 Redis 必問的問題之一,但回答好的人卻不多,大部分只能回答上來 Redis 是單線程的以及說出來單線程的眾多好處,但對于 Redis4.0 和 Redis6.0 中,尤其是 Redis6.0 中多線程的特點,能夠準確回答上來的人非常少。關于單線程和多線程的相關知識,還有以下面試題。

1.Redis 主線程既然是單線程,為什么還這個快?

2. 介紹一下 Redis 中的 IO 多路復用?

3. 介紹一下 Redis6.0 中的多線程?

1.Redis 為什么這么快?

原因有以下幾點:

a. 基于內存操作:Redis 的所有數據都存在內存中,因此所有的運算都是內存級別的,所以它的性能比較高。

b. 數據結構簡單:Redis 的數據結構比較簡單,是為 Redis 專門設計的,而這些簡單的數據結構的查找和操作的時間復雜度都是 O(1)。

c. 多路復用和非阻塞 IO:Redis 使用 IO 多路復用功能來監聽多個 socket 連接的客戶端,這樣就可以使用一個線程來處理多個情況,從而減少線程切換帶來的開銷,同時也避免了 IO 阻塞操作,從而大大提高了 Redis 的性能。

d. 避免上下文切換:因為是單線程模型,因此就避免了不必要的上下文切換和多線程競爭,這就省去了多線程切換帶來的時間和性能上的開銷,而且單線程不會導致死鎖的問題發生。

官方使用的基準測試結果表明,單線程的 Redis 可以達到 10W/ S 的吞吐量。

2.IO 多路復用是什么?

套接字的讀寫方法默認是阻塞的,例如當調用讀取操作 read 方法時,緩沖區沒有任何數據,那么這個線程會卡在這里,直到緩沖區有數據或者連接被關閉時,read 方法才會返回,該線程才能繼續處理其他業務。

但這樣顯然就降低了程序的執行效率,而 Redis 使用的時非阻塞的 IO,這就意味著 IO 的讀寫流程不再是阻塞的,讀寫方法都是瞬間完成并且返回的,也就是它會采用能讀多少就讀多少、能寫多少就寫多少的策略來執行 IO 操作,這顯然更符合我們對性能的追求。

但這種非阻塞的 IO 也面臨一個問題,那就是當我們執行讀取操作時,有可能只讀取了一部分數據;同理寫數據也是這種情況,當緩沖區滿了,而我們的數據還沒有寫完,那么生效的數據何時寫就成了一個問題。

而 IO 的多路復用就是解決上面的這個問題的,使用 IO 多路復用最簡單的方式就是使用 select 函數,此函數是操作系統提供給用戶程序的 API 接口,用于監控多個文件描述符的可讀和可寫情況的,這樣就可以監控到文件描述符的讀寫事件了。當監控到相應的時間之后就可以通知線程處理相應的業務了,這樣就保證了 Redis 讀寫功能的正常執行。

【不過現在的操作系統已經基本上不適用 select 函數了,改為調用 epoll 函數(Linux)了,macOS 則是使用 Kqueue(繼承與 Unix),因為 select 函數在文件描述符非常多的時候性能非常差?!?/p>

3.Redis6.0 中的多線程?

Redis 單線程的優點非常,不但降低了 Redis 內部實現的負責性,也讓所有操作都可以在無鎖的情況下進行,并且不存在死鎖和線程切換帶來的性能以及時間上的消耗;但是其缺點也很明顯,單線程機制導致 Redis 的 QPS(Query Per Second,每秒查詢數)很難得到有效的提高(雖然夠快了,但人畢竟還是要有更高的追求的)。

Redis 在 4.0 版本中雖然引入了多線程,但是此版本的多線程只能用于大數據量的異步刪除,對于非刪除操作的意義并不是很大。

如果我們使用 Redis 多線程就可以分攤 Redis 同步讀寫 IO 的壓力,以及充分利用多核 CPU 資源,并且可以有效的提升 Redis 的 QPS。在 Redis 中雖然使用了 IO 多路復用,并且是基于非阻塞的 IO 進行操作的,但是 IO 的讀寫本身是阻塞的。比如當 socket 中有數據時,Redis 會先將數據從內核態空間拷貝到用戶態空間,然后再進行相關操作,而這個拷貝過程是阻塞的,并且當數據量越大時拷貝所需要的的時間就越多,而這些操作都是基于單線程完成的。

因此在 Redis6.0 中新增了多線程的功能來提高 IO 的讀寫性能,它的主要實現思路是將主線程的 IO 讀寫任務拆分給一組獨立的線程去執行,這樣就可以使用多個 socket 的讀寫并行化了,但 Redis 的命令依舊是主線程串行執行的。

但是注意:Redis6.0 是默認禁用多線程的,但可以通過配置文件 redis.conf 中的 io-threads-do-reads 等于 true 來開啟。但是還不夠,除此之外我們還需要設置線程的數量才能正確地開啟多線程的功能,同樣是修改 Redis 的配置,例如設置 io-threads 4,表示開啟 4 個線程。

【關于線程數的設置,官方的建議是如果為 4 核 CPU,那么設置線程數為 2 或 3;如果為 8 核 CPU,那么設置線程數為 6. 總之線程數一定要小于機器的 CPU 核數,線程數并不是越大越好?!?/p>

關于 Redis 的性能,Redis 的作者在 2019 年的 RedisConf 大會上提到,Redis6.0 引入的多線程 IO 特性對性能的提升至少是一倍以上。國人也有在阿里云使用 4 個線程的 Redis 版本和單線程的 Redis 進行比較測試,發現測試結果和 Redis 作者說的一致,性能基本可以提高一倍。

總結:

本文介紹了 Redis 在 4.0 之前單線程依然快的原因:基于內存操作、數據結構簡單、IO 多路復用和非阻塞 IO、避免了不必要的線程上下文切換。并且在 Redis4.0 開始支持多線程,主要體現在大數據的異步刪除方面,例如:unlink key、flushdb async、flushall async 等。而 Redis6.0 的多線程則增加了對 IO 讀寫的并發能力,用于更好的提升 Redis 的性能。

以上是“redis 屬于單線程還是多線程”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注丸趣 TV 行業資訊頻道!

向 AI 問一下細節

丸趣 TV 網 – 提供最優質的資源集合!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-12-18發表,共計3514字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 潼关县| 永城市| 岫岩| 临潭县| 久治县| 天峻县| 揭西县| 建平县| 萨迦县| 九江县| 灌南县| 宁蒗| 疏勒县| 皋兰县| 三江| 焉耆| 界首市| 施甸县| 蓬安县| 望奎县| 双柏县| 龙海市| 珠海市| 吉木乃县| 江安县| 会昌县| 繁昌县| 石台县| 博客| 肇州县| 疏勒县| 新化县| 卓资县| 达拉特旗| 沈阳市| 淄博市| 库尔勒市| 岱山县| 长岭县| 财经| 弥渡县|