前言
业务Redis数据库,版本4.0社区版
Redis由主从版调整为集群版,遇到了一些问题,做个记录
夜里2点调整Redis,
然后接口出现了下面的问题,一直调整到天亮才弄好,心好累。
问题一、InternalFailure on
问题描述
查询configinfo的信息,get configinfo
报错提示
InternalFailure on GET configinfo
解决方式
创建redis客户端时,需要添加些属性,添加的属性作用是啥也不晓得,后续再百度吧
Config创建客户端
区别:添加 CommandMap
ConfigurationOptions config = new ConfigurationOptions { EndPoints = { { "957.redis.rds.aliyuncs.com", 6379 } }, CommandMap = CommandMap.Create(new HashSet<string> { "INFO", "CONFIG", "CLUSTER", "PING", "ECHO", "CLIENT" }, available: false), KeepAlive = 180, DefaultVersion = new Version(2, 8, 19), Password = "957957" }; var redis = ConnectionMultiplexer.Connect(config).GetDatabase(15); while (true) { Console.WriteLine("请输入key:"); string key = Console.ReadLine().Trim(); Console.WriteLine("请输入value:"); string value = Console.ReadLine().Trim(); redis.StringSet(key, value, DateTime.Now.AddMinutes(10) - DateTime.Now); Console.WriteLine("从Redis中读取{0}的值为: {1}", key, redis.StringGet(key)); }
链接字符串创建客户端
区别:添加 keepAlive=180,version=2.8.19,$CLIENT=,$CLUSTER=,$CONFIG=,$ECHO=,$INFO=,$PING=
//"RedisConnectionString": "957.redis.rds.aliyuncs.com:6379,password=957957,allowadmin=true,connectTimeout=5000,connectRetry=10,syncTimeout=25000",
调整为
//"RedisConnectionString": "957.redis.rds.aliyuncs.com:6379,password=957957,allowadmin=true,keepAlive=180,version=2.8.19,$CLIENT=,$CLUSTER=,$CONFIG=,$ECHO=,$INFO=,$PING=,connectTimeout=5000,connectRetry=10,syncTimeout=25000",
问题二、ERR for redis cluster, eval/evalsha number of keys can't be negative or zero
问题描述
释放redis锁,为了一致性,使用Lua脚本去操作的。
报错提示
提示信息:ERR for redis cluster, eval/evalsha number of keys can't be negative or zero
参考文章
将Lua的参数,传递方式调整下。
由百度,得阿里云的限制
文章:https://developer.aliyun.com/article/645851
解决方式
新写法,支持主从模式和集群模式
/// <summary> /// 业务层 - 更新操作 /// </summary> public async Task<bool> Update() { string key = "lock:99900"; string value = "33559"; var result = await redis.LockReleaseAsync(key, value); } /// <summary> /// 释放锁 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public async Task<RedisResult> LockReleaseAsync(string key, string value) { key = AddSysCustomKey(key); //2021年5月21日09:46:11,由于Redis服务器调整为集群模式,所有key都应该由 KEYS 数组来传递,redis.call/pcall 中调用的redis命令,key的位置必须是KEYS array string script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; RedisKey[] keys = new RedisKey[1]; keys[0] = key; RedisValue[] values = new RedisValue[1]; values[0] = value; return await Do(redis => redis.ScriptEvaluateAsync(script, keys, values)); }
旧写法,仅支持主从模式
/// <summary> /// 业务层 - 更新操作 /// </summary> public async Task<bool> Update() { string key = "lock:99900"; string value = "33559"; var result = await redis.ScriptEvaluateAsync(releaseLockScript, new { key = key, value = value }); } /// <summary> /// 数据层 - 执行Lua脚本 /// </summary> public async Task<RedisResult> ScriptEvaluateAsync(object parameters = null) { string script = "if redis.call('get', @key) == @value then return redis.call('del', @key) else return 0 end"; var prepared = LuaScript.Prepare(script); return await Do(redis => redis.ScriptEvaluateAsync(prepared, parameters)); }