如何使用GetEndPoints()获取唯一端点并解决集群主节点重复问题
解决Redis GetEndPoints()返回重复端点及获取唯一主节点列表的问题
你的问题核心是生产环境Redis集群下,GetEndPoints()返回了重复的端点,导致筛选出的主节点重复。这是因为集群环境中,GetEndPoints()可能会返回同一节点的不同表示形式(比如DNS解析后的多个IP、集群内部通信端点),或者连接字符串中的端点会触发集群节点发现,返回所有集群节点但包含重复项。
方案一:对端点进行归一化去重
我们可以先给每个EndPoint生成唯一标识,再基于这个标识去重,之后再筛选主节点:
首先添加一个辅助方法,用来生成端点的唯一键:
private string GetEndPointUniqueKey(EndPoint endPoint) { return endPoint switch { DnsEndPoint dnsEp => $"{dnsEp.Host}:{dnsEp.Port}", IPEndPoint ipEp => $"{ipEp.Address}:{ipEp.Port}", _ => endPoint.ToString() }; }
然后修改你的Masters实现:
private IEnumerable<IServer> Masters => connection .GetEndPoints() // 按唯一键分组,每组只保留第一个端点 .GroupBy(GetEndPointUniqueKey) .Select(g => g.First()) .Select(e => connection.GetServer(e)) .Where(s => !s.IsSlave) // 最后再对Server实例去重,确保同一主节点只出现一次 .GroupBy(s => $"{s.EndPoint}:{s.ServerType}") .Select(g => g.First());
方案二:直接通过集群节点API获取主节点(更推荐)
对于Redis集群,直接调用集群节点信息的API会更可靠,能直接获取所有节点的角色信息,避免端点重复的问题:
private IEnumerable<IServer> Masters { get { // 先获取集群中的任意一个节点 var firstEndPoint = connection.GetEndPoints().FirstOrDefault(); if (firstEndPoint == null) return Enumerable.Empty<IServer>(); var anyServer = connection.GetServer(firstEndPoint); // 获取所有集群节点的详细信息 var clusterNodes = anyServer.ClusterNodes(); // 筛选主节点并去重 return clusterNodes .Where(node => node.Role == ClusterNodeRole.Master) .Select(node => connection.GetServer(node.EndPoint)) .Distinct(); } }
这个方法直接从集群的节点元数据中获取主节点,不会出现重复的情况,是集群环境下更合适的做法。
内容的提问来源于stack exchange,提问作者Mike Christensen
相关产品推荐
相关产品推荐

