lua

2024-02-27  本文已影响0人  哆啦在这A梦在哪

一.redis中原生之行lua

基本命令:https://www.runoob.com/redis/redis-scripting.html
1.准备一个lua脚本,test.lua

local key1 = KEYS[1]
local val1 = ARGV[1]
local key2 = KEYS[2]
local val2 = ARGV[2]

local res = redis.call("get",key1)
if (res == 18) 
then
    redis.call("set",key1,val1)
else
    redis.call("set",key1,10)
end

return redis.call("get",key1)

如果是容器,先进入 redis 容器之行

redis-cli -h 127.0.0.1 -p 6379 eval "$(cat test.lua)" 2 age name 15 stb
# 或者直接写代码也行,比如
redis-cli -h 127.0.0.1 -p 6379 eval "return {KEYS[1],ARGV[1]}" 1 name stb

如果不想每次都执行 redis-cli,那就直接先进入redis命令行,就可以省略redis-cli -h 127.0.0.1 -p 6379,直接执行eval 命令,如下

redis-cli -h 127.0.0.1 -p 6379 
eval "$(cat test.lua)" 1 age 15
# 或者直接写代码也行,比如
eval "return {KEYS[1],ARGV[1]}" 1 name stb

解释

命令后面的 1 ,代表后面有几个 key参数,如果是 2 就是两个参数,比如上面,age和name是两个标识,就是 2,后面的就是对应的内容

golang中使用

package main

import (
    "context"
    "log"

    "github.com/redis/go-redis/v9"
)

func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr: "127.0.0.1:6379",
        DB:   0, // 默认DB 0
    })
    defer rdb.Close()
    ctx := context.Background()
    // 普通执行
    // 其他命令同理
    // res, err := rdb.Eval(ctx, "return {KEYS[1],ARGV[1]}", []string{"name"}, "stb").Result()
    // 多行脚本执行
    res, err := rdb.Eval(ctx, `
    local key1 = KEYS[1]
    local key2 = KEYS[2]
    local val1 = ARGV[1]
    local val2 = ARGV[2]
    
    local res = redis.call("get",key1)
    if (res == 18) 
    then
        redis.call("set",key1,val1)
    else
        redis.call("set",key1,10)
    end
    
    return redis.call("get",key2)
    `, []string{"name", "age"}, "stb", 18).Result()
    if err != nil {
        return
    }
    log.Println("res=:", res)
}

解释:

其实就是 lua 的代码,在redis 中用对应的命令去执行,比如 eval,把lua 代码看成一段字符串,然后用redis eval 命令执行,加上对应的参数即可

问题解析

1.执行错误会继续执行
2.eval每次都会将完整的脚本传递,网络开销大,应该先用script load 预先缓存,然后用反馈的 哈嘻值,使用 evalsha来执行

// 输入该脚本
# redis-cli script load "$(cat test.lua)"
"bdb8680ea6967110d89ea6e574b6cf4b2b3e6507" // 这个用来执行的标识
// 执行该脚本
# redis-cli evalsha bdb8680ea6967110d89ea6e574b6cf4b2b3e6507 2 age name 15 17
(integer) 32 // 反馈结果
上一篇下一篇

猜你喜欢

热点阅读