分享如何在 .NET Core 使用 C# 正確的使用 Redis Lua Script 開發與除錯流程。
先前分享如何使用 ZeroBrane Studio 協助 Redis 的 Lua Script 開發與除錯介紹如何正確地使用工具來幫我們除錯 Redis Lua Script.
本次結合 C#, .NET Core 與 macOS 環境,重新整理與介紹如何正確地使用 Redis Lua Script.
為什麼使用 Redis Lua Script
在大部分的開發者中,會使用 Redis 相關 framework 的人很普遍,但絕大多數僅使用這些 Framework 已包裹好的指令做操作,鮮少自己將商業邏輯包裹成一個 Lua Script
指令操作.
以 C# + .NET Core 為例,大多使用者都會使用下列的 framework 操作 Redis 內資料:
如果今天要開發的一個資料儲存的情境如下:
- 確認當前
test
是否存在,如果不存在則在第一次呼叫的時候給予預設值0
- 第二次開始的呼叫會針對
test
當前的值每次增加50
以一般 Redis 的指令操作來說我們需要透過多個指令串接以上內容,這會造成 .NET Core 的程式多次進出 Redis Instance 內.
而透過 Lua Script
以上的指令可以僅透過一個客製的指令進行操作,大幅提升 Redis 效能與反應.
Redis的架構設計單執行緒的設計,在運行Lua script的時候是沒辦法處理其他的請求的,所以Lua script並不能像Database的Stored Procedure一樣運行複雜的商務邏輯,個人認為如果有以下情境可以考慮採用:
- 避免多次請求來回浪費掉的round-trip network latency
- 創造出 Redis 與 Redis Framework 沒有支援的command
- Atomic的資料操作 與 Transaction
Redis Lua Script Development and Debugging on macOS
這邊開始介紹如何在 macOS 的環境開發 Redis Lua Script
大致上的內容請先參考分享如何使用 ZeroBrane Studio 協助 Redis 的 Lua Script 開發與除錯
Redis with Docker
環境使用 Docker 進行 Redis Instance 的建置,指令如下:
docker pull Redis
docker run -P --name redis-lab -d redis
透過 -P
參數,這裡進行動態的 port 配置與對應至 container 內的 6379
port
從 docker ps -a
可以查到當前配置的 port 為 32768
透過以下指令與 redis-cli
取得當前的所有鍵值
docker exec -it <container-id> bash
redis-cli
KEYS *
Install ZeroBrane Studio
至官網下載ZeroBrane Studio 與 ZeroBranePackage/redis.lua 這個 plugin
安裝好後可配置使用者設定,載入剛下載的 plugin 至 ZeroBrane Studio 中:
mkdir $HOME/.zbstudio
mkdir $HOME/.zbstudio/packages
接者將下載的 redis.lua
plugin 檔案放入剛剛建立的目錄下($HOME/.zbstudio/packages)
接著將程序打開後可以看到下圖及代表設定成功:
而開發時不要忘記要開啟 watch window
與 stack window
協助觀察變數的變化
Try round for ZeroBrane Studio debugging
這邊開啟應用程式後選擇 redis
則會跳出連線設定視窗,如果要重設則需要重新啟動 ZeroBrane Studio 才可以變更.
而如果開發的 Lua Script
本身有帶入參數的需求可以使用 Command Line Parameters
的設定帶入(多個參數可用空白分隔)
如需求所列,這邊我們建立的 Lua Script 如下:
test.lua
1 | local targetKey = KEYS[1] -- target key for redis |
這邊就需要傳入三個參數,所以設定上則變成:
test 為 Key,透過中間的逗號
分隔了後面兩個 Arg ,分別為 0 與 10
而介面上簡單介紹如下(詳細介紹可參考如何使用 ZeroBrane Studio 協助 Redis 的 Lua Script 開發與除錯):
.NET Core with Redis Lua Script
這邊最後給一段 Sample Code 說明如何透過預先載入的方式避免執行重複的 Redis Lua Script 所造成的內存耗盡問題.
其實 Redis 本身就有這個做法,可透過 SCRIPT LOAD 產生一組 SHA 的編碼後,透過 SHA 與 EVALSHA 來執行.
所以這邊的 C# 與上面已經寫好的 test.lua 的呼叫如下:
program.cs
1 | using System; |
執行結果如下:
這段程式碼還有呼叫了Load()
,這會把Lua script先載入指定的Redis server
一般指定 Master 就可以了,會自動鏡像備份到Slave。
載入後會拿到一個SHA1的 hash code,之後執行時只需傳入這個code,不需重傳整份Lua script,對需要頻繁執行的script有效能上的幫助。