欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn)方法

 更新時(shí)間:2021年11月24日 11:53:43   作者:當(dāng)編程已成習(xí)慣  
redis在2.6推出了腳本功能,允許開發(fā)者使用Lua語言編寫腳本傳到redis中執(zhí)行。本文就介紹了redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn)方法,感興趣的可以了解一下

從redis 2.6.0版本開始,redis內(nèi)置了Lua解釋器,并提供了eval命令來解析Lua腳本求值。

1. 語法格式

語法: eval script numkeys keys args

參數(shù): eval — redis提供解析lua腳本的命令

? ? ? ? ?script — lua腳本

? ? ? ? ? numkeys — 指定鍵名參數(shù)集(keys)的個(gè)數(shù)

? ? ? ? ? keys — 鍵名參數(shù)集,通過全局變量KEYS數(shù)組表示,起始下標(biāo)為1

? ? ? ? ? args — 鍵值參數(shù)集,通過全局變量ARGV數(shù)組表示,起始下標(biāo)為1

描述:? EVAL命令的語義要求字面量不要直接寫在lua腳本中,推薦使用變量來定義lua腳本,并將字面量放在鍵名參數(shù)集keys和鍵值參數(shù)集args中,通過全局變量KEYS和ARGV來獲取,這樣做的好處是可緩存!在lua腳本中,可以使用兩個(gè)函數(shù)來執(zhí)行redis命令,分別是:redis.call()和redis.pcall()

例子:

## 第一個(gè)eval命令,設(shè)置一個(gè)key=name,value=sym的字符串
eval "return redis.call('set',KEYS[1],ARGA[1])" 1 name sym
## 第二個(gè)eval命令:獲取key=name的字符串的值
eval "return redis.call('get',KEYS[1])" 1 name

錯(cuò)誤處理:

上面說過,在lua腳本中可以使用call()和pcall()來執(zhí)行redis腳本,這兩個(gè)函數(shù)的效果是一模一樣的,唯一區(qū)別就是它們對(duì)于錯(cuò)誤處理的不同:

①redis.call()在執(zhí)行命令中發(fā)生錯(cuò)誤,腳本會(huì)停止執(zhí)行,返回一個(gè)腳本錯(cuò)誤,錯(cuò)誤的輸出信息會(huì)說明錯(cuò)誤造成的原因:

②redis.pcall()執(zhí)行命令出錯(cuò)時(shí)將捕獲錯(cuò)誤并返回表示錯(cuò)誤的Lua表類型

2.類型轉(zhuǎn)換

當(dāng) Lua 通過 call() 或 pcall() 函數(shù)執(zhí)行 Redis 命令的時(shí)候,命令的返回值會(huì)被轉(zhuǎn)換成 Lua 數(shù)據(jù)結(jié)構(gòu);同樣地,當(dāng)Lua腳本在 redis內(nèi)置解釋器里運(yùn)行時(shí),Lua的返回值也會(huì)被轉(zhuǎn)換成Redis類型,然后由EVAL將值返回客戶端。lua類型與redis類型之間存在一一轉(zhuǎn)換的關(guān)系:

redis -> lua

redis類型

lua類型

描述

redis_integer

lua_number

redis整數(shù)轉(zhuǎn)為lua數(shù)字

redis_bulk

lua_string

redis bulk回復(fù)轉(zhuǎn)為lua字符串

redis_multi bulk

Lua_table

redis 多條bulk回復(fù)轉(zhuǎn)為Lua 表

redis_status

lua_table

redis狀態(tài)回復(fù)轉(zhuǎn)為lua表,表內(nèi)ok域包含狀態(tài)信息

redis_error

lua_table

redis錯(cuò)誤回復(fù)轉(zhuǎn)為lua表,表內(nèi)的err域包含錯(cuò)誤信息

redis_nil、

redis_multi nil

lua_boolean_false

redis的nil回復(fù)和nil多條回復(fù)轉(zhuǎn)為lua的布爾值false

lua -> redis

lua類型

redis類型

描述

lua_number

redis_integer

lua數(shù)字轉(zhuǎn)為redis整數(shù)

lua_string

redis_bluk

lua字符串轉(zhuǎn)為redis bulk回復(fù)

lua_table、

lua_array

redis_multi bulk

lua表(數(shù)組)轉(zhuǎn)為redis多條bulk回復(fù)

lua_table_ok

redis status

一個(gè)帶單個(gè)ok域的lua表,轉(zhuǎn)為redis

狀態(tài)回復(fù)

lua_table_err

redis_error

一個(gè)帶單個(gè)err域的lua表,轉(zhuǎn)為redis

錯(cuò)誤回復(fù)

lua_boolean_false

redis nil

lua布爾值false轉(zhuǎn)為redis的nil回復(fù)

從lua轉(zhuǎn)換到redis有一條額外的規(guī)則,這條規(guī)則沒有與其相對(duì)應(yīng)的redis轉(zhuǎn)換為lua的規(guī)則:

lua_boolean_true -> redis_integer_1,lua布爾值true轉(zhuǎn)為redis整數(shù)1

3.lua腳本

3.1 script命令

redis提供了以下幾個(gè)script命令,用于對(duì)于腳本子系統(tǒng)進(jìn)行控制:

script flush:清除所有的腳本緩存

script load:將腳本裝入腳本緩存,不立即運(yùn)行并返回其校驗(yàn)和

script exists:根據(jù)指定腳本校驗(yàn)和,檢查腳本是否存在于緩存

script kill:殺死當(dāng)前正在運(yùn)行的腳本(防止腳本運(yùn)行緩存,占用內(nèi)存)

3.2 腳本原子性

redis使用單個(gè)lua解釋器去運(yùn)行所有腳本,并且保證腳本會(huì)以原子性的方式去執(zhí)行,意味著當(dāng)某個(gè)腳本在運(yùn)行時(shí),不會(huì)有其它腳本或者redis命令被執(zhí)行!所以,如果當(dāng)前腳本運(yùn)行很慢,服務(wù)器可能會(huì)因?yàn)檎Χ鵁o法執(zhí)行命令,如:

每個(gè)腳本都有一個(gè)最大執(zhí)行時(shí)間限制,默認(rèn)值是5s。最大執(zhí)行時(shí)間的長短由配置文件redis.conf的lua-time-limit選項(xiàng)來控制,或直接使用config get和config set命令來修改。當(dāng)一個(gè)腳本執(zhí)行達(dá)到最大執(zhí)行時(shí)間,redis不會(huì)主動(dòng)結(jié)束它,它會(huì)進(jìn)行下面幾個(gè)步驟:

①redis記錄一個(gè)腳本正在超時(shí)運(yùn)行

②redis開始重新接受其它客戶端請(qǐng)求,但只接受執(zhí)行script kill命令和shutdown nosave兩個(gè)命令,若客戶端執(zhí)行其它命令,redis會(huì)返回busy錯(cuò)誤。

③如果腳本只執(zhí)行過讀操作,使用script kill命令可以立即停止此腳本;如果腳本執(zhí)行過寫操作,只允許shutdown save/nosave命令,通過停止服務(wù)器來阻止當(dāng)前數(shù)據(jù)寫入磁盤。(此時(shí)服務(wù)器關(guān)閉,數(shù)據(jù)不會(huì)被保存)

?

3.3 腳本緩存和EVALSHA

redis有一個(gè)內(nèi)部的腳本緩存機(jī)制,它不會(huì)每次都重新編譯腳本,反倒是它會(huì)將所有運(yùn)行過的腳本永久保存在腳本緩存中(因?yàn)閞edis發(fā)現(xiàn)腳本體積非常小,即使量很大,甚至經(jīng)常修改,儲(chǔ)存這些腳本的內(nèi)存也是微不足道的)。清空腳本緩存只有唯一一個(gè)方式,就是執(zhí)行script flush命令。使用eval命令執(zhí)行腳本時(shí),每次都要發(fā)送腳本主體,如果腳本足夠復(fù)雜,這會(huì)付出無謂的網(wǎng)絡(luò)帶寬。redis基于對(duì)lua的緩存,它實(shí)現(xiàn)了evalsha命令。

evalsha命令和eval命令效果一樣,都是解釋lua腳本執(zhí)行,但是evalsha命令的第一個(gè)參數(shù)不是腳本主體,而是腳本的SHAI校驗(yàn)和,這個(gè)校驗(yàn)和可以通過script load命令得到。evalsha命令執(zhí)行過程分兩步:

①如果redis服務(wù)器保存了給定SHA1校驗(yàn)和所指定的腳本,就會(huì)執(zhí)行該腳本

②如果redis服務(wù)器沒保存給定SHA1校驗(yàn)和所指定的腳本,它就會(huì)返回一個(gè)特殊錯(cuò)誤,告知客戶端使用eval命令去執(zhí)行

如下圖所示:

?

3.4 全局變量保護(hù)

redis的lua腳本不允許創(chuàng)建全局變量,如果腳本需要在多次執(zhí)行之間維持某種狀態(tài),可以借助外部redis key來保存狀態(tài),每次腳本執(zhí)行前,獲取redis相對(duì)應(yīng)的key賦值給局部變量。在lua腳本中創(chuàng)建或訪問一個(gè)全局變量,都會(huì)引起腳本停止,eval命令會(huì)返回一個(gè)錯(cuò)誤:

redis的全局變量保護(hù)并不是百分百成功,有時(shí)候會(huì)在腳本中混入lua全局狀態(tài),可能會(huì)引發(fā)AOF持久化和主從復(fù)制都無法得到保證。redis建議不要在腳本中使用全局變量,可以使用local關(guān)鍵字定義腳本中的變量!

3.5 日志記錄

在redis中使用腳本不會(huì)自動(dòng)記錄日志,需要我們?cè)谀_本使用redis.log()手動(dòng)保存日志信息。腳本保存的日志,只有那些與redis實(shí)例所設(shè)置的日志等級(jí)相同或更高級(jí)才會(huì)被記錄。語法:redis.log(loglevel,message)。其中,message表示要記錄的日志信息,是一個(gè)字符串;loglevel表示redis日志等級(jí),有4個(gè)取值:

?? redis.LOG_DEBUG

?? redis.LOG_VERBOSE

?? redis.LOG_NOTICE

?? redis.LOG_WARNING

到此這篇關(guān)于redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)redis執(zhí)行l(wèi)ua內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis的五大數(shù)據(jù)類型應(yīng)用場景分析

    redis的五大數(shù)據(jù)類型應(yīng)用場景分析

    這篇文章主要介紹了redis的五大數(shù)據(jù)類型實(shí)現(xiàn)原理,本文給大家分享五大數(shù)據(jù)類型的應(yīng)用場景分析,需要的朋友可以參考下
    2021-08-08
  • Redis實(shí)現(xiàn)分布式Session管理的機(jī)制詳解

    Redis實(shí)現(xiàn)分布式Session管理的機(jī)制詳解

    這篇文章主要介紹了Redis實(shí)現(xiàn)分布式Session管理的機(jī)制詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Redis不是一直號(hào)稱單線程效率也很高嗎,為什么又采用多線程了?

    Redis不是一直號(hào)稱單線程效率也很高嗎,為什么又采用多線程了?

    這篇文章主要介紹了Redis不是一直號(hào)稱單線程效率也很高嗎,為什么又采用多線程了的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Quarkus集成redis操作Redisson實(shí)現(xiàn)數(shù)據(jù)互通

    Quarkus集成redis操作Redisson實(shí)現(xiàn)數(shù)據(jù)互通

    這篇文章主要為大家介紹了Quarkus集成redis操作Redisson實(shí)現(xiàn)數(shù)據(jù)互通的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • redis批量刪除指定前綴key四種方法(收藏)

    redis批量刪除指定前綴key四種方法(收藏)

    這篇文章主要介紹了redis批量刪除指定前綴key四種方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-03-03
  • 基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸

    基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸

    這篇文章主要為大家詳細(xì)介紹了基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Redis中過期鍵刪除的三種方法

    Redis中過期鍵刪除的三種方法

    Redis中可以設(shè)置鍵的過期時(shí)間,并且通過取出過期字典(expires dict)中鍵的過期時(shí)間和當(dāng)前時(shí)間比較來判斷是否過期,那么一個(gè)過期的鍵是怎么被刪除的呢?本文給大家總結(jié)了三種方法,選了其中兩種給大家詳細(xì)的介紹一下,需要的朋友可以參考下
    2024-05-05
  • Redis集群下過期key監(jiān)聽的實(shí)現(xiàn)代碼

    Redis集群下過期key監(jiān)聽的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Redis集群下過期key監(jiān)聽的實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 詳解Redis中數(shù)值亂碼的根本原因以及解決方式

    詳解Redis中數(shù)值亂碼的根本原因以及解決方式

    這篇文章給大家詳細(xì)分析了Redis中數(shù)值亂碼的根本原因以及解決方式,通過代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • 詳解Redis如何保證接口的冪等性

    詳解Redis如何保證接口的冪等性

    如何防止接口中同樣的數(shù)據(jù)提交,以及如何保證消息不被重復(fù)消費(fèi),這些都是shigen在學(xué)習(xí)的過程中遇到的問題,今天,趁著在學(xué)習(xí)redis的間隙,我寫了一篇文章進(jìn)行簡單的實(shí)現(xiàn),需要的朋友可以參考下
    2023-11-11

最新評(píng)論