内容简介:Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua可以在很多地方使用比如游戏开发、独立应用脚本、Web应用脚本、扩招和数据库插件等等。今天记录的是在redis中执行lua脚本实现原子操作。如果不是专业些lua脚本我们可以看下在redis中使用lua的场景很多,这次记录的使用场景是:开发需要用到redis记录一个有顺序的数据,但是又不能重复添加。所以准备先用一个set记录list存在的值用来判断是否重复(set
Lua
Lua 是一种轻量小巧的脚本语言,用标准 C语言 编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua可以在很多地方使用比如游戏开发、独立应用脚本、Web应用脚本、扩招和数据库插件等等。今天记录的是在 redis 中执行 lua 脚本实现原子操作。如果不是专业些lua脚本我们可以看下 菜鸟联盟 的简单教程,已经够我们平时简单使用了。
使用场景
在redis中使用lua的场景很多,这次记录的使用场景是:开发需要用到redis记录一个有顺序的数据,但是又不能重复添加。所以准备先用一个set记录list存在的值用来判断是否重复(set在redis中是不允许重复的),再用list数据类型进行保存。但是如果分开执行这些语句在高并发的情况下可能会遇到问题,在某种情况下可能会加入重复数据。这个时候就可以用到lua脚本来原子的执行这两条语句。
代码
package main import ( "fmt" "time" "github.com/gomodule/redigo/redis" ) const( SCRIPT_INCR = ` local num = redis.call('sismember', KEYS[1], ARGV[1]) if num > 0 then return -1 else redis.call('sadd',KEYS[1],ARGV[1]) return redis.call('lpush',KEYS[2],ARGV[1]) end ` ) func init()(){ initRedis() } var redisCoon redis.Conn //初始化redis连接,redis在本地 docker 中运行 func initRedis()(){ redisClient := &redis.Pool{ // 最大空闲链接 MaxIdle: 10, // 最大激活链接 MaxActive: 10, // 最大空闲链接等待时间 IdleTimeout: 5 * time.Second, Dial: func() (redis.Conn, error) { rc, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { return nil, err } rc.Do("SELECT", 0) fmt.Println("USE DB", 0) return rc, nil }, } redisCoon = redisClient.Get() } func AddCode(id,code string)(){ lua := redis.NewScript(2, SCRIPT_INCR) in,err :=redis.Int(lua.Do(redisCoon, "u:"+id, "u:set:"+id, code)) fmt.Println(in,"--",err) } func main() { AddCode("1","60001") AddCode("1","60001") AddCode("1","60002") } //执行结果 //1 -- <nil> //-1 -- <nil> //2 -- <nil> //redis查询结果 //127.0.0.1:6379> lrange u:set:1 0 -1 //1) "60002" //2) "60001" //127.0.0.1:6379> smembers u:1 //1) "60001" //2) "60002"
在 go 中使用的是redigo的包来操作redis。redigo自带redis连接池可以方便的定义做大连接数,最大空闲数,最大空闲连接等和超时时间等。我们可以很方便控制这些参数也可以很方便的执行lua脚本。执行步骤如下:
- 第一步需要新建一个脚本对象,第一个参数为keycount,标志你的lua脚本参数中key的个数 第二个参数为脚本字符串
- 第二步 执行这个脚本,把定义时候的2个key传递过去,之后的参数为脚本中的ARGV
- 第三部 使用redis.Int 获取返回值,如果没有返回值直接使用Do即可
脚本接受一个set的key和一个list的key 先判断set是否存在保证没有重复。之后再去往list中添加,避免高并发中加入重复数据。如果已经存在则返回-1表示。如果没有则往set,list中都添加值。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Erlang趣学指南
邓辉、孙鸣 / 人民邮电出版社 / 2016-9-7 / 79.00元
这是一本讲解Erlang编程语言的入门指南,内容通俗易懂,插图生动幽默,示例短小清晰,结构安排合理。书中从Erlang的基础知识讲起,融汇所有的基本概念和语法。内容涉及模块、函数、类型、递归、错误和异常、常用数据结构、并行编程、多处理、OTP、事件处理,以及所有Erlang的重要特性和强大功能。一起来看看 《Erlang趣学指南》 这本书的介绍吧!