【发布时间】:2018-09-17 01:37:09
【问题描述】:
我需要获取我当前连接的所有主机的列表。这应该很容易:
private IEnumerable<IServer> Masters => connection
.GetEndPoints()
.Select(e => connection.GetServer(e))
.Where(s => !s.IsSlave);
这可以在本地工作,但在我们连接到集群的生产环境中,它会返回重复的主节点并搞砸我的代码。原因是我们的连接字符串是“RedisServer1:7000,RedisServer2:7000”,所以我们得到一个 EndPoint,它是一个带有 RedisServer1 的 DnsEndPoint,一个 EndPoint 是一个 IPEndPoint,它是 10.0.0.15(或某个 IP),因为它是使用集群中的所有内容。这两个端点实际上指向同一个框。所以,我想我可以这样做:
private IEnumerable<IServer> Masters => connection
.GetEndPoints()
.Where(e => e is IPEndPoint)
.Select(e => connection.GetServer(e))
.Where(s => !s.IsSlave);
这修复了生产,所以我不再有骗子。但是,我们的功能测试会中断,因为它们使用的是非集群的单个 Redis 实例,它只是“localhost”的 DnsEndpoint。
我可能会使用某种“分组依据”并过滤掉骗子,但 DnsEndpoint 有主机名,而 IPEndPoint 有 IP 地址,所以没有真的方法来判断两个端点是否是相同的。我一直在寻找某种全球唯一的“Redis 实例 ID”或其他东西,但似乎没有这样的东西。也许我能以某种方式判断我是否已连接到集群并据此更改我的逻辑?
解决此问题的最佳方法是什么?
更新:为了澄清我的意思,如果我有一个在 Localhost 上运行的 6 节点集群,GetEndPoints() 将返回 7 件事:
(数组元素0和4是同一个东西)
【问题讨论】:
-
也许只是通过
Dns.GetHostEntry将DnsEndPoints 解析为IP 地址,这样您就只有一个IP 列表?然后您可以过滤掉重复项。 -
@Evk - 是的,我认为这是可行的!它会增加一些网络开销,但这是一个仅在站点启动时运行的功能..
-
也许它甚至不会产生任何开销,因为 redis api 应该已经将主机解析为 ips,所以所有这些主机可能都在本地 dns 缓存中。
标签: c# .net redis stackexchange.redis