阿里云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));
}
原文地址:https://www.cnblogs.com/masonblog/p/14792963.html