【问题标题】:How to send multiple commands to Redis cluster using StackExchange.Redis library如何使用 StackExchange.Redis 库向 Redis 集群发送多个命令
【发布时间】: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';

标签: stackexchange.redis


【解决方案1】:

理论上,是的。所有的位都在那里。但是,authors 库目前不使用集群(因为它缺少 4.2 路线图中的以 DC 为中心的功能)。为了帮助测试,我们最近改进了对集群配置的访问;我将尝试通过它运行您的示例。但是,如果您可以在库和命令行之间运行 exact same test,这对我来说实际上会很有趣 - 在您的示例中,键实际上是不同的。我很想看看它对完全相同的键的含义。

【讨论】:

  • 感谢您的宝贵时间。我已将代码键重新运行到命令行键
  • 谢谢。至少,好消息是它正确处理了所有的分片和解析。坏消息显然是它无法与服务器对话。我不知道为什么我的头顶。但我们正在积极加强我们的集群测试和支持,如果存在固有问题,这可能会有所帮助。您还可以尝试将文本编写器传递给连接 API 以查看它的内容。
  • 谢谢马克,我又做了一个测试。请参阅上面的 12/4 更新。我希望这是有帮助的
  • “我认为问题是 StackExchange.Redis 客户端无法知道密钥属于哪个 hashlot,因为 redis 集群中的每个密钥都有对应的 hashlot 属于特定的主节点” - 不知道。即使您只将一台服务器放入配置中,它也知道。它只是找不到它。我需要找出原因。
【解决方案2】:

这可能是由于跨槽错误。

看一看:Redis Cross Slot error

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 2016-09-20
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多