【发布时间】:2016-12-02 18:31:41
【问题描述】:
我花了很多天尝试使用不同的方法向 redis 集群发送多个命令,但仍然没有解决方案。这种方法是使用 StachExchange。我有一个 redis 集群,有 3 个主节点,每个主节点有 1 个从节点。端口 30001、30002 和 30003 是主端口
这是我的代码
using StackExchange.Redis;
using System;
namespace redis
{
class Program
{
static void Main(string[] args)
{
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.1.100:30001,192.168.1.100:30002,192.168.1.100:30003,connectTimeout=1000");
IDatabase db = redis.GetDatabase();
db.StringSet("mykey", "abcdefg");
db.StringSet("mykey1", "11111");
db.StringSet("mykey2", "2222");
string value2 = db.StringGet("mykey2");
Console.WriteLine(value2);
}
}
}
下面是错误
Unhandled Exception: StackExchange.Redis.RedisServerException: Endpoint 127.0.0.1:30003 serving hashslot 14687 is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect.
at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server)
at StackExchange.Redis.RedisDatabase.StringSet(RedisKey key, RedisValue value, Nullable`1 expiry, When when, CommandFlags flags)
at redis.Program.Main(String[] args) in c:\users\xxxx\documents\visual studio 2015\Projects\redis\redis\Program.cs:line 31
Press any key to continue . . .
我还做了一些实验,直接向 redis cli 运行命令,我在发送我认为导致问题的命令后注意到重定向
在发送命令之前,我已将命令刷新到我的主人 30001、30002 和 30003
xxxx@RedisServer:~/cluster-test/30003$ redis-cli -c -p 30001
127.0.0.1:30001> set mykey "abcdefg"
-> Redirected to slot [14687] located at 127.0.0.1:30003
OK
127.0.0.1:30003> set mykey1 "11111"
-> Redirected to slot [1860] located at 127.0.0.1:30001
OK
127.0.0.1:30001> set mykey2 "2222"
-> Redirected to slot [14119] located at 127.0.0.1:30003
OK
127.0.0.1:30003> get mykey
"abcdefg"
127.0.0.1:30003> get mykey1
-> Redirected to slot [1860] located at 127.0.0.1:30001
"11111"
127.0.0.1:30001> get mykey2
-> Redirected to slot [14119] located at 127.0.0.1:30003
"2222"
127.0.0.1:30003>
我需要帮助将这些命令发送到 redis 集群。顺便说一句,代码在非集群上运行得很好
12/4 更新Endpoint 127.0.0.1:30003 serving hashslot 14687 is not reachable at...
查看上面的错误代码,我将连接更改为仅连接到端口 30003
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.1.100:30003,connectTimeout=1000");
IDatabase db = redis.GetDatabase();
db.StringSet("mykey", "abcdefg");
它能够连接并设置 mykey
127.0.0.1:30003> get mykey
"abcdefg"
另一个测试
这次我在 mykey1 所在的行中设置了一个调试
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.1.100:30003,connectTimeout=1000");
IDatabase db = redis.GetDatabase();
db.StringSet("mykey", "abcdefg");
db.StringSet("mykey1", "11111");
mykey 行是成功的,因为我们正在连接到 mykey 的哈希槽所属的节点 但是 mykey1 有一个例外,因为它的哈希槽属于 30001 节点
occurred in StackExchange.Redis.dll
Additional information: Endpoint 127.0.0.1:30001 serving hashslot 1860 is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover from the network disconnect.
我认为问题是 StackExchange.Redis 客户端无法知道密钥属于哪个 hashlot,因为 redis 集群中的每个密钥都有对应的 hashlot 属于特定的主节点
另一个测试
mykey 属于 30003,所以我先把 192.168.1.100:30003 放在连接字符串中 然后我知道 mykey1 属于 192.168.1.100:30001 所以我把它放在 30003 之后
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("192.168.1.100:30003,192.168.1.100:30001,connectTimeout=1000");
IDatabase db = redis.GetDatabase();
db.StringSet("mykey", "abcdefg");
db.StringSet("mykey1", "11111");
调试后的结果,设置mykey
时出现如下异常An unhandled exception of type 'StackExchange.Redis.RedisServerException' occurred in StackExchange.Redis.dll
Additional information: Endpoint 127.0.0.1:30003 serving hashslot 14687 is not reachable at this point of time. Please check connectTimeout value. If it is low, try increasing it to give the ConnectionMultiplexer a chance to recover
这个结果显示客户端正在使用 192.168.1.100:30001,它使用了连接中的最后一个主机
【问题讨论】:
-
您能否在
ConnectionMultiplexer.Connect之后添加Thread.Sleep(5000)重新运行测试? -
您使用的是哪个版本的库?
-
这是我的包
我还在 ConnectionMultiplexer.Connect 之后添加了 Thread.Sleep(5000)但它只增加了 5 秒的延迟,然后在 db.StringSet("mykey", "abcdefg"); 中产生 'StackExchange.Redis.RedisServerException';