问题描述

需求:从一个变化的列表list中取出第一条数据,list 10s更新一次,10s内不能一直取第一条,需要均衡;

bug代码:

// lua脚本
var copyIndexScript string = `local value = redis.call("Get", KEYS[1])if value == false  thenredis.call("Set" , KEYS[1], "0")redis.call("Expire" , KEYS[1], KEYS[2])return 0elselocal value1 = redis.call("Incr" , KEYS[1])return value1end`
// lua脚本缓存hash值
var copyIndexLuaHash string
//redis初始化
func init() {RedisClient = redis.NewClusterClient(&redis.ClusterOptions{Addrs:    []string{"127.0.0.1:7000","127.0.0.1:7001","127.0.0.1:7002","127.0.0.1:7003","127.0.0.1:7004","127.0.0.1:7005"},Password: "", //密码 })//脚本会产生一个sha1哈希值,下次用的时候可以直接使用这个值copyIndexLuaHash, _ = RedisClient.ScriptLoad(copyIndexScript).Result()
}
// 获取下标值
n, err := RedisClient.EvalSha(copyIndexLuaHash, []string{id, time}).Result()

报错:CROSSSLOT Keys in request don't hash to the same slot
原因:所有key必须在1个slot上

修改为:用参数传参;

// lua脚本
var copyIndexScript string = `local value = redis.call("Get", ARGV[1])if value == false  thenredis.call("Set" , ARGV[1], "0")redis.call("Expire" , ARGV[1], ARGV[2])return 0elselocal value1 = redis.call("Incr" , ARGV[1])return value1end`
// 获取下标值
n, err := RedisClient.EvalSha(copyIndexLuaHash,nil, []string{id, time}).Result()

报错:NOSCRIPT No matching script. Please use EVAL
原因:集群模式,在当前节点,获取缓存sha1,可能获取不到;干脆直接用eval

script load命令用于将脚本script添加到脚本缓存中,但并不立即执行这个脚本。如果给定的脚本已经在缓存里面了,那么不执行任何操作。在脚本被加入到缓存之后,通过EVALSHA命令,可以使用脚本的 SHA1 校验和来调用这个脚本。脚本可以在缓存中保留无限长的时间,直到执行SCRIPT FLUSH为止。
EVAL命令也会将脚本添加到脚本缓存中,但是它会立即执行输入的脚本。

// 获取下标值
n, err := RedisClient.Eval(copyIndexScript,nil, []string{id, time}).Result()

适配阿里云redis集群,报错:ERR for redis cluster, eval/evalsha number of keys can't be negative or zerorn

阿里云Redis集群对lua脚本限制如下: https://developer.aliyun.com/article/645851

  1. 所有key都应该由 KEYS 数组来传递,redis.call/pcall 中调用的redis命令,key的位置必须是KEYS array(不能使用Lua变量替换KEYS),否则直接返回错误信息,“-ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS arrayrn”。
  2. 所有key必须在1个slot上,否则返回错误信息,“-ERR eval/evalsha command keys must be in same slotrn”。
  3. 调用必须要带有key,否则直接返回错误信息, “-ERR for redis cluster, eval/evalsha number of keys can’t be negative or zerorn”。

解决方案:

按照KEYS,ARGV传参

// lua脚本
var copyIndexScript string = `local value = redis.call("Get", KEYS[1])if value == false  thenredis.call("Set" , KEYS[1], "0")redis.call("Expire" , KEYS[1], ARGV[1])return 0elselocal value1 = redis.call("Incr" , KEYS[1])return value1end`
// 获取下标值
n, err := RedisClient.Eval(copyIndexScript, []string{id}, time).Result()

扩展:redis lua脚本做ip限流

ratelimiting.lua,内容如下

local times = redis.call('incr',KEYS[1])if times == 1 thenredis.call('expire',KEYS[1], ARGV[1])
endif times > tonumber(ARGV[2]) thenreturn 0
end
return 1

在redis客户端机器上,如何测试这个脚本呢?如下:

redis-cli --eval ratelimiting.lua rate.limiting:127.0.0.1 , 10 3

记录go-redis使用集群时,报错:CROSSSLOT Keys in request don‘t hash to the same slot相关推荐

  1. K8S排水错误汇总(忽略DaemonSet管理Pod、Mysql集群排水报错、Mongo集群排水报错)

    文章目录 [成功排水展示] 初始状态 排水命令 正确排水的输出 排水后结果 恢复节点 [FAQ] 1. 忽略DaemonSet管理的Pod 语法 报错示例 2. 删除本地数据 语法 报错示例(mysq ...

  2. redis集群搭建报错-(error) CLUSTERDOWN The cluster is down

    [README] 最近搭建一个redis集群,参考博文 (https://www.cnblogs.com/mafly/p/redis_cluster.html) 对集群配置后,master, slav ...

  3. 执行redis命令redis-trib.rb查看集群信息报错cannot load such file -- redis (LoadError)

    问题描述: 在执行redis-trib.rb命令查看集群状态的时候,报错: [aiprd@hadoop1 ~]$ redis-trib.rb check 192.168.30.10:7000 Trac ...

  4. 关于redis创建集群时出现[ERR] Node x.x.x.x:6379 is not empty. Either the node already knows other nodes (check

    独醉F 2020-04-28 18:52:15 576 收藏 文章标签: redis linux 数据库 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接 ...

  5. 从零开始在ubuntu上安装和使用k8s集群及报错解决

    文章目录 安装docker 安装kubernetes 配置k8s集群 配置虚拟机网络 配置Master节点的k8s网络 拉取k8s需要的镜像 启动 kubeadm 和 kubelet 配置 node节 ...

  6. mysql集群重启报错lock_CentOS7.2 下 MySQL 之 PXC 集群部署【Docker+单机多节点】

    背景 [注意]: 鄙人认为本篇适合做入门测试/学习之用,选择的 "单机多节点配置",后面再整理 "多机配置"文章. 近期正突击学习数据库知识 想着对 PXC 集 ...

  7. ceph-deploy离线部署ceph集群及报错解决FAQ

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...

  8. zookeeper集群搭建报错日志:Cannot open channel to 3 at election address ecs-db04/192.168.0.4:3888

    今日闲来无事搭建个zk集群玩玩,结果遇到一些问题,记录在此,可以参考排错.. 在配置完参数后启动服务,查看服务状态时报一下这个问题: ZooKeeper JMX enabled by default ...

  9. 部署k8s集群及报错完美解决方案

    目录 部署环境 一.master操作 二.node01操作 三.Kubernetes部署容器化应用 四.其他报错解决 部署环境 Linux版本 CPU MEM CentOS7 双核 4G/node m ...

最新文章

  1. .NET(C#、VB)移动开发——Smobiler平台控件介绍:TextTabBar控件
  2. 全球及中国水产加工市场消费潜力分析与投资规模建议报告2022版
  3. [程序员面试题精选100题]19.反转链表
  4. mysql的indata文件_【数据分析】MySQL之不能导入本地文件“Loading local data is disable;”...
  5. Cassandra1.2文档学习(12)—— hint机制
  6. linux查看java虚拟机内存_深入理解java虚拟机(linux与jvm内存关系)
  7. win7系统文件夹属性在哪打开
  8. 天梯—奇偶分家(C语言)
  9. 一种基于annotation的Spring-mvc权限控制方法
  10. java面试之多线程篇
  11. 通过8uftp客户端连接FTP服务器来感受防火墙下FTP主动模式和被动模式的区别。
  12. CPU内部架构与工作原理
  13. 怎样把文件转成bt文件?
  14. java计算2个日期的天数时间差
  15. distinct效率更高还是group by效率更高?
  16. 310实验室一点补充
  17. 问题:MongoDB C# driver异常:Truncation resulted in data loss
  18. mapping文件的编写
  19. GitBook在Windows下安装部署
  20. 给IDA7.0的python2.7安装模块库

热门文章

  1. C#控制Excel的打印格式
  2. 细数流落民间的10大贵族CN域名
  3. 客户视频|申银万国期货曹总:选择ZStack的3个关键因素
  4. 数据分析经典图书推荐
  5. android 横向头像栏,GitHub - liushiqi0112/android-headimage-cliper: 头像上传图片裁剪,实现仿QQ、微信两种效果...
  6. 14期《世有华章,字字如玉》7月刊
  7. lda主题模型困惑度_Perplexity(困惑度)详解
  8. 我和Java的爱恨情仇
  9. DELPHI实现键盘勾子
  10. 《一直在路上》系列—大美西北,西北大环线