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

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

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

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

1. 語法格式

語法: eval script numkeys keys args

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

? ? ? ? ?script — lua腳本

? ? ? ? ? numkeys — 指定鍵名參數集(keys)的個數

? ? ? ? ? keys — 鍵名參數集,通過全局變量KEYS數組表示,起始下標為1

? ? ? ? ? args — 鍵值參數集,通過全局變量ARGV數組表示,起始下標為1

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

例子:

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

錯誤處理:

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

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

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

2.類型轉換

當 Lua 通過 call() 或 pcall() 函數執(zhí)行 Redis 命令的時候,命令的返回值會被轉換成 Lua 數據結構;同樣地,當Lua腳本在 redis內置解釋器里運行時,Lua的返回值也會被轉換成Redis類型,然后由EVAL將值返回客戶端。lua類型與redis類型之間存在一一轉換的關系:

redis -> lua

redis類型

lua類型

描述

redis_integer

lua_number

redis整數轉為lua數字

redis_bulk

lua_string

redis bulk回復轉為lua字符串

redis_multi bulk

Lua_table

redis 多條bulk回復轉為Lua 表

redis_status

lua_table

redis狀態(tài)回復轉為lua表,表內ok域包含狀態(tài)信息

redis_error

lua_table

redis錯誤回復轉為lua表,表內的err域包含錯誤信息

redis_nil、

redis_multi nil

lua_boolean_false

redis的nil回復和nil多條回復轉為lua的布爾值false

lua -> redis

lua類型

redis類型

描述

lua_number

redis_integer

lua數字轉為redis整數

lua_string

redis_bluk

lua字符串轉為redis bulk回復

lua_table、

lua_array

redis_multi bulk

lua表(數組)轉為redis多條bulk回復

lua_table_ok

redis status

一個帶單個ok域的lua表,轉為redis

狀態(tài)回復

lua_table_err

redis_error

一個帶單個err域的lua表,轉為redis

錯誤回復

lua_boolean_false

redis nil

lua布爾值false轉為redis的nil回復

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

lua_boolean_true -> redis_integer_1,lua布爾值true轉為redis整數1

3.lua腳本

3.1 script命令

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

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

script load:將腳本裝入腳本緩存,不立即運行并返回其校驗和

script exists:根據指定腳本校驗和,檢查腳本是否存在于緩存

script kill:殺死當前正在運行的腳本(防止腳本運行緩存,占用內存)

3.2 腳本原子性

redis使用單個lua解釋器去運行所有腳本,并且保證腳本會以原子性的方式去執(zhí)行,意味著當某個腳本在運行時,不會有其它腳本或者redis命令被執(zhí)行!所以,如果當前腳本運行很慢,服務器可能會因為正忙而無法執(zhí)行命令,如:

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

①redis記錄一個腳本正在超時運行

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

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

?

3.3 腳本緩存和EVALSHA

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

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

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

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

如下圖所示:

?

3.4 全局變量保護

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

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

3.5 日志記錄

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

?? redis.LOG_DEBUG

?? redis.LOG_VERBOSE

?? redis.LOG_NOTICE

?? redis.LOG_WARNING

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

相關文章

  • Redis不同數據類型的命令語句詳解

    Redis不同數據類型的命令語句詳解

    這篇文章主要介紹了Redis不同數據類型的命令語句,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • redis哨兵模式分布式鎖實現與實踐方式(redisson)

    redis哨兵模式分布式鎖實現與實踐方式(redisson)

    這篇文章主要介紹了redis哨兵模式分布式鎖實現與實踐方式(redisson),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 利用Supervisor管理Redis進程的方法教程

    利用Supervisor管理Redis進程的方法教程

    Supervisor 是可以在類 UNIX 系統(tǒng)中進行管理和監(jiān)控各種進程的小型系統(tǒng)。它自帶了客戶端和服務端工具,下面這篇文章主要給大家介紹了關于利用Supervisor管理Redis進程的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • redis在php中常用的語法【推薦】

    redis在php中常用的語法【推薦】

    string是redis最基本的類型,而且string類型是二進制安全的。這篇文章主要介紹了redis在php中常用的語法,需要的朋友可以參考下
    2018-08-08
  • Windows系統(tǒng)安裝redis數據庫

    Windows系統(tǒng)安裝redis數據庫

    這篇文章介紹了Windows系統(tǒng)安裝redis數據庫的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • Redis如何在項目中合理使用經驗分享

    Redis如何在項目中合理使用經驗分享

    這篇文章主要給大家介紹了關于Redis如何在項目中合理使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Redis具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-04-04
  • redis做websocket分布式消息推送服務的實現

    redis做websocket分布式消息推送服務的實現

    本文介紹了使用Redis作為消息隊列實現WebSocket分布式消息推送服務的方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • 阿里云服務器安裝配置redis的方法并且加入到開機啟動(推薦)

    阿里云服務器安裝配置redis的方法并且加入到開機啟動(推薦)

    這篇文章主要介紹了阿里云服務器安裝配置redis并且加入到開機啟動,需要的朋友可以參考下
    2017-12-12
  • Redis IP地址的綁定的實現

    Redis IP地址的綁定的實現

    這篇文章主要介紹了Redis IP地址的綁定的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • 解鎖redis鎖的正確姿勢

    解鎖redis鎖的正確姿勢

    這篇文章主要為大家詳細介紹了解鎖redis鎖的正確姿勢,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03

最新評論

景谷| 淮南市| 定边县| 大田县| 遂川县| 华安县| 黔江区| 偃师市| 体育| 福海县| 天气| 青田县| 灵武市| 安平县| 漳平市| 福建省| 麟游县| 始兴县| 综艺| 邻水| 闽侯县| 尚义县| 五大连池市| 孟津县| 容城县| 大埔区| 武威市| 纳雍县| 九江市| 通辽市| 保亭| 安西县| 琼结县| 梓潼县| 平顺县| 岳池县| 若羌县| 涿鹿县| 固始县| 祁阳县| 介休市|