這篇文章主要介紹“redis在高并發(fā)下的性能講解”,在日常操作中,相信很多人在redis在高并發(fā)下的性能講解問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對(duì)大家解答”redis在高并發(fā)下的性能講解”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司服務(wù)緊隨時(shí)代發(fā)展步伐,進(jìn)行技術(shù)革新和技術(shù)進(jìn)步,經(jīng)過10余年的發(fā)展和積累,已經(jīng)匯集了一批資深網(wǎng)站策劃師、設(shè)計(jì)師、專業(yè)的網(wǎng)站實(shí)施團(tuán)隊(duì)以及高素質(zhì)售后服務(wù)人員,并且完全形成了一套成熟的業(yè)務(wù)流程,能夠完全依照客戶要求對(duì)網(wǎng)站進(jìn)行成都做網(wǎng)站、成都網(wǎng)站建設(shè)、建設(shè)、維護(hù)、更新和改版,實(shí)現(xiàn)客戶網(wǎng)站對(duì)外宣傳展示的首要目的,并為客戶企業(yè)品牌互聯(lián)網(wǎng)化提供全面的解決方案。前言:
最近上手了一個(gè)項(xiàng)目,我負(fù)責(zé)該項(xiàng)目的架構(gòu)設(shè)計(jì)與實(shí)現(xiàn)。本來公司做了很多給公司以外的人使用的API,但是在外人使用的時(shí)候,接口的鏈接是怎樣就給別人怎么樣,沒有加密也沒有做并發(fā)控制,接口程序所在的機(jī)器在哪,給別人的IP就在哪,而且沒有平臺(tái)進(jìn)行管理。因此我清楚地知道,這些接口的價(jià)值很難被發(fā)現(xiàn)(哪個(gè)接口別人用的比較多,哪個(gè)接口別人用的比較少)。
僅僅針對(duì)”監(jiān)控“的這一需求,我們引入了redis作為中間層,首先我們完善了用戶使用接口的注冊流程,通過用戶信息和地址,hash出一個(gè)key,這個(gè)key是對(duì)應(yīng)著一個(gè)地址的,把這個(gè)(key - 地址)對(duì)存在了redis里面。其次是nginx,nginx在我們的項(xiàng)目里面的流程大概是這樣:
1、用戶注冊之后獲取到他的key,通過包含了key的跟原本的url完全不同的url來訪問
2、nginx捕獲到用戶特殊的key,然后程序根據(jù)這個(gè)key從redis中取出目標(biāo)地址,再由nginx代替用戶訪問真正的地址,繼而返回。
(這個(gè)過程好處是很多的)
(1)、隱藏了真實(shí)的地址,程序可以在上游服務(wù)器之外的地方干預(yù)用戶的訪問,提高安全性,干預(yù)過程可以很復(fù)雜
(2)、獲取用戶的信息,并將其存回redis,上游服務(wù)器通過定時(shí)程序?qū)⒋嬖趓edis中的日志持久化進(jìn)oracle并刪除,然后進(jìn)一步分析和可視化
問題來了
這個(gè)項(xiàng)目還處于測試階段,資源是一臺(tái)window server 服務(wù)器,和centos6.5服務(wù)器,測試階段10秒內(nèi)大概有10萬的并發(fā)量,剛部署上去的一兩天還是沒有問題的,接下來卻出現(xiàn)了redis連接不上的情況。查看進(jìn)程訪問,會(huì)出現(xiàn)下面的情況。(window server 下)
出現(xiàn)很多FiN_WAIT_2的TCP鏈接。
(學(xué)習(xí)視頻分享:redis視頻教程)
分析
一、redis是使用單線程處理連接的,意味著它絕對(duì)會(huì)出現(xiàn)下面二所說的情況。
二、很明顯這是由于nginx和redis之間有很多沒有釋放的資源造成的,查看這個(gè)TCP的狀態(tài)FIN_WAIT_2,解釋一下:
在HTTP應(yīng)用中,存在一個(gè)問題,SERVER由于某種原因關(guān)閉連接,如KEEPALIVE的超時(shí),這樣,作為主動(dòng)關(guān)閉的SERVER一方就會(huì)進(jìn)入 FIN_WAIT2狀態(tài),但TCP/IP協(xié)議棧有個(gè)問題,F(xiàn)IN_WAIT2狀態(tài)是沒有超時(shí)的(不象TIME_WAIT狀態(tài)),所以如果CLIENT不關(guān)閉,這個(gè)FIN_WAIT_2狀態(tài)將保持到系統(tǒng)重新啟動(dòng),越來越多的FIN_WAIT_2狀態(tài)會(huì)致使內(nèi)核crash。
好吧,大學(xué)沒有好好念書,下面是http連接的狀態(tài)變化
客戶端狀態(tài)遷移
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSEDb.
服務(wù)器狀態(tài)遷移
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
有缺陷的客戶端與持久連接
有一些客戶端在處理持久連接(akakeepalives)時(shí)存在問題。當(dāng)連接空閑下來服務(wù)器關(guān)閉連接時(shí)(基于KeepAliveTimeout指令),
客戶端的程序編制使它不發(fā)送FIN和ACK回服務(wù)器。這樣就意味著這個(gè)連接 將停留在FIN_WAIT_2狀態(tài)直到以下之一發(fā)生:
客戶端為同一個(gè)或者不同的站點(diǎn)打開新的連接,這樣會(huì)使它在該個(gè)套接字上完全關(guān)閉以前的連接。
用戶退出客戶端程序,這樣在一些(也許是大多數(shù)?)客戶端上會(huì)使操作系統(tǒng)完全關(guān)閉連接。
FIN_WAIT_2超時(shí),在那些具有FIN_WAIT_2狀態(tài)超時(shí)設(shè)置的服務(wù)器上。
如果你夠幸運(yùn),這樣意味著那些有缺陷的客戶端會(huì)完全關(guān)閉連接并釋放你服務(wù)器的資源。
然而,有一些情況下套接字永遠(yuǎn)不會(huì)完全關(guān)閉,比如一個(gè)撥號(hào)客戶端在關(guān)閉客戶端程序之前從ISP斷開。
此外,有的客戶端有可能空置好幾天不創(chuàng)建新連接,并且這樣在好幾天里保持著套接字的有效即使已經(jīng)不再使用。這是瀏覽器或者操作系統(tǒng)的TCP實(shí)現(xiàn)的Bug。
產(chǎn)生原因有:
1、長連接并且當(dāng)連接一直處于IDLE狀態(tài)導(dǎo)致SERVERCLOSE時(shí),CLIENT編程缺陷,沒有向SERVER 發(fā)出FIN和ACK包
2、APACHE1.1和APACHE1.2增加了linger_close()函數(shù),前面的帖子有介紹,這個(gè)函數(shù)可能引起了這個(gè)問題(為什么我也不清楚)
解決辦法:
1。對(duì)FIN_WAIT_2狀態(tài)增加超時(shí)機(jī)制,這個(gè)特性在協(xié)議里沒有體現(xiàn),但在一些OS中已經(jīng)實(shí)現(xiàn)
如:LINUX、SOLARIS、FREEBSD、HP-UNIX、IRIX等
2。不要用linger_close()編譯
3。用SO_LINGER代替,這個(gè)在某些系統(tǒng)中還能很好地處理
4。增加用于存儲(chǔ)網(wǎng)絡(luò)連接狀態(tài)的內(nèi)存mbuf,以防止內(nèi)核crash
5。DISABLE KEEPALIVE
針對(duì)這種情況,我們做了幾次討論,有些結(jié)論,分別是:
1、設(shè)置nginx與redis的連接池,keepalive的時(shí)間,分別設(shè)為10秒,5秒,但是結(jié)果還是一樣
2、不用keepalive,即不使用連接池,即每次用完就close()掉,你可以看到連接少了,但是不使用連接池,意味著10秒內(nèi)要打開關(guān)閉10萬次,開銷太大
3、redis集群,在原本集群的體系上添加redis的集群,這或許能解決問題,但是10秒內(nèi)10萬實(shí)際上并不多,這樣做了或許是取巧,并沒有找到問題
4、設(shè)置redis的idle(空閑)時(shí)間限制,結(jié)果一樣。
解決方案:
實(shí)際上不算解決方案,因?yàn)榉艞壛藃edis的內(nèi)存機(jī)制,而是使用nginx本身的內(nèi)存技術(shù)。網(wǎng)上關(guān)于redis的優(yōu)化大部分不適用,這個(gè)問題有待分析解決。
到此,關(guān)于“redis在高并發(fā)下的性能講解”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!