Redis性能解析--Redis為什麼那麼快?

来源:https://www.cnblogs.com/xlecho/archive/2019/11/10/11832118.html
-Advertisement-
Play Games

echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微信號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!!! Redis的實際被應用都是因為它的性能,在眾多緩存中Redis也是一個比較快的中間件,而且它是單線程操作, ...


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


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多路復用函數庫來實現的。

做一個有底線的博客主


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 基礎概念 1.1. 什麼是事務 什麼是事務?舉個生活的例子 :你去小賣部買東西,“一手交錢,一手交貨“就是一個事務的例子,交錢和交貨必須全部成功,事務才算成功,任一個活動失敗,事務將撤銷所有已成功的活動。明白上述例子,再來看事務的定義 :事務可以看做是一次大的活動,它由不同的小活動組成,這些活動 ...
  • 本段源碼可以學習的地方: 1. 考慮到效率問題,可以通過上下文的機制,在屬性被訪問的時候臨時構建; 2. 可以重寫一些魔術方法,比如 __new__ 方法,在調用 object.__new__(cls) 前後進行屬性的一些小設置; 3. 在本庫中使用的重寫魔術方法,上下文這兩種基礎之上,我們可以想... ...
  • '''''' ''' 1 python的定義 是一門弱類型的解釋性的高級編程語言 這裡的高級是相對低級(例如:彙編語言等) 高級編程語言和低級編程語言的區別 1、前者更接近於人的理解--字母組成的語法 2、後者更接近於計算器的理解--位元組碼、二進位 2 python的特點 人生苦短,我用python... ...
  • (手機橫屏看源碼更方便) 簡介 線程系列我們基本就學完了,這一個系列我們基本都是圍繞著線程池在講,其實關於線程還有很多東西可以講,後面有機會我們再補充進來。當然,如果你有什麼好的想法,也可以公從號右下角聯繫我。 重要知識點 直接上圖,看著這張圖我相信你能夠回憶起很多東西,也可以看著這張圖來自己提問自 ...
  • 一、常量 1.常量的定義:final修飾的實例變數是不可變的,這種變數一般和static聯合使用,被稱為“常量” 2.常量的語法格式: public static final 類型 常量名 = 值; java規範中要求所有常量的名字全部大寫,每個單詞之間使用下劃線連接 package com.bjp ...
  • 新聞 "邀請博客主們:2019年的F Advent日曆" "宣告ML.NET 1.4" ".NET Core與Jupyter筆記本" "在Jupyter筆記本中使用ML.NET" "用於Windows桌面的.NET Core 3" "宣告.NET Core 3.1預覽版2" "在.NET Core ...
  • PSR是PHP Standards Recommendation的簡稱,意為PHP推薦標準。要想瞭解PSR,首先得知道制定這一標準的人/組織是誰————PHP-FIG。 PHP-FIG PHP-FIG全稱為PHP Framework Interop Group,是一個組織,這個組織的成員由一些PHP ...
  • echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微信號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這才是真正的堪稱強大!!! Redis在我們平時的開發或者練習的時候,往往很容易忽略一個問題,那就是我們的Redis記憶體占滿的問題。但 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...