主頁 > 軟體設計 > Redis為什么這么快

Redis為什么這么快

2021-01-11 16:01:25 軟體設計

Redis為什么這么快

  • 前言
  • 什么是 Redis
  • Redis 的安裝
  • Redis 到底有多快
  • Redis 是單執行緒還是多執行緒
  • Redis 為什么選擇使用單執行緒來執行請求
  • 什么是 I/O 多路復用
  • Redis 中 I/O 多路復用的應用
  • Redis 為什么這么快

前言

本篇博客已被收錄GitHub:https://zhouwenxing.github.io/

在日常開發中,為了保證資料的一致性,我們一般都選擇關系型資料庫來存盤資料,如 MySQLOracle 等,因為關系型資料庫有著事務的特性,然而在并發量比較大的業務場景,關系型資料庫卻又往往會成為系統瓶頸,無法完全滿足我們的需求,所以就需要使用到快取,而非關系型資料庫,即 NoSQL 資料庫往往又會成為最佳選擇,

NoSQL 資料庫最常見的解釋是 non-relational,也有人解釋為 Not Only SQL,非關系型資料庫不保證事務,也就是不具備事務 ACID 特性,這也是非關系型資料庫和關系型資料庫最大的區別,而我們即將介紹的 Redis 就屬于 NoSQL 資料庫的一種,

什么是 Redis

Redis 全稱是:REmote DIctionary Service,即遠程字典服務,Redis 是一個開源的(遵守 BSD 協議)、支持網路、可基于記憶體亦可持久化的日志型、Key-Value 資料庫,
Redis 具有以下特性:

  • 1、支持豐富的資料型別:字串(strings),散列(hashes),串列(lists),集合(sets),有序集合(sorted sets),位圖等,
  • 2、功能豐富:提供了持久化機制,過期策略,訂閱/發布等功能,
  • 3、高性能,高可用且支持集群,
  • 4、提供了多種語言的 API

Redis 的安裝

  • 1、下載對應版本的安裝包,如:Redis 5.0.5 版本,其他版本也可以點擊這里進行下載,
  • 2、下載好之后傳到服務器指定目錄,執行命令 tar -zxvf redis-5.0.5.tar.gz 進行解壓,
  • 3、解壓成功之后,進入 Redis 主目錄,執行命令 make && make install PREFIX=/xxx/xxx/redis-5.0.5 進行安裝,如果不指定目錄,則默認是安裝在 /usr/local 目錄下,
  • 4、安裝成功之后可以看到 Redis 主目錄下多了一個 bin 目錄,bin 目錄內包含了一些可執行腳本,
  • 5、回到 Redis 主目錄下,找到 redis.conf 組態檔,將其中的配置 daemonize no 修改為 daemonize yes,表示在后臺啟動服務,
  • 6、然后就可以執行命令 /xxx/xxx/redis-5.0.5/bin/redis-server /xxx/xxx/redis-5.0.5/redis.conf 啟動 Redis 服務,

Redis 到底有多快

大家可能都知道 Redis 很快,可是 Redis 到底能有多快呢,比如 Redis 的吞吐量能達到多少?我想這就不是每一個人都能說的上來一個具體的數字了,

Redis 官方提供了一個測驗腳本,可以供我們測驗 Redis 的 吞吐量,

  • redis-benchmark -q -n 100000 可以測驗常用命令的吞吐量,
  • redis-benchmark -t set,lpush -n 100000 -q 測驗 Redis 處理 setlpush 命令的吞吐量,
  • redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')" 測驗 Redis 處理 Lua 腳本等吞吐量,

下圖就是我這邊執行第一條命令的自測結果,可以看到大部分命令的吞吐量都可以達到 4 萬以上,也就是說每秒鐘可以處理 4 萬次以上請求:
在這里插入圖片描述
但是如果你以為這就是 Redis 的真實吞吐量,那就錯了,實際上,Redis 官方的測驗結果是可以達到 10 萬的吞吐量,下圖就是官方提供的一個基準測驗結果(縱坐標就是吞吐量,橫坐標是連接數):

在這里插入圖片描述

Redis 是單執行緒還是多執行緒

這個問題比較經典,因為在很多人的認知里,Redis 就是單執行緒的,然而 Redis4.0 版本開始就有了多執行緒的概念,雖然處理命令請求的核心模塊確實是保證了單執行緒執行,然而在其他許多地方已經有了多執行緒,比如:在后臺洗掉物件,通過 Redis 模塊實作阻塞命令,生成 dump 檔案,以及 6.0 版本中網路 I/O 實作了多執行緒等,而且在未來 Redis 應該會有越來越多的模塊實作多執行緒,

所謂的單執行緒,只是說 Redis 的處理客戶端的請求(即執行命令)時,是單執行緒去執行的,并不是說整個 Redis 都是單執行緒,

Redis 為什么選擇使用單執行緒來執行請求

Redis 為什么會選擇使用單執行緒呢?這是因為 CPU 成為 Redis 瓶頸的情況并不常見,成為 Redis 瓶頸的通常是記憶體或網路帶寬,例如,在一個普通的 Linux 系統上使用 pipelining 命令,Redis 可以每秒完成 100 萬個請求,所以如果我們的應用程式主要使用 O(N)O(log(N)) 復雜度的命令,它幾乎不會使用太多的 CPU

那么既然 CPU 不會成為瓶頸,理所當然的就沒必要去使用多執行緒來執行命令,我們需要明確的一個問題就是多執行緒一定比單執行緒快嗎?答案是不一定,因為多執行緒也是有代價的,最直接的兩個代價就是執行緒的創建和銷毀執行緒(當然可以通過執行緒池來一定程度的減少頻繁的創建執行緒和銷毀執行緒)以及執行緒的背景關系切換,

在我們的日常系統中,主要可以區分為兩種:CPU 密集型 和 IO 密集型,

  • CPU 密集型:這種系統就說明 CPU 的利用率很高,那么使用多執行緒反而會增加背景關系切換而帶來額外的開銷,所以使用多執行緒效率可能會不升反降,舉個例子:假如你現在在干活,你一直不停的在做一件事,需要 1 分鐘可以做完,但是你中途總是被人打斷,需要花 1 秒鐘時間步行到旁邊去做另一件事,假如這件事也需要 1 分鐘,那么你因為反復切換做兩件事,每切換一次就要花 1 秒鐘,最后做完這 2 件事的時間肯定大于 2 分鐘(取決于中途切換的次數),但是如果中途不被打斷,你做完一件事再去做另一件事,那么你最多只需要切換 1 次,也就是 21 秒就能做完,
  • IO 密集型:IO 操作也可以分為磁盤 IO 和網路 IO 等操作,大部分 IO 操作的特點是比較耗時且 CPU 利用率不高,所以 Redis 6.0 版本網路 IO 會改進為多執行緒,至于磁盤 IO,因為 Redis 中的資料都存盤在記憶體(也可以持久化),所以并不會過多的涉及到磁盤操作,舉個例子:假如你現在給樹苗澆水,你每澆完一次水之后就需要等別人給你加水之后你才能繼續澆,那么假如這個等待程序需要 5 秒鐘,也就是說你澆完一次水就可以休息 5 秒鐘,而你切換去做另一件事來回只需要 2 秒,那么你完全可以先去做另一件事,做完之后再回來,這樣就可以充分利用你空閑的 5 秒鐘時間,從而提升了效率,

使用多執行緒還會帶來一個問題就是資料的安全性,所以多執行緒編程都會涉及到鎖競爭,由此也會帶來額外的開銷,

什么是 I/O 多路復用

I/O 指的是網路 I/O, 多路指的是多個 TCP 連接(如 Socket),復用指的是復用一個或多個執行緒,I/O 多路復用的核心原理就是不再由應用程式自己來監聽連接,而是由服務器內核替應用程式監聽,

Redis 中,其多路復用有多種實作,如:selectepollevportkqueue 等,

我們用去餐廳吃飯為的例子來解釋一下 I/O 多路復用機制(點餐人相當于客戶端,餐廳的廚房相當于服務器,廚師就是執行緒),

  • 阻塞 IO:張三去餐廳吃飯,點了一道菜,這時候他啥事也不干了,就是一直等,等到廚師炒好菜,他就把菜端走開始吃飯了,也就是在菜被炒好之前,張三被阻塞了,這就是 BIO(阻塞 IO),效率會非常低下,
  • 非阻塞 IO:張三去餐廳吃飯,點了一道菜,這時候張三他不會一直等,找了個位置坐下,刷刷抖音,打打電話,做點其他事,然后每隔一段時間就去廚房問一下自己的菜好了沒有,這種就屬于非阻塞 IO,這種方式雖然可以提高性能,但是如果有大量 IO 都來定期輪詢,也會給服務器造成非常大的負擔,
  • 事件驅動機制:張三去餐廳吃飯,點了一道菜,這時候他找了個位置坐下來等,
    • 廚房那邊菜做好了就會把菜端出來了,但是并不知道這道菜是誰的,于是就挨個詢問顧客,這就是多路復用中的 select 模型,不過 select 模型最多只能監聽 1024socketpoll 模型解決了這個限制問題),
    • 廚房做好了菜直接把菜放在視窗上,大喊一聲,某某菜做好了,是誰的快過來拿,這時候聽到通知的人就會自己去拿,這就是多路復用中的 epoll 模型,

需要注意的是在 IO 多路復用機制下,客戶端可以阻塞也可以選擇不阻塞(大部分場景下是阻塞 IO),這個要具體情況具體分析,但是在多路復用機制下,服務端就可以通過多執行緒(上面示例中可以多幾個廚師同時炒菜)來提升并發效率,

Redis 中 I/O 多路復用的應用

Redis 服務器是一個事件驅動程式,服務器需要處理兩類事件:檔案事件和時間事件,

  • 檔案事件:Redis 服務器和客戶端(或其他服務器)進行通信會產生相應的檔案事件,然后服務器通過監聽并處理這些事件來完成一系列的通信操作,
  • 時間事件:Redis 內部的一些在給定時間之內需要進行的操作,

Redis 的檔案事件處理器以單執行緒的方式運行,其內部使用了 I/O 多路復用程式來同時監聽多個套接字(Socket)連接,提升了性能的同時又保持了內部單執行緒設計的簡單性,下圖就是檔案事件處理器的示意圖:
在這里插入圖片描述
I/O 多路復用程式雖然會同時監聽多個 Socket 連接,但是其會將監聽的 Socket 都放到一個佇列里面,然后通過這個佇列有序的,同步的將每個 Socket 對應的事件傳送給檔案事件分派器,再由檔案事件分派器分派給對應的事件處理器進行處理,只有當一個 Socket 所對應的事件被處理完畢之后,I/O多路復用程式才會繼續向檔案事件分派器傳送下一個 Socket 所對應的事件,這也可以驗證上面的結論,處理客戶端的命令請求是單執行緒的方式逐個處理,但是事件處理器內并不是只有一個執行緒,

Redis 為什么這么快

Redis 為什么這么快的原因前面已經基本提到了,現在我們再進行總結一下:

  • 1、Redis 是一款純記憶體結構,避免了磁盤 I/O 等耗時操作,
  • 2、Redis 命令處理的核心模塊為單執行緒,減少了鎖競爭,以及頻繁創建執行緒和銷毀執行緒的代價,減少了執行緒背景關系切換的消耗,
  • 3、采用了 I/O 多路復用機制,大大提升了并發效率,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/247215.html

標籤:其他

上一篇:管理系統類畢設(四)---后端搭建詳細說明

下一篇:吞吐量、QPS(TPS)、并發數、RT性能指標理解

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more