lua基础
注释:
-- this is a comment
声明全局变量:
x = 123
声明本地变量:
local y = 456
方法声明:
function hello_world()
return "Hello World"
end
迭代:
for i = 1, 10 do
print(i)
end
条件:
if x == 123 then
print("x is the magic number")
else
print("I have no idea what x is")
end
字符串连接:
print("Hello" .. " World")
作为数组使用一个table — 数组的索引从1开始:
data_types = {1.0, 123, "redis", true, false, hello_world}
print(data_types[3]) -- the output is "redis"
作为hash使用一个table:
languages = {lua = 1993, javascript = 1995, python = 1991, ruby =1995}
print("Lua was created in " .. languages["lua"])
print("JavaScript was created in " .. languages.javascript)
redis脚本执行是一种原子操作,所以在执行期间redis服务会被阻塞。默认脚本操作会有5秒的执行时间
当一个lua脚本执行超时不会自动停止,它会开始对每一个命令回复一个busy状态,表明脚本正在运行。使用命令SCRIPT KILL
或者SHUTDOWN NOSAVE
终止脚本执行才能使redis服务回到正常状态
举个栗子
package main
import (
"fmt"
"github.com/go-redis/redis"
)
var Client *redis.Client
func init() {
Client = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
}
//noinspection GoInvalidCompositeLiteral
func main() {
Client.FlushAll()
Client.Set("foo", "bar" , 0)
var luaScript = redis.NewScript(`return redis.call("GET" , KEYS[1])`)
n , err := luaScript.Run(Client , []string{"foo"}).Result()
if err != nil {
panic(err)
}
fmt.Println(n , err)
}
另一个栗子
package main
import (
"fmt"
"github.com/go-redis/redis"
)
var Client *redis.Client
func init() {
Client = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
}
//noinspection GoInvalidCompositeLiteral
func main() {
Client.FlushAll()
foo := []redis.Z{
{
1732, "George Washington",
},
{
1809, "Abraham Lincoln",
},
{
1858, "Theodore Roosevelt",
},
}
Client.ZAdd("presidents", foo...)
var luaScript = redis.NewScript(`
local elements = redis.call("ZRANGE" , KEYS[1] , 0 , 0)
redis.call("ZREM" , KEYS[1] , elements[1])
return elements[1]
`)
n , err := luaScript.Run(Client , []string{"presidents"} , 1).Result()
if err != nil {
panic(err)
}
fmt.Println(n , err)
}
使用evalsha来操作lua
当执行脚本多次的时候,可以使用
SCRIPT LOAD
和EVALSHA
代替EVAL
有可能节省带宽。命令SCRIPT LOAD
缓存一个lua脚本,同时返回一个sha1的标识符。命令EVALSHA
基于sha1的标识符执行脚本,通过SCRIPT LOAD
返回。使用EVALSHA
只有标识符通过网络传输,而不是一个lua代码块
继续举个栗子
package main
import (
"fmt"
"github.com/go-redis/redis"
)
var Client *redis.Client
func init() {
Client = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
}
//noinspection GoInvalidCompositeLiteral
func main() {
Client.FlushAll()
Client.Set("foo" , "bar" , -1)
var luaScript = `return redis.call("INFO")`
result ,err := Client.ScriptLoad(luaScript).Result() //返回的脚本会产生一个sha1哈希值,下次用的时候可以直接使用这个值,类似于
if err != nil {
panic(err)
}
foo :=Client.EvalSha(result ,[]string{})
fmt.Println(foo.Val())
}