前言
Redis從2.6版本開始引入對Lua腳本的支持,通過在服務器中嵌入Lua環(huán)境,Redis客戶端可以使用Lua腳本,直接在服務端原子的執(zhí)行多個Redis命令。
其中,使用EVAL命令可以直接對輸入的腳本進行求值:
1
2
|
redis>EVAL "return 'hello world'" 0 "hello world" |
使用腳本的好處如下:
1.減少網絡開銷:本來5次網絡請求的操作,可以用一個請求完成,原先5次請求的邏輯放在redis服務器上完成。使用腳本,減少了網絡往返時延。
2.原子操作:Redis會將整個腳本作為一個整體執(zhí)行,中間不會被其他命令插入。
3.復用:客戶端發(fā)送的腳本會永久存儲在Redis中,意味著其他客戶端可以復用這一腳本而不需要使用代碼完成同樣的邏輯。
Redis執(zhí)行Lua腳本
實現一個訪問頻率控制,某個ip在短時間內頻繁訪問頁面,需要記錄并檢測出來,就可以通過Lua腳本高效的實現
在redis客戶端機器上,新建一個文件ratelimiting.lua,內容如下
1
2
3
4
5
6
7
8
9
10
|
local times = redis.call( 'incr' ,KEYS[ 1 ]) if times == 1 then redis.call( 'expire' ,KEYS[ 1 ], ARGV[ 1 ]) end if times > tonumber(ARGV[ 2 ]) then return 0 end return 1 |
在redis客戶端機器上,如何測試這個腳本呢?如下:
1
|
redis-cli -- eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 |
--eval參數是告訴redis-cli讀取并運行后面的Lua腳本,ratelimiting.lua是腳本的位置,后面跟著是傳給Lua腳本的參數。其中","前的rate.limiting:127.0.0.1是要操作的鍵,可以再腳本中用KEYS[1]獲取,","后面的10和3是參數,在腳本中能夠使用ARGV[1]和ARGV[2]獲得。注:","兩邊的空格不能省略,否則會出錯
結合腳本的內容可知這行命令的作用是將訪問頻率限制為每10秒最多3次,所以在終端中不斷的運行此命令會發(fā)現當訪問頻率在10秒內小于或等于3次時返回1,否則返回0。
測試運行如下:
1
2
3
4
5
6
7
8
9
10
|
[root@rhel6 redis-learning] # redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 (integer) 1 [root@rhel6 redis-learning] # redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 (integer) 1 [root@rhel6 redis-learning] # redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 (integer) 1 [root@rhel6 redis-learning] # redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 (integer) 0 [root@rhel6 redis-learning] # redis-cli --eval ratelimiting.lua rate.limitingl:127.0.0.1 , 10 3 (integer) 0 |
補充:
現在Lua腳本用在很多游戲上,主要是Lua腳本做到可以嵌入到其他程序中運行,游戲升級的時候,可以直接升級腳本,而不用重新安裝游戲。比如游戲的很多關卡,只需要增加lua腳本,在游戲中嵌入Lua解釋器,游戲團隊線上更新Lua腳本,然后游戲自動下載最新的游戲關卡。例如之前很多的游戲《憤怒的小鳥》就是用Lua語言實現的關卡。
摘自《Redis入門指南》
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://www.cnblogs.com/yanghuahui/p/3697996.html