【阿里云Redis】由[主从版]调整为[集群版]问题记录
前言
业务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));
}

浙公网安备 33010602011771号