久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

redis的高級特性有哪些

149次閱讀
沒有評論

共計 5501 個字符,預計需要花費 14 分鐘才能閱讀完成。

自動寫代碼機器人,免費開通

這篇文章主要介紹了 redis 的高級特性有哪些,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓丸趣 TV 小編帶著大家一起了解一下。

Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用 ANSI C 語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value 數據庫,并提供多種語言的 API。

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
127.0.0.1:6379  set B 100
127.0.0.1:6379  multi
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
127.0.0.1:6379  get B
 110

通過 multi 命令開啟事務。事務不能嵌套,多個 multi 命令效果一樣的
使用 multi 開啟事務之后,客戶端向服務器發送多條命令,這些命令并不會立即被執行,而是會被放到一個隊列中,當 exec 命令調用之后,隊列中的命令才會被執行。
我們可以使用 discard 來清空事務隊列。

127.0.0.1:6379  multi
127.0.0.1:6379  set k1 1
QUEUED
127.0.0.1:6379  set k2 2
QUEUED
127.0.0.1:6379  discard
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
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
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
127.0.0.1:6379  watch money
127.0.0.1:6379  multi
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
127.0.0.1:6379  set name lisi
OK

如果數據進行了修改操作,將無法使用 script kill 終止腳本,因為違反了原子性。此時只能通過 shutdown nosave 來強行終止 redis。
shutdown nosave 和 shutdown 的區別在于 shutdown nosave 不會進行持久化
操作,意味著發生在上一次快照后的數據庫修改都會丟失。

感謝你能夠認真閱讀完這篇文章,希望丸趣 TV 小編分享的“redis 的高級特性有哪些”這篇文章對大家有幫助,同時也希望大家多多支持丸趣 TV,關注丸趣 TV 行業資訊頻道,更多相關知識等著你來學習!

向 AI 問一下細節

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-12-16發表,共計5501字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 师宗县| 旌德县| 北海市| 潮州市| 长岭县| 崇左市| 喀喇沁旗| 萍乡市| 海安县| 韶山市| 神池县| 衡南县| 松桃| 东平县| 哈密市| 茌平县| 泸西县| 淄博市| 万源市| 镇赉县| 开封县| 武冈市| 湖南省| 横山县| 沁源县| 全南县| 宜良县| 安康市| 清新县| 皮山县| 仪陇县| 沙河市| 武安市| 定结县| 乐业县| 长丰县| 乌兰浩特市| 舞钢市| 寿阳县| 洪雅县| 尼勒克县|