Docker環(huán)境下Redis Lua腳本部署與執(zhí)行方式
先提前說個核心結(jié)論:Redis的Lua腳本不需要編譯、不需要安裝,核心就是“讓Redis能找到腳本文件”,再用簡單的命令執(zhí)行就行。
Docker部署Redis Lua,優(yōu)先用「目錄掛載」,測試用「直接復(fù)制文件」
一、Redis Lua腳本執(zhí)行的本質(zhì)
很多人會誤以為Lua腳本需要像部署應(yīng)用一樣,安裝依賴、啟動服務(wù)——其實完全不用!
Redis本身就內(nèi)置了Lua解釋器,只要Redis能讀取到Lua腳本文件,或者你直接把腳本內(nèi)容傳給Redis,它就能直接執(zhí)行。咱們在Docker里要做的,本質(zhì)就是「讓Redis容器能訪問到Lua腳本」,剩下的就是Redis的原生命令操作。
另外補(bǔ)充兩個關(guān)鍵知識點:
- Redis執(zhí)行Lua腳本有兩種方式:直接傳腳本內(nèi)容(EVAL命令)、緩存腳本后用SHA值調(diào)用(SCRIPT LOAD + EVALSHA,性能更高,生產(chǎn)推薦);
- Docker里的Redis容器,默認(rèn)沒有宿主機(jī)的文件權(quán)限,所以不能直接讀取宿主機(jī)的腳本,要么掛載目錄,要么把腳本復(fù)制進(jìn)容器。
二、生產(chǎn)環(huán)境首選:目錄掛載(最規(guī)范,方便維護(hù))
這種方式是生產(chǎn)環(huán)境最推薦的,核心邏輯是「把宿主機(jī)的一個文件夾,掛載到Redis容器里」,這樣我們在宿主機(jī)修改、新增Lua腳本,容器里就能實時同步,不用每次都復(fù)制文件,后期維護(hù)特別方便。
步驟1:啟動Redis容器,掛載目錄
先停止并刪除舊的Redis容器(如果有的話),然后執(zhí)行以下命令,啟動一個新的Redis容器,并掛載宿主機(jī)目錄:
# 先創(chuàng)建宿主機(jī)存放Lua腳本的目錄(自定義路徑,我這里用/home/redis/lua) mkdir -p /home/redis/lua chmod 777 /home/redis/lua # 給權(quán)限,避免容器訪問不到 # 啟動Redis容器,掛載目錄 docker run -d \ --name wzxgRedis # 容器名字,自定義 -p 6379:6379 # 端口映射,宿主機(jī)6379對應(yīng)容器6379 -v /home/redis/lua:/lua # 掛載:宿主機(jī)路徑:/容器內(nèi)路徑 redis:latest redis-server # 啟動Redis服務(wù)
注:
-v /home/redis/lua:/lua 這一句,就是把宿主機(jī)的/home/redis/lua文件夾,和容器里的/lua文件夾關(guān)聯(lián)起來,相當(dāng)于“共享文件夾”,宿主機(jī)放腳本,容器里就能直接看到。
步驟2:在宿主機(jī)編寫Lua腳本
在宿主機(jī)的掛載目錄里寫腳本,容器里會自動同步,不用再手動復(fù)制。比如寫一個簡單的“自增計數(shù)”腳本。
# 進(jìn)入宿主機(jī)的Lua腳本目錄 cd /home/redis/lua # 創(chuàng)建并編輯腳本(也可以用記事本編輯后上傳) vim wzxg.lua
腳本內(nèi)容
-- KEYS[1]:傳入的第一個key(后續(xù)執(zhí)行時指定)
-- redis.call():調(diào)用Redis原生命令
local key = KEYS[1]
-- 對key進(jìn)行自增,返回自增后的值
local count = redis.call("INCR", key)
return count
保存退出vim(按ESC,輸入:wq,回車即可)。這時候,容器里的/lua目錄下,wzxg.lua腳本,因為我們掛載了目錄。
步驟3:進(jìn)入容器,執(zhí)行Lua腳本
腳本準(zhǔn)備好了,接下來進(jìn)入Redis容器,用Redis命令執(zhí)行腳本,兩種方式任選,優(yōu)先推薦方式2(性能更高)。
# 進(jìn)入Redis容器的redis-cli客戶端 docker exec -it wzxgRedis redis-cli
方式1:直接加載文件執(zhí)行(測試用,簡單)
直接讀取容器內(nèi)的腳本文件,一次性執(zhí)行,適合測試腳本是否能正常運(yùn)行:
EVAL "$(cat /lua/wzxg.lua)" 1 mycounter
拆解一下這個命令:
- EVAL:Redis執(zhí)行Lua腳本的核心命令;
- “$(cat /lua/test.lua)”:讀取容器內(nèi)/lua目錄下的test.lua腳本內(nèi)容;
- 1:表示后續(xù)傳入的KEYS數(shù)量(這里我們只傳一個key,就是mycounter);
- mycounter:傳入的KEYS[1],也就是腳本里的key變量。
執(zhí)行后,會返回1(第一次自增),再執(zhí)行一次返回2,說明腳本執(zhí)行成功!
方式2:緩存腳本,用SHA值調(diào)用(生產(chǎn)推薦)
如果腳本需要頻繁執(zhí)行,每次都傳腳本內(nèi)容會浪費帶寬,這時候可以把腳本緩存到Redis里,Redis會返回一個唯一的SHA值,后續(xù)直接用SHA值調(diào)用即可,性能更高。
# 1. 緩存腳本,返回SHA值 SCRIPT LOAD "$(cat /lua/wzxg.lua)"
SHA 值是 Redis 對 Lua 腳本內(nèi)容進(jìn)行哈希計算后,生成的一串唯一字符串(比如 54cfc1234567890abcdef...),相當(dāng)于這個腳本的 “專屬標(biāo)識”—— 只要腳本內(nèi)容不變,SHA 值就不變;腳本一改,SHA 值就會變。
# 2. 用SHA值執(zhí)行腳本,參數(shù)和EVAL一樣 EVALSHA 54cfc1234567890abcdef 1 mycounter
效果和方式1一樣,但后續(xù)每次執(zhí)行,只需要傳SHA值,不用再傳整個腳本,適合生產(chǎn)環(huán)境頻繁調(diào)用的場景。
三、測試用簡易方案:直接復(fù)制腳本進(jìn)容器
如果只是臨時測試腳本,不想掛載目錄,也可以直接把宿主機(jī)的腳本復(fù)制進(jìn)Redis容器,步驟更簡單,適合快速測試。
# 1. 宿主機(jī)創(chuàng)建腳本(比如還是wzxg.lua,路徑隨意,比如~/wzxg.lua) # 2. 復(fù)制腳本到Redis容器的/lua目錄(沒有這個目錄會自動創(chuàng)建) docker cp ~/wzxg.lua wzxgRedis:/lua/wzxg.lua # 3. 進(jìn)入redis-cli執(zhí)行(和上面步驟3一樣) docker exec -it wzxgRedis redis-cli EVAL "$(cat /lua/wzxg.lua)" 1 mycounter
注意:這種方式,宿主機(jī)修改腳本后,不會同步到容器里,需要重新執(zhí)行docker cp命令復(fù)制,所以只適合測試,不適合生產(chǎn)環(huán)境。
四、踩過的坑
- 掛載目錄時,一定要給宿主機(jī)目錄權(quán)限(chmod 777),否則容器里會提示“權(quán)限不足”,讀不到腳本;
- 執(zhí)行腳本時,KEYS的數(shù)量一定要寫對(EVAL后面的數(shù)字),比如傳2個key,就寫2,否則會報錯;
- 生產(chǎn)環(huán)境一律用「SCRIPT LOAD + EVALSHA」,避免每次傳腳本浪費帶寬;
- Lua腳本里只能用Redis支持的命令(redis.call()),不能寫復(fù)雜的循環(huán)和邏輯,因為Redis是單線程,腳本執(zhí)行時間過長會阻塞Redis;
- 如果腳本里有中文注釋,保存時一定要用UTF-8編碼,否則會出現(xiàn)亂碼,導(dǎo)致腳本執(zhí)行失敗。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker 解決容器時間與主機(jī)時間不一致的問題三種解決方案
這篇文章主要介紹了Docker 解決容器時間與主機(jī)時間不一致的問題的相關(guān)資料,這里提供了三種方法,供大家參考,需要的朋友可以參考下2016-12-12
Docker部署UI自動化測試環(huán)境的實現(xiàn)步驟
本文主要介紹了Docker部署UI自動化測試環(huán)境的實現(xiàn)步驟,通過Docker可以快速創(chuàng)建、部署和測試腳本,提高測試效率,具有一定的參考價值,感興趣的可以了解一下2023-08-08
Windows?Server?2016中文版安裝docker的詳細(xì)步驟
因業(yè)務(wù)需要所以需要安裝Docker,但是在途中遇到了一些問題,所以下面這篇文章主要給大家介紹了關(guān)于Windows?Server?2016中文版安裝docker的詳細(xì)步驟,需要的朋友可以參考下2022-07-07
使用docker在linux環(huán)境中部署springboot包的教程
這篇文章主要介紹了使用docker在linux環(huán)境中部署springboot包,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
Docker搭建代碼檢測平臺SonarQube并檢測maven項目的流程
這篇文章主要介紹了Docker搭建代碼檢測平臺SonarQube并檢測maven項目,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

