最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解Redis線程模型的原理及使用

 更新時(shí)間:2025年11月16日 09:31:10   作者:Tacy0213  
Redis的線程模型整體還是多線程的,只是后臺(tái)執(zhí)行指令的核心線程是單線程的,整個(gè)線程模型可以理解為還是以單線程為主,基于這種單線程為主的線程模型,不同客戶端的各種指令都需要依次排隊(duì)執(zhí)行,下面就來詳細(xì)的了解一下

1 redis是單線程還是多線程

總的來說:redis是客戶端多線程,服務(wù)端要分版本,redis4.X以前:單線程,之后的版本核心線程是單線程,其他也使用的多線程。

客戶端
Redis為了實(shí)現(xiàn)服務(wù)端與更多的客戶端進(jìn)行連接,使用多線程來維護(hù)與客戶端的socket連接。在redis.conf中的參數(shù)“maxclients” 就是設(shè)置最大連接客戶端連接數(shù)的

服務(wù)端
在服務(wù)端,redis響應(yīng)網(wǎng)絡(luò)I/O和鍵值對讀寫的請求,是由一個(gè)單獨(dú)的主線程來完成,Redis基于epoll實(shí)現(xiàn)了IO多路復(fù)用,用來滿足一個(gè)主線程可以同時(shí)響應(yīng)多個(gè)客戶端的socket連接的請求。

Redis將客戶端多個(gè)并發(fā)的請求轉(zhuǎn)成了串行的執(zhí)行方式,這種串行化的線程模型,不僅規(guī)避了MySQL的臟讀、幻讀、不可重復(fù)讀之類的并發(fā)問題, 而且加上Redis基于內(nèi)存工作的極高性能,也讓Redis成為很多并發(fā)問題的解決工具。

Redis4.X以前的版本,都是采用的純單線程。之后的版本,加入了多線程,做了優(yōu)化,核心的任務(wù)還是單線程執(zhí)行,對于一些費(fèi)時(shí)的,比如持久化RDB,AOF文件、unlink異步刪除、集群數(shù)據(jù)同步等,都是由額外的線程執(zhí)行的。對于 FLUSHALL操作,也提供了異步的方式。

問:為什么CPU早就多核了,Redis的核心線程模型卻用單線呢?
答:Redis一直保持核心線程的單線程模型,其實(shí)是因?yàn)閷τ诂F(xiàn)代的Redis來說,CPU通常不會(huì)成為Redis的性能瓶頸。影響Redis的性能瓶頸大部分是內(nèi)存和網(wǎng)絡(luò)。因此,核心線程改為多線程的要求并不急切。另外,Redis的這種單線程為主的工作機(jī)制還可以減少線程上下文切換的性能消耗。而且,如果Redis將核心線程改為多線程并發(fā)執(zhí)行,那么就必然帶來資源競爭,反而會(huì)極大增加Redis的業(yè)務(wù)復(fù)雜性,影響Redis的業(yè)務(wù)執(zhí)行效率。

2 Redis如何保證指令原子性

問題:
Redis是支持同時(shí)連接多個(gè)客戶端,如果多個(gè)客戶端同時(shí)進(jìn)行讀寫請求,由于核心的讀寫鍵值的操作,Redis是單線程處理的,那多個(gè)請求同時(shí)過來就會(huì)排隊(duì),排隊(duì)的順序就可能會(huì)亂,針對單個(gè)客戶端,Redis并沒有類似MySQL的事務(wù)那樣保證同一個(gè)客戶端的操作原子性。那redis是如何保證指令原子性的呢?

2.1 Redis指令原子性的實(shí)現(xiàn)機(jī)制

2.1.1 復(fù)合指令

Redis內(nèi)部提供了很多復(fù)合指令,一個(gè)指令可以執(zhí)行多個(gè)操作, 比如 MSET(HMSET)、GETSET、SETNX、SETEX。這些復(fù)合指令都能很好的保持原子性。

2.1.2 Redis事務(wù)

Redis事務(wù)通過MULTI、EXEC、DISCARDWATCH命令實(shí)現(xiàn),允許將多個(gè)操作打包為一個(gè)原子單元執(zhí)行。事務(wù)中的所有命令會(huì)按順序執(zhí)行,且不會(huì)被其他客戶端命令打斷。

  # 丟棄事務(wù)
  DISCARD (null)
  # 執(zhí)行事務(wù)中的所有命令。
  EXEC (null)
  # 開啟事務(wù)
  MULTI (null)
  # 去掉監(jiān)聽
  UNWATCH (null)
  # 監(jiān)聽某一個(gè)key的變化。key有變化后,就執(zhí)行當(dāng)前事務(wù)
  WATCH key [key ...]

事務(wù)的執(zhí)行流程

  1. 開啟事務(wù):使用MULTI命令標(biāo)記事務(wù)開始,后續(xù)命令會(huì)進(jìn)入隊(duì)列而非立即執(zhí)行。
  2. 命令入隊(duì):輸入操作命令(如SET、GET、INCR等),這些命令會(huì)按順序存入隊(duì)列。
  3. 執(zhí)行或放棄
    • EXEC:執(zhí)行隊(duì)列中的所有命令,返回各命令的結(jié)果。
    • DISCARD:取消事務(wù),清空命令隊(duì)列。

事務(wù)的原子性特點(diǎn)

  • 非嚴(yán)格原子性:Redis事務(wù)僅保證命令順序執(zhí)行,但單條命令失敗不會(huì)回滾(與關(guān)系型數(shù)據(jù)庫不同)。例如語法錯(cuò)誤會(huì)導(dǎo)致整個(gè)事務(wù)失敗,而運(yùn)行時(shí)錯(cuò)誤(如對字符串執(zhí)行INCR)僅影響當(dāng)前命令。
  • 無隔離級別:事務(wù)執(zhí)行期間,其他客戶端命令不會(huì)插入,但事務(wù)內(nèi)操作的結(jié)果在EXEC前不可見。

WATCH命令與樂觀鎖
WATCH用于監(jiān)控一個(gè)或多個(gè)鍵,若這些鍵在EXEC前被其他客戶端修改,則事務(wù)會(huì)失?。ǚ祷?code>nil)。適用于需要檢測數(shù)據(jù)變化的場景。

示例代碼

WATCH balance
MULTI
DECRBY balance 50
EXEC  # 若balance被其他客戶端修改,此處返回nil

2.1.3 Pipeline

Redis Pipeline 是一種客戶端技術(shù),用于將多個(gè)命令一次性發(fā)送到服務(wù)器并批量接收響應(yīng),減少網(wǎng)絡(luò)往返時(shí)間(RTT),顯著提升批量操作的性能。適用于需要執(zhí)行大量命令的場景(如批量寫入、讀?。?。

RTT: 當(dāng)客戶端執(zhí)行一個(gè)指令,數(shù)據(jù)包需要通過網(wǎng)絡(luò)從Client傳到Server,然后再從Server返回到Client。這個(gè)中間的時(shí)間消耗,就稱為RTT(Round Trip Time)。

Pipeline 的核心原理

  • 傳統(tǒng)模式:客戶端發(fā)送一個(gè)命令后需等待服務(wù)器響應(yīng),再發(fā)送下一個(gè)命令,每次命令消耗一個(gè) RTT。
  • Pipeline 模式:客戶端將多個(gè)命令打包一次性發(fā)送,服務(wù)器按順序執(zhí)行后批量返回結(jié)果,僅消耗一次 RTT。

非原子性:Pipeline 中的命令會(huì)被分批發(fā)送到服務(wù)器,但服務(wù)器可能在其他客戶端命令間插入執(zhí)行(需用 MULTI/EXEC 實(shí)現(xiàn)原子性)。
錯(cuò)誤處理:某條命令失敗不會(huì)影響后續(xù)命令執(zhí)行,需檢查返回結(jié)果中的錯(cuò)誤信息。
合理批量大小:避免單次 Pipeline 數(shù)據(jù)量過大導(dǎo)致網(wǎng)絡(luò)阻塞或超時(shí)(建議分批發(fā)送)。

與事務(wù)(Transaction)的區(qū)別

  • Pipeline:批量發(fā)送命令,無原子性保證。
  • 事務(wù)(MULTI/EXEC):命令按順序原子性執(zhí)行,但會(huì)消耗更多 RTT(需配合 Pipeline 優(yōu)化)。

適用場景

  • 批量寫入數(shù)據(jù)(如日志入庫)。
  • 批量讀取多個(gè)鍵值(減少網(wǎng)絡(luò)延遲)。
  • 高頻命令需低延遲(如計(jì)數(shù)器遞增)。

2.1.4 lua腳本

Lua是一種輕量級、高效的腳本語言,比如參數(shù)類型、作用域、函數(shù)等,設(shè)計(jì)初衷為嵌入其他應(yīng)用程序中擴(kuò)展功能。

Redis中Lua腳本的作用
Redis從2.6版本開始支持Lua腳本,主要解決以下問題:

  • 原子性操作:腳本內(nèi)的多條Redis命令作為一個(gè)整體執(zhí)行,避免競態(tài)條件。
  • 減少網(wǎng)絡(luò)開銷:合并多個(gè)操作為單個(gè)腳本,降低客戶端與Redis的通信次數(shù)。
  • 復(fù)雜邏輯封裝:實(shí)現(xiàn)如分布式鎖、限流等需多命令組合的功能。

Lua腳本在Redis中的基本用法

  • 腳本執(zhí)行命令
    通過EVAL直接執(zhí)行腳本,或使用SCRIPT LOAD預(yù)加載后以EVALSHA調(diào)用:
-- 直接執(zhí)行示例
EVAL "return redis.call('GET', KEYS[1])" 1 mykey

-- 預(yù)加載腳本
SCRIPT LOAD "return redis.call('SET', KEYS[1], ARGV[1])"
EVALSHA "sha1哈希值" 1 key value
  • 參數(shù)傳遞規(guī)則

    • KEYS:鍵名列表,用于標(biāo)識(shí)Redis中操作的數(shù)據(jù)。
    • ARGV:額外參數(shù)列表,傳遞非鍵名數(shù)據(jù)。
    • 必須明確指定KEYS的數(shù)量(如EVAL script 2 key1 key2 arg1)。
  • 腳本特性

    • 原子性:腳本執(zhí)行期間其他命令會(huì)被阻塞。
    • 緩存機(jī)制:Redis緩存腳本的SHA1哈希,避免重復(fù)傳輸。
    • 調(diào)試支持:通過redis-cli --ldb可進(jìn)行腳本調(diào)試。
  • 應(yīng)用場景
    分布式鎖 ,以下腳本實(shí)現(xiàn)鎖的獲取與釋放:

-- 獲取鎖(SET if Not eXists)
local ok = redis.call('SETNX', KEYS[1], ARGV[1])
if ok == 1 then
    redis.call('EXPIRE', KEYS[1], ARGV[2])
end
return ok

-- 釋放鎖(驗(yàn)證值匹配)
if redis.call('GET', KEYS[1]) == ARGV[1] then
    return redis.call('DEL', KEYS[1])
else
    return 0
end

到此這篇關(guān)于深入理解Redis線程模型的原理及使用的文章就介紹到這了,更多相關(guān)Redis線程模型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Grafana監(jiān)控Redis的操作方法

    使用Grafana監(jiān)控Redis的操作方法

    這篇文章主要介紹了使用Grafana監(jiān)控Redis,號(hào)稱下一代可視化監(jiān)控系統(tǒng),結(jié)合SpringBoot使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • 阿里云官方Redis開發(fā)規(guī)范總結(jié)

    阿里云官方Redis開發(fā)規(guī)范總結(jié)

    本文主要介紹了阿里云官方Redis開發(fā)規(guī)范總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Redis不使用 keys 命令獲取鍵值信息的方法

    Redis不使用 keys 命令獲取鍵值信息的方法

    這篇文章主要介紹了Redis 不使用 keys 命令獲取鍵值信息的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-08-08
  • Redis鎖完美解決高并發(fā)秒殺問題

    Redis鎖完美解決高并發(fā)秒殺問題

    本文主要介紹了Redis鎖完美解決高并發(fā)秒殺問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí)

    Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí)

    這篇文章主要為大家介紹了Redis數(shù)據(jù)類型之散列類型hash命令學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Redis實(shí)現(xiàn)分布式鎖詳解

    Redis實(shí)現(xiàn)分布式鎖詳解

    這篇文章主要介紹了redis如何實(shí)現(xiàn)分布式鎖,文章中有詳細(xì)的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-04-04
  • Redis的共享session應(yīng)用實(shí)現(xiàn)短信登錄

    Redis的共享session應(yīng)用實(shí)現(xiàn)短信登錄

    本文主要介紹了Redis的共享session應(yīng)用實(shí)現(xiàn)短信登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Redis MCP 安裝與配置指南

    Redis MCP 安裝與配置指南

    本文將詳細(xì)介紹如何安裝和配置 Redis MCP,包括快速啟動(dòng)、源碼安裝、Docker 安裝、以及相關(guān)的配置參數(shù)和環(huán)境變量設(shè)置,感興趣的朋友一起看看吧
    2025-07-07
  • Redis列表類型的常用命令小結(jié)

    Redis列表類型的常用命令小結(jié)

    這篇文章給大家整理了在操作Redis列表類型中的常用命令,文章總結(jié)的很全面,對大家學(xué)習(xí)Redis具有一定的參考借鑒價(jià)值,下面來一起看看吧。
    2016-09-09
  • Redis內(nèi)存碎片原理深入分析

    Redis內(nèi)存碎片原理深入分析

    這篇文章主要為大家介紹了Redis內(nèi)存碎片原理深入分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評論

高雄市| 汶川县| 通河县| 临沂市| 马尔康县| 阿拉善左旗| 漾濞| 清远市| 江门市| 黄龙县| 抚宁县| 错那县| 巴青县| 嘉义县| 三都| 蒙自县| 丹棱县| 德庆县| 新建县| 门源| 河北区| 通渭县| 曲靖市| 定西市| 黎平县| 梧州市| 鄂托克前旗| 成安县| 兴业县| 四平市| 锦屏县| 定陶县| 介休市| 大悟县| 琼中| 上栗县| 玉树县| 常德市| 安多县| 五台县| 安阳县|