人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

Redis中Lua腳本的使用和設(shè)置超時(shí)

發(fā)布日期:2022-02-02 17:23 | 文章來(lái)源:gibhub

Redis提供了Lua腳本功能來(lái)讓用戶(hù)實(shí)現(xiàn)自己的原子命令,但也存在著風(fēng)險(xiǎn),編寫(xiě)不當(dāng)?shù)哪_本可能阻塞線(xiàn)程導(dǎo)致整個(gè)Redis服務(wù)不可用。

本文將介紹Redis中Lua腳本的基本用法,以及腳本超時(shí)導(dǎo)致的問(wèn)題和處理方式。

EVAL命令簡(jiǎn)介

eval格式

Redis 提供了命令EVAL來(lái)執(zhí)行Lua腳本,格式如下

EVAL script numkeys key [key …] arg [arg …]

其中 script 是將要執(zhí)行的腳本內(nèi)容,至于后面的腳本參數(shù)部分與本文無(wú)關(guān),在此不做贅述。

特性

由于Redis對(duì)數(shù)據(jù)集單線(xiàn)程讀寫(xiě)的特性,Lua腳本執(zhí)行時(shí)會(huì)阻塞所有對(duì)數(shù)據(jù)集的讀寫(xiě)操作,這給它帶來(lái)了下面兩個(gè)特性:

  • 原子性:可以通過(guò)Lua腳本實(shí)現(xiàn)對(duì)數(shù)據(jù)集的原子讀寫(xiě)操作,這和Redis的事務(wù)功能MULTI / EXEC類(lèi)似
  • 長(zhǎng)時(shí)間阻塞風(fēng)險(xiǎn):如果Lua腳本執(zhí)行時(shí)間過(guò)長(zhǎng),導(dǎo)致整個(gè)Redis不可用

執(zhí)行流程

eval "return 'hello world'" 0為例,腳本執(zhí)行步驟如下

定義腳本函數(shù)

執(zhí)行過(guò)的腳本可以根據(jù)hash值找到函數(shù)重新使用

Redis會(huì)根據(jù)傳入的腳本內(nèi)容生成函數(shù),函數(shù)名由 f_ + 腳本內(nèi)容的sha1摘要組成。

function f_5332031c6b470dc5a0dd9b4bf2030dea6d65de91()
	return 'hello world'
end

函數(shù)保存到 Lua_scripts字典,便于 evalsha使用

執(zhí)行腳本函數(shù)

  • 將KEYS和ARGV兩個(gè)參數(shù)數(shù)組傳入Lua執(zhí)行環(huán)境
  • 裝載超時(shí)處理鉤子
  • 執(zhí)行腳本
  • 移除超時(shí)鉤子
  • 結(jié)果保存到客戶(hù)端輸出緩沖區(qū),等待服務(wù)器將結(jié)果返回客戶(hù)端
  • Lua環(huán)境垃圾回收

關(guān)于腳本超時(shí)

介紹完EVAL命令,下面來(lái)關(guān)注Lua腳本長(zhǎng)時(shí)間阻塞的風(fēng)險(xiǎn)。

Redis的配置文件中提供了如下配置項(xiàng)來(lái)規(guī)定最大執(zhí)行時(shí)長(zhǎng)

  • Lua-time-limit 5000 Lua腳本最大執(zhí)行時(shí)間,默認(rèn)5秒

但這里有個(gè)坑,當(dāng)一個(gè)腳本達(dá)到最大執(zhí)行時(shí)長(zhǎng)的時(shí)候,Redis并不會(huì)強(qiáng)制停止腳本的運(yùn)行,僅僅在日志里打印個(gè)警告,告知有腳本超時(shí)。

Lua slow script detected: still in execution after 5000 milliseconds. You can try killing the script using the SCRIPT KILL command. Script SHA1 is: 2531e4edc1a1e2a9bac3c52e99466f9ccabf12c0

為什么不能直接停掉呢?

因?yàn)?Redis 必須保證腳本執(zhí)行的原子性,中途停止可能導(dǎo)致內(nèi)存的數(shù)據(jù)集上只修改了部分?jǐn)?shù)據(jù)。

(只讀的腳本應(yīng)該是可以自動(dòng)停的,沒(méi)自動(dòng)停的原因我猜測(cè)是:腳本超時(shí)嚴(yán)重可以肯定出現(xiàn)了編碼錯(cuò)誤,作者可能希望在測(cè)試中盡早發(fā)現(xiàn)這種問(wèn)題,而不是靠自動(dòng)停止導(dǎo)致bug被忽略?)

如果時(shí)長(zhǎng)達(dá)到 Lua-time-limit 規(guī)定的最大執(zhí)行時(shí)間,Redis只會(huì)做這幾件事情:

日志記錄有腳本運(yùn)行超時(shí)

開(kāi)始允許接受其他客戶(hù)端請(qǐng)求,但僅限于 SCRIPT KILLSHUTDOWN NOSAVE 兩個(gè)命令

其他請(qǐng)求仍返回busy錯(cuò)誤

SCRIPT KILL 命令

如果Lua只是讀取數(shù)據(jù)而沒(méi)做修改的話(huà),執(zhí)行 SCRIPT KILL 就可以直接終止腳本執(zhí)行,不用擔(dān)心數(shù)據(jù)被修改。

但是,如果腳本已經(jīng)改寫(xiě)了數(shù)據(jù)內(nèi)容,SCRIPT KILL將報(bào)出以下錯(cuò)誤,因?yàn)樗茐臄?shù)據(jù)集的內(nèi)容。

(error) UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.

SHUTDOWN NOSAVE 命令

如上所述,如果腳本已經(jīng)執(zhí)行了寫(xiě)命令,SCRIPT KILL將無(wú)法執(zhí)行。那我們就只剩以下兩種選擇了:

  • 繼續(xù)等待腳本執(zhí)行完成
  • 使用 SHUTDOWN NOSAVE 來(lái)直接停掉 Redis,并避免臟數(shù)據(jù)持久化到磁盤(pán)

最后,不知道你有沒(méi)有疑問(wèn),從開(kāi)始執(zhí)行腳本到 SHUTDOWN 之間的寫(xiě)命令會(huì)把日志寫(xiě)到AOF里嗎?Lua腳本中的命令什么時(shí)候會(huì)寫(xiě)AOF里?

講道理,既然 Redis 為了不破壞腳本的原子性而不讓SCRIPT KILL執(zhí)行,那么腳本中寫(xiě)命令的 “提交” 也應(yīng)當(dāng)是原子執(zhí)行的,而不是執(zhí)行一句就向AOF里寫(xiě)一句。

“提交”:借用數(shù)據(jù)庫(kù)中 commit 的概念,這里指寫(xiě)入AOF文件中

下面就來(lái)驗(yàn)證這個(gè)猜測(cè):

先執(zhí)行 tail -f appendonly.aof 實(shí)時(shí)查看AOF文件變化

再開(kāi)一個(gè)redis-cli 命令行執(zhí)行一個(gè)內(nèi)容如下的Lua腳本

redis.call('set','a','aaaa') --先執(zhí)行寫(xiě)命令
local count = 1 
while( 999999999 > count ) -- 阻塞幾秒
do  
   count = count+1   
end
127.0.0.1:6379> eval "redis.call('set','a','aaaa') local count = 1 while( 999999999 > count ) do  count = count+1   end" 0
(nil)
(8.65s)

現(xiàn)象是,腳本剛開(kāi)始執(zhí)行,AOF文件毫無(wú)反應(yīng),一直等到8秒后腳本完成,命令才追加寫(xiě)入到AOF中。

這就驗(yàn)證了Redis腳本里的寫(xiě)命令是等到執(zhí)行完成后再一次性寫(xiě)入AOF的。

參考

Redis設(shè)計(jì)與實(shí)現(xiàn)

到此這篇關(guān)于Redis中Lua腳本的使用和設(shè)置超時(shí) 的文章就介紹到這了,更多相關(guān)Redis Lua 超時(shí)內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

美國(guó)服務(wù)器租用

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線(xiàn)路精選!

全天候客戶(hù)服務(wù)

7x24全年不間斷在線(xiàn)

專(zhuān)屬顧問(wèn)服務(wù)

1對(duì)1客戶(hù)咨詢(xún)顧問(wèn)

在線(xiàn)
客服

在線(xiàn)客服:7*24小時(shí)在線(xiàn)

客服
熱線(xiàn)

400-630-3752
7*24小時(shí)客服服務(wù)熱線(xiàn)

關(guān)注
微信

關(guān)注官方微信
頂部