Redis性能解析--Redis爲何那麼快?

echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微信號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這纔是真正的堪稱強大!!!redis


Redis的實際被應用都是由於它的性能,在衆多緩存中Redis也是一個比較快的中間件,並且它是單線程操做,沒有過的內存開銷,給程序帶來了更多的擴展空間。緩存

Redis的性能展現

在保證網絡通暢的狀況下,相同的CPU和相同的Redis版本,處理不一樣大小的數據,Redis的吞吐量以下圖所示,該圖來自Redis的官方網站。咱們能夠在網站中看到。Redis在處理1000字節的數據的時候,都是穩定位置吞吐量在10w,當處理的數據不斷增大的時候,吞吐量才慢慢開始降低。
在這裏插入圖片描述
圖片來自redis官網微信

下圖是提供的QPS測試圖,官方提供的數據是能夠達到100000+的QPS(每秒內查詢次數)。
在這裏插入圖片描述
圖片來自redis官網網絡

Redis爲何那麼快?

  • 純內存KV操做
  • 內部是單程實現的(不須要建立/銷燬線程,避免上下文切換,無併發資源競爭的問題)
  • 異步非阻塞的I/O(多路複用)

存內存KV操做快在哪裏?

咱們從上面的介紹裏面咱們看到了Redis是一個純kv的操做。而且Redis絕大部分請求是純粹的內存操做,因此速度很是快。數據存在內存中,類型與存在hashMap中,那麼爲何那麼快呢?咱們能夠一塊兒來看一下幾種經常使用數據結構的對比,和他們的優點。數據結構

數據結構 操做 時間複雜度
List insert O(N)
List select O(1)
Set insert O(1)
Set select O(1)
HashMap insert O(1)
HashMap select O(1)

從上圖咱們能夠看出,HashMap的優點就是查找和操做的時間複雜度都是O(1),因此Redis內部採用這種結構可以從根本上得到足夠的優點,當讓,Redis的快速不只僅是數據結構成就的,還有單程成和異步I/O多線程

Redis爲何使用單線程?

Redis使用單線程就夠了!咱們能夠看到下圖中官網的描述,Redis的使用瓶頸並非CPU,它主要受到內存和網絡的限制。例如,使用在通常Linux系統上運行的流水線Redis每秒能夠發送一百萬個請求,所以,若是您的應用程序主要使用O(N)或O(log(N))命令,則幾乎不會使用過多的CPU 。
在這裏插入圖片描述併發

從描述中咱們能夠看到,Redis在使用的時候,使用單線程就已經可以獲取Redis足夠使用的CPU資源,主要的瓶頸在於內存。可是單線程爲何可以作到這麼快的速度的呢?異步

Redis使用單線程,相比於多線程快在哪裏?

從上面官網的介紹咱們看到了,Redis的瓶頸不在線程,不在獲取CPU的資源,因此若是使用多線程就會帶來多餘的資源佔用。好比上下文切換、資源競爭、鎖的操做。函數

  • 上下文的切換
    • 上下文其實不難理解,它就是CPU寄存器和程序計數器。主要的做用就是存放沒有被分配到資源的線程,多線程操做的時候,不是每個線程都可以直接獲取到CPU資源的,咱們之因此可以看到咱們電腦上可以運行不少的程序,是應爲多線程的執行和CPU不斷對多線程的切換。可是總有線程獲取到資源,也總有線程須要等待獲取資源,這個時候,等待獲取資源的線程就須要被掛起,也就是咱們的寄存。這個時候咱們的上下文就產生了,當咱們的上下文再次被喚起,獲得資源的時候,就是咱們上下文的切換。
  • 競爭資源
    • 競爭資源相對來講比較好理解,CPU對上下文的切換其實就是一種資源分批,可是在切換以前,到底切換到哪個上下文,就是資源競爭的開始。在我redis中因爲是單線程的,因此全部的操做都不會涉及到資源的競爭。
  • 鎖的消耗
    • 對於多線程的狀況來說,不能迴避的就是鎖的問題。若是說多線程操做出現併發,有可能致使數據不一致,或者操做達不到預期的效果。這個時候咱們就須要鎖來解決這些問題。當咱們的線程不少的時候,就須要不斷的加鎖,釋放鎖,該操做就會消耗掉咱們不少的時間

I/O複用,非阻塞模型

對於I/O阻塞可能有不少人不知道,I/O操做的阻塞究竟是怎麼引發的,Redis又是怎麼解決的呢?性能

  • I/O操做的阻塞:當用戶線程發出IO請求以後,內核會去查看數據是否就緒,若是沒有就緒就會等待數據就緒,而用戶線程就會處於阻塞狀態,用戶線程交出CPU。當數據就緒以後,內核會將數據拷貝到用戶線程,並返回結果給用戶線程,用戶線程才解除block狀態。
  • Redis採用多路複用:I/O 多路複用實際上是在單個線程中經過記錄跟蹤每個sock(I/O流) 的狀態來管理多個I/O流。select, poll, epoll 都是I/O多路複用的具體的實現。epoll性能比其餘幾者要好。redis中的I/O多路複用的全部功能經過包裝常見的select、epoll、evport和kqueue這些I/O多路複用函數庫來實現的。

作一個有底線的博客主

相關文章
相關標籤/搜索