redis為何如此之快
- Redis基本是內(nèi)存操作,所以速度很快
內(nèi)存:
1. 尋址時(shí)間:納秒級(jí)別ns
2. 帶寬:很大
磁盤(pán):
1. 尋址時(shí)間:毫秒級(jí)別ms
2. 帶寬:G/M
磁盤(pán)比內(nèi)存尋址慢了10W倍以上,所以單機(jī)Redis能支持每秒10W以上的請(qǐng)求
- Redis通信采用非阻塞IO, 內(nèi)部實(shí)現(xiàn)采用epolll+自己實(shí)現(xiàn)的簡(jiǎn)單的事件框架。epoll中的讀、寫(xiě)、關(guān)閉、連接都轉(zhuǎn)化成了事件,然后利用epoll的多路復(fù)用特性,絕不在io上浪費(fèi)一點(diǎn)時(shí)
- 單機(jī)Redis采用單進(jìn)程、單線程、單實(shí)例,避免了不必要的上下文切換和競(jìng)爭(zhēng)條件
可能很多人認(rèn)為要想系統(tǒng)處理速度快不是應(yīng)該使用多線程技術(shù)。但其實(shí)Redis的數(shù)據(jù)都是放在內(nèi)存中,查詢(xún)存儲(chǔ)都延時(shí)都非常小,是納秒級(jí)別的,所以如果使用多線程,就需要加鎖,系統(tǒng)資源還需要耗費(fèi)在線程之間上下文切換上面,反而會(huì)影響性能。單進(jìn)程、單線程天生就保證了請(qǐng)求的順序執(zhí)行,不需要加鎖,也沒(méi)有了不必要的上下文切換,因此可以將硬件的性能發(fā)揮到極致
這3個(gè)條件不是相互獨(dú)立的,特別是第一條,如果請(qǐng)求都是耗時(shí)的,采用單線程吞吐量及性能可想而知了。應(yīng)該說(shuō)Redis為特殊的場(chǎng)景選擇了合適的技術(shù)方案。
Epoll的高性能如何成就Redis
I/O模型 BIO、NIO、多路復(fù)用I/O、AIO
1. 阻塞I/O(Blocking I/O BIO)
應(yīng)用程序進(jìn)程/線程如果發(fā)起1K個(gè)請(qǐng)求,則開(kāi)啟1K個(gè)socket文件描述符,socket在等待內(nèi)核返回?cái)?shù)據(jù)時(shí)是阻塞式的,數(shù)據(jù)未準(zhǔn)備好就一直阻塞等待,一次只會(huì)返回一個(gè)socket結(jié)果,直到返回?cái)?shù)據(jù)后才等待下一個(gè)socket的返回
2. 輪詢(xún)非阻塞I/O(Non-Blocking I/O NIO)
應(yīng)用進(jìn)程如果發(fā)起1K個(gè)請(qǐng)求,則在用戶(hù)空間不停輪詢(xún)這1K個(gè)socket文件描述符,查看是否有結(jié)果返回。這種方法雖然不阻塞,但是效率太低,有大量無(wú)效的循環(huán)
3. 多路復(fù)用I/O(Multiplexing I/O)
select: 能打開(kāi)的文件描述符個(gè)數(shù)有限(最多1024個(gè)),如果有1K個(gè)請(qǐng)求,用戶(hù)進(jìn)程每次都要把1K個(gè)文件描述符發(fā)送給內(nèi)核,內(nèi)核在內(nèi)部輪詢(xún)后將可讀描述符返回,用戶(hù)進(jìn)程再依次讀取。因?yàn)槲募枋龇╢d)相關(guān)數(shù)據(jù)需要在用戶(hù)態(tài)和內(nèi)核態(tài)之間拷來(lái)拷去,所以性能還是比較低
poll:可打開(kāi)的文件描述符數(shù)量提高,但性能仍然不夠
epoll(linux下多為該技術(shù)):用戶(hù)態(tài)和內(nèi)核態(tài)之間不用文件描述符(fd)的拷貝,而是通過(guò)mmap技術(shù)開(kāi)辟共享空間,所有fd用紅黑樹(shù)存儲(chǔ),有返回結(jié)果的fd放在鏈表中,用戶(hù)進(jìn)程通過(guò)鏈表讀取返回結(jié)果,偽異步I/O,性能較高。epoll分為水平觸發(fā)和邊緣出發(fā)兩種模式,ET是邊緣觸發(fā),LT是水平觸發(fā),一個(gè)表示只有在變化的邊際觸發(fā),一個(gè)表示在某個(gè)階段都會(huì)觸發(fā)
4. 異步I/O AIO
AIO:異步I/O,性能最高,但是使用非常復(fù)雜,不是很常用(windows系統(tǒng)中多見(jiàn))






