怎么在Golang中利用lua脚本实现复述,原子操作

  介绍

今天就跟大家聊聊有关怎么在Golang中利用lua脚本实现复述,原子操作,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

<强>目录

<李>

[复述,调用lua脚本)(#复述,调用lua脚本)

<李>

[复述+ lua实现评分排行榜实时更新)(#复述+ lua实现评分排行榜实时更新)

[lua脚本)(# lua脚本)
Golang调用复述+ lua示例
字节切片与字符串的转换优化

<强>复述,调用lua脚本

<强> EVAL命令

复述,调用lua脚本需要使用EVAL命令。

复述,EVAL命令格式:

复述127.0.0.1:6379>EVAL脚本numkeys键[键……)参数(参数…)

最简单的例子:

127.0.0.1:6379>, eval “return {& # 39;你好,,GrassInWind ! & # 39;}“0   1),“你好,,GrassInWind !“   127.0.0.1:6379>, eval “return  redis.call(& # 39;集# 39;键[1],& # 39;酒吧# 39;)“1,foo   好

使用redis-cli调用lua脚本示例(若在windows系统下,则需要git在bash中执行,在powershell中无法读取值):

* * * @LAPTOP-V7V47H0L  MINGW64 /d/学习/代码/lua   美元,redis-cli.exe  -a  123年,——eval  test.lua  testkey ,你好   你好

测试。lua如下(复述,日志打印在服务器的日志中):

local 关键,value =,键[1],ARGV [1]   redis.log (redis.LOG_NOTICE,“关键=?,,,“价值=https://www.yisu.com/zixun/?值)   复述。调用(“设置”键,值)   当地一个=复述。调用(‘得到’,关键)   返回一个

<强>脚本命令

复述,提供了以下几个脚本命令,用于对于脚本子系统进行控制:

脚本刷新:清除所有的脚本缓存

脚本加载:将脚本装入脚本缓存,不立即运行并返回其校验和

脚本存在:根据指定脚本校验和,检查脚本是否存在于缓存

脚本杀:杀死当前正在运行的脚本(防止脚本运行缓存,占用内存)

主要优势:减少网络开销:多个请求通过脚本一次发送,减少网络延迟

原子操作:将脚本作为一个整体执行,中间不会插入其他命令,无需使用事务

复用:客户端发送的脚本永久存在复述中,其他客户端可以复用脚本

可嵌入性:可嵌入JAVA、c#等多种编程语言,支持不同操作系统跨平台交互

通过脚本命令加载及执行lua脚本示例:

127.0.0.1:6379>, script  load “return  & # 39; Hello  GrassInWind& # 39;“   “c66be1d9b54b3182f8d8e12f8b01a4e5c7c4af5b"   127.0.0.1:6379>, script  exists “c66be1d9b54b3182f8d8e12f8b01a4e5c7c4af5b"   1),(整数),1   127.0.0.1:6379>, evalsha “c66be1d9b54b3182f8d8e12f8b01a4e5c7c4af5b" 0   “Hello  GrassInWind"   127.0.0.1:6379> script 冲洗   好吧   127.0.0.1:6379>, script  exists “c66be1d9b54b3182f8d8e12f8b01a4e5c7c4af5b"   1),(整数),0

#复述+ lua实现评分排行榜实时更新

使用复述的zset保存排行数据,使用lua脚本实现评分排行更新的原子操作。

<强> lua脚本

相关复述,命令:ZCARD关键获取有序集合的成员数

ZRANGEBYSCORE关键分钟马克斯(WITHSCORES)(限制)通过分数返回有序集合指定区间内的成员(从小到大的顺序)

ZREMRANGEBYRANK关键开始停止移除有序集合中给定的排名区间的所有成员

ZADD关键score1 member1 [score2 member2]向有序集合添加一个或多个成员,或者更新已存在成员的分数

主要思路是维护一个zset,将评分前N位保存到复述中,当成员的评分发生变化时,动态更新zset的成员信息。

lua脚本如下,其中键[1]表示zset的关键,ARGV[1]表示期望的zset最大存储成员数量,ARGV[2]表示评分上限,默认评分下限是0,ARGV[3]表示待添加的评分,ARGV[4]表示待添加的成员名称。

——,redis  zset 操作   ——,argv [capacity  maxScore  newMemberScore 成员)   ——,执行示例,redis-cli.exe ——eval  zsetop.lua  mtest ,, 3, 5, 5 test1   ——,获取键和参数   local 键帽,maxSetScore、newMemberScore member =,键[1],ARGV [1], ARGV [2], ARGV [3], ARGV [4]   redis.log (redis.LOG_NOTICE,“关键=?,,,,帽=?,,,,maxSetScore=?,, maxSetScore,“, newMemberScore=?,, newMemberScore,“,成员=?,,成员)   local  len =, redis.call (& # 39; zcard& # 39;,,键);   ——,len  need  not  nil,, otherwise  will  occur “attempt 用compare  nil  with  number"   if  len 然后   当时,if  (len),祝辞=,当时(cap)   ,然后   local 才能;num =,当时(len),当时(cap) + 1   local 才能;list =, redis.call (& # 39; zrangebyscore& # 39;,键,0,maxSetScore, & # 39;限制# 39;,0,num)   redis.log才能(redis.LOG_NOTICE,“关键=凹?“maxSetScore=? maxSetScore,,“num=? num)   for  k,才能lowestScoreMember 双(列表),拷贝   ,,local  lowestScore =, redis.call (& # 39; zscore& # 39;,,关键,lowestScoreMember)   ,,redis.log (redis.LOG_NOTICE,“列表:,,,,lowestScore,, lowestScoreMember)   ,,if 当时(newMemberScore),祝辞,当时(lowestScore)   ,,   ,,,local  rank =, redis.call (& # 39; zrevrank& # 39;,钥匙,成员)   ,,,,,rank  is  nil  indicate  new  member  is  not  exist 集,拷贝,need  remove 从而lowest  score 成员   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

怎么在Golang中利用lua脚本实现复述,原子操作