当前位置:网站首页 > Lua脚本开发 > 正文

如何执行脚本命令_lua脚本解密工具

在使用redis过程中,我们经常会使用到lua脚本,可能大多数的同学使用场景是这样的:

incrScript := "一大段的lua脚本" redis.Eval(incrScript, keys, args...)

lua脚本可能会很长,这里就会有个问题是需要考虑的,每次执行都有传输一大段文本到redis服务器(脚本文本),很浪费网络io;聪明的同学可能会想到解决方案了。把脚本缓存到服务器上,通过

redis.EvalSha(scHash, keys, args...)

来执行;很好,于是乎这样的思路出现了,先加载脚本到redis服务器,得到一个脚本hash值,通过 EvalSha 来执行脚本,大体的代码是这样的:

scHash, e = redis.ScriptLoad(incrScript) redis.EvalSha(scHash, keys, args...)

但是,这里要解决两个问题:

1)怎么保证ScriptLoad尽量少的执行?

2)集群环境多节点怎么保障?

针对第一个问题,我的思路是这样的,通过一个闭包机制,保障一个进程内,第一次调用执行ScriptLoad得到脚本hash值,具体代码实现:

var incrScriptFn = func() func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { once := &sync.Once{} scHash := "" return func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { once.Do(func() { _ = tools.DoWithRetry(func() error { var e error scHash, e = cli.ScriptLoad(incrScript) return e }, time.Millisecond*15) }) // 通过得到的scHash来调用cli.EvalSha(scHash, keys, args...) ...... ...... ...... } }()

针对第二个问题,我的思路是这样的,因为同样的脚本(注意,脚本里面不能出现随机值和可变值,保障在不同的客户端执行hash的结果是一样的)执行的hash值是一样的,并且redis有个机制,在每次支持eval以后,服务器会缓存该脚本,缓存的脚本hash值跟ScriptLoad得到的hash值是一样的

针对这个机制,我们可以代码这样来实现:

var incrScriptFn = func() func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { once := &sync.Once{} scHash := "" return func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { // 得到scHash ..... ..... ..... // 通过执行脚本hash,可以节约数据的传输 val, err = cli.EvalSha(scHash, keys, args...) if err != nil { // 如果失败,有可能是在集群环境中,打到没有缓存的节点上了,这里通过eval直接执行,执行成功以后,该节点会缓存该脚本,下次 // 执行就直接可以运行EvalSha了 return cli.Eval(incrScript, keys, args...) } return } }()

综上,最后完整的闭包代码实现:

var incrScriptFn = func() func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { once := &sync.Once{} scHash := "" return func(cli *redis.Redis, keys []string, args ...interface{}) (val interface{}, err error) { once.Do(func() { _ = tools.DoWithRetry(func() error { var e error scHash, e = cli.ScriptLoad(incrScript) return e }, time.Millisecond*15) }) if len(scHash) == 0 { // 这里是一个保护设置,保证在incrScriptHash获取不到脚本hash的时候还能正常执行 return cli.Eval(incrScript, keys, args...) } // 通过执行脚本hash,可以节约数据的传输 val, err = cli.EvalSha(scHash, keys, args...) if err != nil { // 如果失败,有可能是在集群环境中,打到没有缓存的节点上了,这里通过eval直接执行,执行成功以后,该节点会缓存该脚本,下次 // 执行就直接可以运行EvalSha了 return cli.Eval(incrScript, keys, args...) } return } }()

调用的地方:

说到最后:

当然,有的同学可能会这样想,我们可以让运维同学先把脚本缓存到服务器呀,代码里面直接使用hash值。但是这里有个问题就是运维成本的问题,加之在redis环境中,节点可能是动态伸缩的。所以从简单角度考虑,还是代码实现更方便。

欢迎大家砸砖讨论,留言转发关注

到此这篇如何执行脚本命令_lua脚本解密工具的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • lua脚本编辑器_lua开发2024-11-04 17:00:09
  • redis 脚本语言_redis执行lua脚本2024-11-04 17:00:09
  • redis使用lua脚本加锁和解锁_lua编程软件2024-11-04 17:00:09
  • lua脚本语言主要用来做什么_lua编程软件2024-11-04 17:00:09
  • lua脚本引擎_lua脚本编辑器2024-11-04 17:00:09
  • redis lua pipeline_罗技lua脚本2024-11-04 17:00:09
  • lua脚本如何做成插件_wireshark lua插件2024-11-04 17:00:09
  • lua 开源项目_lua游戏脚本自动打怪2024-11-04 17:00:09
  • lua脚本语言零基础教程_lua可视化脚本编辑器2024-11-04 17:00:09
  • redisson lua脚本_如何编写脚本2024-11-04 17:00:09
  • 全屏图片