真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

redis屬于單線程還是多線程

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

成都創(chuàng)新互聯(lián)長期為近1000家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為蓮都企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,蓮都網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

Redis4.0之前是單線程運(yùn)行的;Redis4.0后開始支持多線程。Redis4.0之前使用單線程的原因:1、單線程模式方便開發(fā)和調(diào)試;2、Redis內(nèi)部使用了基于epoll的多路復(fù)用;3、Redis主要的性能瓶頸是內(nèi)存或網(wǎng)絡(luò)帶寬。

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

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

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

簡單來說,Redis在4.0之前使用單線程的模式是因?yàn)橐韵氯齻€原因:

  • 使用單線程模式的Redis,其開發(fā)和維護(hù)更簡單,因?yàn)閱尉€程模式方便開發(fā)和調(diào)試。

  • 即使使用單線程模型也能夠并發(fā)地處理多客戶端的請求,主要是因?yàn)镽edis內(nèi)部使用了基于epoll的多路復(fù)用。

  • 對于Redis來說,主要的性能瓶頸是內(nèi)存或網(wǎng)絡(luò)帶寬,而非CPU。

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

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

  • flushdb async:刪除當(dāng)前數(shù)據(jù)庫的所有數(shù)據(jù)【http://www.redis.cn/commands/flushdb.html】;

  • flushall async:刪除所有庫中的數(shù)據(jù)【http://www.redis.cn/commands/flushall.html】。

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

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

考點(diǎn)分析:

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

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

2.介紹一下Redis中的IO多路復(fù)用?

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

1.Redis為什么這么快?

原因有以下幾點(diǎn):

a.基于內(nèi)存操作:Redis的所有數(shù)據(jù)都存在內(nèi)存中,因此所有的運(yùn)算都是內(nèi)存級別的,所以它的性能比較高。

b.數(shù)據(jù)結(jié)構(gòu)簡單:Redis的數(shù)據(jù)結(jié)構(gòu)比較簡單,是為Redis專門設(shè)計(jì)的,而這些簡單的數(shù)據(jù)結(jié)構(gòu)的查找和操作的時間復(fù)雜度都是O(1)。

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

d.避免上下文切換:因?yàn)槭菃尉€程模型,因此就避免了不必要的上下文切換和多線程競爭,這就省去了多線程切換帶來的時間和性能上的開銷,而且單線程不會導(dǎo)致死鎖的問題發(fā)生。

官方使用的基準(zhǔn)測試結(jié)果表明,單線程的Redis可以達(dá)到10W/S的吞吐量。

2.IO多路復(fù)用是什么?

套接字的讀寫方法默認(rèn)是阻塞的,例如當(dāng)調(diào)用讀取操作read方法時,緩沖區(qū)沒有任何數(shù)據(jù),那么這個線程會卡在這里,直到緩沖區(qū)有數(shù)據(jù)或者連接被關(guān)閉時,read方法才會返回,該線程才能繼續(xù)處理其他業(yè)務(wù)。

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

但這種非阻塞的IO也面臨一個問題,那就是當(dāng)我們執(zhí)行讀取操作時,有可能只讀取了一部分?jǐn)?shù)據(jù);同理寫數(shù)據(jù)也是這種情況,當(dāng)緩沖區(qū)滿了,而我們的數(shù)據(jù)還沒有寫完,那么生效的數(shù)據(jù)何時寫就成了一個問題。

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

【不過現(xiàn)在的操作系統(tǒng)已經(jīng)基本上不適用select函數(shù)了,改為調(diào)用epoll函數(shù)(Linux)了,macOS則是使用Kqueue(繼承與Unix),因?yàn)閟elect函數(shù)在文件描述符非常多的時候性能非常差。】

3.Redis6.0中的多線程?

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

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

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

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

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

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

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

總結(jié):

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

以上是“redis屬于單線程還是多線程”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


文章名稱:redis屬于單線程還是多線程
文章來源:http://weahome.cn/article/ihpohs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部