<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Redis7單線程與多線程詳解

馬哥Linux運維 ? 來源:51CTO ? 2024-01-16 17:33 ? 次閱讀

1、redis為什么選擇單線程

abf3f2d8-b44f-11ee-8b88-92fbcf53809c.jpg

1.1、redis7單線程

ac0046a0-b44f-11ee-8b88-92fbcf53809c.jpg

Redis是單線程

主要是指Redis的網絡IO和鍵值對讀寫是由一個線程來完成的

Redis在處理客戶端的請求時包括獲取 (socket 讀)、解析、執行、內容返回 (socket 寫) 等都由一個順序串行的主線程處理,這就是所謂的“單線程”。

這也是Redis對外提供鍵值存儲服務的主要流程。

但Redis的其他功能,比如持久化RDB、AOF、異步刪除、集群數據同步等等,其實是由額外的線程執行的。

Redis命令工作線程是單線程的,但是,整個Redis來說,是多線程的;

1.2、redis7單線程快

基于內存操作:redis的所有數據都存在內存中,因此所有的運算都是內存級別的,性能比較高

數據結構簡單:redis的數據結構是專門設計的,而這些簡單的數據結構的查找和操作的時間大部分復雜度都是O(1)

多路復用和非阻塞I/O:redis使用I/O多路復用功能來監聽多個socket連接客戶端,這樣就可以使用一個線程來處理多個請求,減少線程切換帶來的開銷。同時也避免了I/O阻塞操作

避免上下文切換:因為是單線程模型,因此就避免了不必要的上下文切換和多線程競爭,省去了多線程切換帶來的時間和性能上的消耗,而且單線程不會導致死鎖問題的發生

ac0b898e-b44f-11ee-8b88-92fbcf53809c.jpg

簡單來說,Redis4.0之前一直采用單線程的主要原因有以下三個:

1 使用單線程模型是 Redis 的開發和維護更簡單,因為單線程模型方便開發和調試;

2 即使使用單線程模型也并發的處理多客戶端的請求,主要使用的是IO多路復用和非阻塞IO;

3 對于Redis系統來說,主要的性能瓶頸是內存或者網絡帶寬而并非 CPU。

2、為啥加入多線程

1、單線程的問題

正常情況下使用 del 指令可以很快的刪除數據

而當被刪除的 key 是一個非常大的對象時,例如時包含了成千上萬個元素的 hash 集合時,那么 del 指令就會造成 Redis 主線程卡頓。

這就是redis3.x單線程時代最經典的故障,大key刪除的頭疼問題,

由于redis是單線程的,del bigKey .....

等待很久這個線程才會釋放,類似加了一個synchronized鎖,你可以想象高并發下,程序堵成什么樣子?

2、解決辦法

使用惰性刪除可以有效的避免redis卡頓的問題

比如當我(Redis)需要刪除一個很大的數據時,因為是單線程原子命令操作,這就會導致 Redis 服務卡頓,

于是在 Redis 4.0 中就新增了多線程的模塊,當然此版本中的多線程主要是為了解決刪除數據效率比較低的問題的。

unlink key

flushdb async

flushall async

把刪除工作交給了后臺的小弟(子線程)異步來刪除數據了。

因為Redis是單個主線程處理,redis之父antirez一直強調"Lazy Redis is better Redis".

而lazy free的本質就是把某些cost(主要時間復制度,占用主線程cpu時間片)較高刪除操作,

從redis主線程剝離讓bio子線程來處理,極大地減少主線阻塞時間。從而減少刪除導致性能和穩定性問題。

在redis4.0就引入了多個線程來實現數據的異步惰性刪除等功能

但是其處理讀寫請求的仍然只有一個線程,所以仍然算是狹義上的單線程

3、redis6/7多線程特性和IO多路復用

3.1、redis主要的性能瓶頸是內存或者網絡帶寬而非CPU

ac167402-b44f-11ee-8b88-92fbcf53809c.jpg

3.2、redis6/7真正多線程登場

在Redis6/7中,非常受關注的第一個新特性就是多線程。

這是因為,Redis一直被大家熟知的就是它的單線程架構,雖然有些命令操作可以用后臺線程或子進程執行(比如數據刪除、快照生成、AOF重寫)。

但是,從網絡IO處理到實際的讀寫命令處理,都是由單個線程完成的。

隨著網絡硬件的性能提升,Redis的性能瓶頸有時會出現在網絡IO的處理上,也就是說,單個主線程處理網絡請求的速度跟不上底層網絡硬件的速度,

為了應對這個問題:

采用多個IO線程來處理網絡請求,提高網絡請求處理的并行度,Redis6/7就是采用的這種方法。

但是,Redis的多IO線程只是用來處理網絡請求的,對于讀寫操作命令Redis仍然使用單線程來處理。

這是因為,Redis處理請求時,網絡處理經常是瓶頸,通過多個IO線程并行處理網絡操作,可以提升實例的整體處理性能。

而繼續使用單線程執行命令操作,就不用為了保證Lua腳本、事務的原子性,額外開發多線程互斥加鎖機制了(不管加鎖操作處理),這樣一來,Redis線程模型實現就簡單了

3.3、主線程和IO線程是協作完成請求處理

ac1b76d2-b44f-11ee-8b88-92fbcf53809c.jpg

3.4、Unix網絡編程中的五種IO模型

Blocking IO 阻塞IO

NoneBlocking IO 非阻塞IO

IO Multiplexing IO多路復用

signal driven IO 信號驅動IO

asynchronous IO 異步IO

IO多路復用

一個服務端進程可以同時處理多個套接字描述符

實現IO多路復用的模型有3種:select-->poll-->epoll三個階段來描述

模擬一個tcp服務器處理30個客戶socket。

假設你是一個監考老師,讓30個學生解答一道競賽考題,然后負責驗收學生答卷,你有下面幾個選擇:

第一種選擇(輪詢):按順序逐個驗收,先驗收A,然后是B,之后是C、D。。。這中間如果有一個學生卡住,全班都會被耽誤,你用循環挨個處理socket,根本不具有并發能力。

第二種選擇(來一個new一個,1對1服務):你創建30個分身線程,每個分身線程檢查一個學生的答案是否正確。這種類似于為每一個用戶創建一個進程或者線程處理連接。

第三種選擇(響應式處理,1對多服務),你站在講臺上等,誰解答完誰舉手。這時C、D舉手,表示他們解答問題完畢,你下去依次檢查C、D的答案,然后繼續回到講臺上等。

此時E、A又舉手,然后去處理E和A。。。

這種就是IO復用模型。Linux下的select、poll和epoll就是干這個的。

將用戶socket對應的文件描述符(FileDescriptor)注冊進epoll,然后epoll幫你監聽哪些socket上有消息到達,這樣就避免了大量的無用操作。

此時的socket應該采用非阻塞模式。這樣,整個過程只在調用select、poll、epoll這些調用的時候才會阻塞,

收發客戶消息是不會阻塞的,整個進程或者線程就被充分利用起來,這就是事件驅動,所謂的reactor反應模式。

在單個線程通過記錄跟蹤每一個Sockek(I/O流)的狀態來同時管理多個I/O流. 一個服務端進程可以同時處理多個套接字描述符。

目的是盡量多的提高服務器的吞吐能力。

大家都用過nginx,nginx使用epoll接收請求,ngnix會有很多鏈接進來, epoll會把他們都監視起來,然后像撥開關一樣,誰有數據就撥向誰,然后調用相應的代碼處理。

redis類似同理,這就是IO多路復用原理,有請求就響應,沒請求不打擾。

ac1f4690-b44f-11ee-8b88-92fbcf53809c.jpg

ac22c5cc-b44f-11ee-8b88-92fbcf53809c.jpg

3.5、簡單說明

redis工作線程是單線程的

但是整個redis來說,是多線程的

ac30f96c-b44f-11ee-8b88-92fbcf53809c.jpg

ac35280c-b44f-11ee-8b88-92fbcf53809c.jpg

4、redis7如何開啟多線程

ac38ea28-b44f-11ee-8b88-92fbcf53809c.jpg

1.設置io-thread-do-reads配置項為yes,表示啟動多線程。

2。設置線程個數。

關于線程數的設置,官方的建議是如果為 4 核的 CPU,建議線程數設置為 2 或 3,如果為 8 核 CPU 建議線程數設置為 6,線程數一定要小于機器核數,線程數并不是越大越好。

5、總結

Redis自身出道就是優秀,基于內存操作、數據結構簡單、多路復用和非阻塞 I/O、避免了不必要的線程上下文切換等特性,在單線程的環境下依然很快;

但對于大數據的 key 刪除還是卡頓厲害,因此在 Redis 4.0 引入了多線程unlink key/flushall async 等命令,主要用于 Redis 數據的異步刪除;

而在 Redis6/7中引入了 I/O 多線程的讀寫,這樣就可以更加高效的處理更多的任務了,Redis 只是將 I/O 讀寫變成了多線程

而命令的執行依舊是由主線程串行執行的,因此在多線程下操作 Redis 不會出現線程安全的問題。

Redis 無論是當初的單線程設計,還是如今與當初設計相背的多線程,目的只有一個:讓 Redis 變得越來越快。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 網絡
    +關注

    關注

    14

    文章

    7280

    瀏覽量

    87718
  • 多線程
    +關注

    關注

    0

    文章

    271

    瀏覽量

    19760
  • Redis
    +關注

    關注

    0

    文章

    365

    瀏覽量

    10541
  • 單線程
    +關注

    關注

    0

    文章

    16

    瀏覽量

    1747
收藏 人收藏

    評論

    相關推薦

    Java多線程的用法

    本文將介紹一下Java多線程的用法。 基礎介紹 什么是多線程 指的是在一個進程中同時運行多個線程,每個線程都可以獨立執行不同的任務或操作。 與單線程
    的頭像 發表于 09-30 17:07 ?687次閱讀

    單線程的雙任務調度

    STM32是單線程的,通信協議層和應用功能層的耦合性比較低,如果獨立運行,提高效率不少,主要實現的方法有哪些呢?
    發表于 01-10 10:15

    單線程SRAM靜態內存使用

    概述本篇只要介紹這么使用STM32CubeMx工具添加RT-Thread操作系統組件,碼代碼的IDE是keil。介紹單線程SRAM靜態內存使用。如果還不知道,這么使用STM32CubeMx工具添加
    發表于 08-24 06:57

    python多線程和多進程對比

    電視邊吃飯邊聊天。這就是我們的 多進程 才能做的事了。2. 單線程VS多線程VS多進程文字總是蒼白無力的,不如用代碼直接來測試一下。開始對比之前,首先定義四種類型的場景 - CPU計算密集型 - 磁盤
    發表于 03-15 16:42

    LabWindows_CVI多線程技術的應用研究

    分析了線程與進程的關系,研究了LabWindows/CVI多線程技術運行機制及其數據保護機制,對利用異步定時器實現的多線程軟件與傳統單線程軟件進行效能差異分析。在某武器系統測控軟件
    發表于 08-29 14:53 ?68次下載
    LabWindows_CVI<b class='flag-5'>多線程</b>技術的應用研究

    VC-MFC多線程編程詳解

    VC編程中關于 MFC多線程編程的詳解文檔
    發表于 09-01 15:01 ?0次下載

    多線程好還是單線程好?單線程多線程的區別 優缺點分析

    摘要:如今單線程多線程已經得到普遍運用,那么到底多線程好還是單線程好呢?單線程多線程的區別又
    發表于 12-08 09:33 ?8w次閱讀

    從I/O的阻塞與非阻塞、I/O處理的單線程多線程角度探討服務器模型

    這里探討的服務器模型主要指的是服務器端對I/O的處理模型。從不同維度可以有不同的分類,這里從I/O的阻塞與非阻塞、I/O處理的單線程多線程角度探討服務器模型。
    的頭像 發表于 01-08 16:13 ?6673次閱讀

    多線程服務器編程模型:如何正確使用mutex 和condition variable

    本文對多線程服務器的常用編程模型進行了一個詳細的解讀,本文中的多線程服務器是運行在 Linux 操作系統上網絡應用程序。介紹了典型的單線程服務器編程模型和典型的多線程服務器的
    的頭像 發表于 02-19 08:29 ?6967次閱讀
    <b class='flag-5'>多線程</b>服務器編程模型:如何正確使用mutex 和condition variable

    阿里云Redis多線程性能提升思路解析

    10萬級別。本文試圖通過對Redis多線程的優化,來達到增強性能的目的。背景眾所周知redis是單進程單線程模型(不完全是單進程單線程,還
    發表于 08-30 16:41 ?215次閱讀

    實現Java多線程爬蟲的兩點

    在我們調試爬蟲程序的時候,單線程爬蟲沒什么問題,但是當我們在線上環境使用單線程爬蟲程序去采集網頁時,單線程就暴露出了兩個致命的問題:
    的頭像 發表于 05-05 21:25 ?1802次閱讀
    實現Java<b class='flag-5'>多線程</b>爬蟲的兩點

    單線程也能開發異步任務?ACE JS框架到底是如何做到的

    HarmonyOS 2提供了兩種應用開發語言:Java和JS。Java線程特性能夠讓多任務并行,充分利用硬件資源開發出高性能的應用。而JS卻是一個單線程語言,無法像Java一樣創建新的Thread
    的頭像 發表于 08-13 17:16 ?1842次閱讀
    <b class='flag-5'>單線程</b>也能開發異步任務?ACE JS框架到底是如何做到的

    Redis為何選擇單線程

    Redis為何選擇單線程? 在Redisv6.0以前,Redis的核心網絡模型選擇用單線程來實現。 核心意思就是,對于一個 DB 來說,CPU 通常不會是瓶頸,因為大多數請求不會是 C
    的頭像 發表于 10-09 10:59 ?220次閱讀

    單線程是否會引起 fail-fast機制

    ConcurrentModificationException 異常,產生 fail-fast 事件。 多線程?并發修改?才會引起 fail-fast 機制保護程序?小 B 覺得這個答案沒有說全,面試官說了單線程
    的頭像 發表于 10-10 16:31 ?242次閱讀
    <b class='flag-5'>單線程</b>是否會引起 fail-fast機制

    redis多線程還能保證線程安全嗎

    單線程的,多個客戶端請求會按序執行,每個請求使用一個線程完成,這樣可以避免多線程之間的競爭條件和鎖等帶來的開銷。但是,由于Redis是存儲內存中的數據的,當多個客戶端同時對同一個數據
    的頭像 發表于 12-05 10:28 ?777次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>