go、redis使用lua脚本的学习

go lua redis

在redis使用lua脚本的好处

  • 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。
  • 原子操作。Redis会将整个脚本作为一个整体执行,中间不会被其他请求插入。因此在脚本运行过程中无需担心会出现竞态条件,无需使用事务。
  • 复用。客户端发送的脚本会永久存在redis中,这样其他客户端可以复用这一脚本,而不需要使用代码完成相同的逻辑。

在redis中使用lua脚本

lua 可以通过redis.call()调用redis命令

//返回redis中KEYS[1] 的值
retrun redis.call('GET',KEYS[1])

redis中的一些lua命令

  • EVAL
    • 命令格式:EVAL script numkeys key [key …] arg [arg …]
    • script参数是一段 Lua 脚本程序
    • numkeys指定后续参数有几个key,即:key [key …]中key的个数。如没有key,则为0
    • key [key …] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key)。在Lua脚本中通过KEYS[1], KEYS[2]获取。
    • arg [arg …] 附加参数。在Lua脚本中通过ARGV[1],ARGV[2]获取。
    //相当于SETEX key1 60 10 
    EVAL "redis.call('SET',KEYS[1],ARGV[1]);redis.call('EXPIRE',KEYS[1],ARGV[2]);return 1;" 1 key1 10 60
    
  • SCRIPT LOAD
    • 命令格式 SCRIPT LOAD script
    • SCRIPT LOAD 将脚本 script 添加到Redis服务器的脚本缓存中,并不立即执行这个脚本,而是会立即对输入的脚本进行求值。并返回给定脚本的 SHA1 校验和。如果给定的脚本已经在缓存里面了,那么不执行任何操作。
  • EVALSHA
    • 命令格式:EVALSHA sha1 numkeys key [key …] arg [arg …]
    • 在脚本被加入到缓存之后,在任何客户端通过EVALSHA命令,可以使用脚本的 SHA1 校验和来调用这个脚本。脚本可以在缓存中保留无限长的时间,直到执行SCRIPT FLUSH为止。
  • SCRIPT EXISTS
    • 命令格式:SCRIPT EXISTS sha1 [sha1 …]
    • 给定一个或多个脚本的 SHA1 校验和,返回一个包含 0 和 1 的列表,表示校验和所指定的脚本是否已经被保存在缓存当中
  • SCRIPT FLUSH
    • 命令格式:SCRIPT FLUSH
    • 清除Redis服务端所有 Lua 脚本缓存
  • SCRIPT KILL
    • 命令格式:SCRIPT KILL
    • 杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效。 这个命令主要用于终止运行时间过长的脚本,比如一个因为 BUG 而发生无限 loop 的脚本,诸如此类。
    • 假如当前正在运行的脚本已经执行过写操作,那么即使执行SCRIPT KILL,也无法将它杀死,因为这是违反 Lua 脚本的原子性执行原则的。在这种情况下,唯一可行的办法是使用SHUTDOWN NOSAVE命令,通过停止整个 Redis 进程来停止脚本的运行,并防止不完整(half-written)的信息被写入数据库中。
127.0.0.1:6379> SCRIPT LOAD "redis.call('SET',KEYS[1],ARGV[1]);redis.call('EXPIRE',KEYS[1],ARGV[2]);return 1;"
"6cc501292668ceef3dd487b3e4e889dc08d07587"
127.0.0.1:6379> EVALSHA "6cc501292668ceef3dd487b3e4e889dc08d07587" 1 key1 10 60
(integer) 1
127.0.0.1:6379> get key1
"10"
127.0.0.1:6379> ttl key1
(integer) 42
127.0.0.1:6379> SCRIPT EXISTS "6cc501292668ceef3dd487b3e4e889dc08d07587"
1) (integer) 1
127.0.0.1:6379> SCRIPT FLUSH
OK
127.0.0.1:6379> SCRIPT EXISTS "6cc501292668ceef3dd487b3e4e889dc08d07587"
1) (integer) 0

redis直接执行lua脚本文件

  • script.lua
    redis.call('SET',KEYS[1],ARGV[1]);
    redis.call('EXPIRE',KEYS[1],ARGV[2]);
    return 1;
    
  • 终端中执行命令: redis-cli -a 密码 --eval Lua脚本路径 key [key …] , arg [arg …]
    redis-cli -a 123456 --eval ./script.lua key1 , 10 , 60
    

在go中调用

这里我们使用redigo,下面是几个简单的函数

Dial

  • func Dial(network, address string, options …DialOption) (Conn, error)
	//dial创建单条连接
	//example
	c, err := redis.Dial("tcp", ":6379")
	if err != nil {
   
		// handle error
	}
	defer c.Close()

	//建一个连接池
	pool := &redis.Pool{
   
		// 最大空闲链接
		MaxIdle: 10,
		// 最大激活链接
		MaxActive: 10,
		// 最大空闲链接等待时间
		IdleTimeout: 10 * time.Second,
		Dial: func() (redis.Conn, error) {
   
			c, err := redis.Dial("tcp", "127.0.0.1:6379")
			if err != nil {
   
				fmt.Println("Connect to redis error", err)
			}
			return c, nil
		},
	}
	c:=pool.Get()

Do or Send

	//Do让redis客户端执行命令
	c.
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值