搜尋
首頁資料庫Redisredis的高階特性介紹

redis的高階特性介紹

Jan 13, 2021 am 10:11 AM
redis高階特性

redis的高階特性介紹

Redis(Remote Dictionary Server ),即遠端字典服務,是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key- Value資料庫,並提供多種語言的API。

(學習影片分享:redis影片教學

1.redis發布訂閱模式

Redis除了提供像list的這種的訊息佇列模式,還提供了一組命令實現發布/訂閱模式。例如微博,公眾號等都是可以由此實現。

redis的高階特性介紹

1.2 訂閱頻道

發布者需要將訊息傳送到一個地方,讓訂閱者可以訂閱訊息,而這個地方就是頻道(channel)。訂閱者可以訂閱一個或多個頻道,所有訂閱了這個頻道的訂閱者都會受到這則訊息。

開啟兩個客戶端進行測試

客户端1 订阅channel1
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1

客户端2 发布一则消息
127.0.0.1:6379> publish channel1 test
(integer) 1

客户端1 订阅消息
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "test"

1.2 依規則訂閱

#支援?和*佔位符。 ?代表一個字符,*代表 0 個或多個字符。

啟動四個redis-cli,一個作為訊息的發布者,另外三個作為訂閱者。
訂閱者1:訂閱體育相關

psubscribe *sport

訂閱者2:訂閱新聞相關

psubscribe news*

訂閱者3:訂閱天氣相關

psubscribe new weather*

發布者:

publish news-sport Kobe
publish news-music jaychou
publish news-weather rain

此時訂閱者1將會收到Kobe,訂閱者2將會收到全部訊息,訂閱者3將會收到rain。

redis的高階特性介紹

2.redis事務

2.1 為什麼要用交易

我們都是知道redis的單一指令是原子性的,但是如果需要用多個指令作為一個不可分割的操作序列,就需要用到交易。
例如使用setnx實現分散式鎖,我們一般先set,然後對key設定expire,防止del發生異常時候鎖不會釋放,業務處理完之後在del,這三個操作我們就希望作為一組命令執行。
redis交易有兩個特點:

  • 依照進入佇列的順序執行

  • 不會受到其他客戶端請求影響

redis的交易設計四個指令:multi(開啟交易),exec(執行交易),dicard(取消交易),watch(監視)

2.2 交易的用法

轉帳場景A和B各有100元,A向B轉帳10元,A減10元,B加10元

127.0.0.1:6379> set A 100
OK
127.0.0.1:6379> set B 100
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby A 10
QUEUED
127.0.0.1:6379> incrby B 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 90
2) (integer) 110
127.0.0.1:6379> get A
"90"
127.0.0.1:6379> get B
"110"

透過multi指令開啟交易。事務不能嵌套,多個multi指令效果一樣的
使用multi開啟事務之後,客戶端向伺服器發送多條指令,這些指令並不會立即被執行,而是會被放到一個佇列中,當exec指令呼叫之後,佇列中的命令才會被執行。
我們可以使用discard來清空事務佇列。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> set k2 2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> get k2
(nil)

當我們執行事務的時候出現了問題會回滾嗎?

exec之前發生錯誤(如指令語法錯誤)

127.0.0.1:6379> clear
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name test
QUEUED
127.0.0.1:6379> hset user lisi
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name
(nil)

exec之後發生錯誤(對同一個key使用不同資料類型的命令)

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> hset k1 a b
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get k1
"1"

透過上面操作,我們可以知道當交易在exec前發生錯誤,將會回滾所有操作;如果在exec後發生錯誤,只有錯誤的指令不會被執行。
為什麼redis在一個交易中存在錯誤不進行回滾呢?
我們從上面操作可以看出,redis只有在指令語法錯誤的時候進行回滾,而指令操作錯誤是有開發人員導致的bug,例如:你對一個int型別進行1,然後不小心2,或對一個string類型進行1,回滾是不適用的

2.3 watch指令

它可以為Redis事務提供CAS樂觀鎖定操作,也就是多個執行緒更新某個變數的時候,會讓舊值跟記憶體位址比較,如果相等,則更新為新值。
我們可以用watch監視一個或多個key,如果開啟事務之後,至少有一個被監視的key在exec執行之前被修改,則會取消整個事務。

首先client 1執行watch監視money這個key,並開啟事務對money進行增加100

127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 100
QUEUED

在事務結束之前,在client 2對money進行減少100

127.0.0.1:6379> decrby money 100
(integer) 900

此時client 1結束事務,money的值並沒有被增加,反而減少,說明事務的修改失效

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"900"

3. Lua腳本

Lua腳本是一種輕量級腳本語言,C語言寫的,跟預存過程有點類似。為啥要用lua腳本呢?

一次發送多個命令,減少網路開銷Redis會將腳本作為一個整體執行,確保原子性(可用此方式替換事務)腳本復用,以便於多個客戶端完成相同的邏輯。

3.1 使用

我們可以使用以下指令進行呼叫lua腳本

eval script numkeys [key1 key2 key3 ....] [arg1 arg2 arg3 ....]

eval 執行lua腳本

script 代表lua腳本的內容

numkeys key的數量

[key1 key2 key3 ....] 键名参数,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

[arg1 arg2 arg3 ....] 全局变量,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)

来个简单的例子

127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],KEYS[2],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "val1"
3) "key2"
4) "val1"
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "key2"
3) "val1"
4) "val1"

在lua脚本如何调用redis命令呢?
我们可以使用 redis.call(command, key [param1, param2…])进行操作

commond redis的命令,如set,get等key 被操作的键[param1, param2…]表示给key的参数

127.0.0.1:6379> eval "redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2])" 2 name age lisi 18
(nil)
127.0.0.1:6379> mget name age
1) "lisi"
2) "18

以上命令等价于 mset name lisi age 18, key的数量为2,2 后面两个值为key,在之后就是args

直接在redis-cli中写lua脚本不够方便,通常我们会把脚本放在文件中,然后执行这个文件
我们在一个目录下新建一个test.lua的脚本,填写以下内容后执行。

root@VM-0-5-centos src]# mkdir testlua
[root@VM-0-5-centos src]# cd testlua/
[root@VM-0-5-centos testlua]# ll
total 0
[root@VM-0-5-centos testlua]# touch test.lua
[root@VM-0-5-centos testlua]# vim test.lua
redis.call('set',KEYS[1],ARGV[1])
return redis.call('get',KEYS[1])
[root@VM-0-5-centos testlua]# redis-cli --eval test.lua 1 myname , Armin
"Armin"

值得注意的是key和arg之间需要加上空格逗号空格(myname , Armin)

3.2 缓存lua脚本

之所以需要缓存lua脚本,这是因为每次调用的时候都将整个脚本传给redis服务端,会产生较大的网络开销。为了解决这个问题,Redis提供了evalsha命令,让开发人员通过脚本内容的SHA1摘要执行脚本。

那么怎么将生成这个SHA1并将脚本内容加载到缓存呢,这就用到script load命令去计算脚本的SHA1摘要并记录脚本到缓存中,执行evalsha时,redis会根据提供的摘要去脚本缓存找到对应脚本内容,如果找到则执行,否则返回错误提示: “NOSCRIPT No matching script. Please use EVAL”

127.0.0.1:6379> script load "return 'Hey boy'"
"3760855b303510c83f0be2e8acfb0be64113ae6e"
127.0.0.1:6379> evalsha 3760855b303510c83f0be2e8acfb0be64113ae6e 0
"Hey boy"
127.0.0.1:6379> script exists 3760855b303510c83f0be2e8acfb0be64113ae6e //判断是否存在
1) (integer)

Redis还给lua脚本的执行提供了超时时间,默认的超时时间为5s,超过5s之后redis会接受其他命令但是会返回一个"BUSY"的错误
可在redis.conf中修改指定参数

lua-time-limit 5000

Redis提供了个script kill的命令来终止正在运行的脚本

127.0.0.1:6379> set name lisi
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
127.0.0.1:6379> script kill
OK
127.0.0.1:6379> set name lisi
OK

如果数据进行了修改操作,将无法使用script kill终止脚本,因为违反了原子性。此时只能通过shutdown nosave来强行终止redis。
shutdown nosave 和 shutdown 的区别在于 shutdown nosave 不会进行持久化 操作,意味着发生在上一次快照后的数据库修改都会丢失。

相关推荐:redis数据库教程

以上是redis的高階特性介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金。如有侵權,請聯絡admin@php.cn刪除
了解NOSQL:Redis的關鍵特徵了解NOSQL:Redis的關鍵特徵Apr 13, 2025 am 12:17 AM

Redis的關鍵特性包括速度、靈活性和豐富的數據結構支持。 1)速度:Redis作為內存數據庫,讀寫操作幾乎瞬時,適用於緩存和會話管理。 2)靈活性:支持多種數據結構,如字符串、列表、集合等,適用於復雜數據處理。 3)數據結構支持:提供字符串、列表、集合、哈希表等,適合不同業務需求。

REDIS:確定其主要功能REDIS:確定其主要功能Apr 12, 2025 am 12:01 AM

Redis的核心功能是高性能的內存數據存儲和處理系統。 1)高速數據訪問:Redis將數據存儲在內存中,提供微秒級別的讀寫速度。 2)豐富的數據結構:支持字符串、列表、集合等,適應多種應用場景。 3)持久化:通過RDB和AOF方式將數據持久化到磁盤。 4)發布訂閱:可用於消息隊列或實時通信系統。

REDIS:流行數據結構指南REDIS:流行數據結構指南Apr 11, 2025 am 12:04 AM

Redis支持多種數據結構,具體包括:1.字符串(String),適合存儲單一值數據;2.列表(List),適用於隊列和棧;3.集合(Set),用於存儲不重複數據;4.有序集合(SortedSet),適用於排行榜和優先級隊列;5.哈希表(Hash),適合存儲對像或結構化數據。

redis計數器怎麼實現redis計數器怎麼實現Apr 10, 2025 pm 10:21 PM

Redis計數器是一種使用Redis鍵值對存儲來實現計數操作的機制,包含以下步驟:創建計數器鍵、增加計數、減少計數、重置計數和獲取計數。 Redis計數器的優勢包括速度快、高並發、持久性和簡單易用。它可用於用戶訪問計數、實時指標跟踪、遊戲分數和排名以及訂單處理計數等場景。

redis命令行怎麼用redis命令行怎麼用Apr 10, 2025 pm 10:18 PM

使用 Redis 命令行工具 (redis-cli) 可通過以下步驟管理和操作 Redis:連接到服務器,指定地址和端口。使用命令名稱和參數向服務器發送命令。使用 HELP 命令查看特定命令的幫助信息。使用 QUIT 命令退出命令行工具。

redis集群模式怎麼搭建redis集群模式怎麼搭建Apr 10, 2025 pm 10:15 PM

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

redis怎麼讀取隊列redis怎麼讀取隊列Apr 10, 2025 pm 10:12 PM

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。

redis集群zset怎麼使用redis集群zset怎麼使用Apr 10, 2025 pm 10:09 PM

Redis 集群中使用 zset:zset 是一種有序集合,將元素與評分關聯。分片策略: a. 哈希分片:根據 zset 鍵的哈希值分佈。 b. 範圍分片:根據元素評分劃分為範圍,並將每個範圍分配給不同的節點。讀寫操作: a. 讀操作:如果 zset 鍵屬於當前節點的分片,則在本地處理;否則,路由到相應的分片。 b. 寫入操作:始終路由到持有 zset 鍵的分片。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用