使用 DataStax C# 驱动程序时故障转移不适用于 Cassandra

Failover not working with Cassandra when using DataStax C# Driver

我在 Azure 中设置了一个双节点,我试图在与 C# 驱动程序连接时进行故障转移。在使用 cqlsh 和 OpsCenter 时,我的节点似乎通信正常。

var contact = "publicipforfirstnode";
_cluster = Cassandra.Cluster.Builder().AddContactPoint(contact).Build();
_session = _cluster.Connect("demo");

我最初连接的是第一个节点的 public IP。这很好用。但是在配置中,我使用虚拟网络分配的内部网络 IP,例如 10.1.0.4、10.1.0.5 等。我将它们设置为每个节点的 listen_address 和 broadcast_rpc_address。即使我在配置中使用内部 IP,我也可以很好地连接 public IP。我有一个特殊的防火墙规则,允许我从 public IP 上的某台机器进行连接。然而,为了避免内部节点通信的防火墙规则,我将节点放在同一个虚拟网络上,不需要额外的工作。

在我的第一个节点出现故障之前,这看起来很棒。 然后它使用内部 IP 尝试第二个节点。

I get an error: All Hosts tried for query (Public IP of First Node), (Internal IP of Second Node)

但是由于我是从一台不在虚拟网络中的机器连接的,所以它无法访问这个内部 IP。我的应用程序不会在内部网络中,所以这似乎是个问题。

不使用内部 ips 迫使我设置身份验证 and/or 我宁愿不必做的特殊防火墙规则。有什么方法可以强制 c# 驱动程序使用 public ips 并允许节点在内部 ips 上进行通信?除非您有多个区域,否则使用内部 ips 似乎是推荐的最佳做法。

在 cassandra.yaml 文件中配置为 broadcast_rpc_address 的 IP 被驱动程序用来连接它们。

在您的情况下,如果您想使用 public IP 地址连接驱动程序,您应该将 broadcast_rpc_address 设置为 public IP 地址。

您可以在驱动程序中启用跟踪以查看后台发生的情况:

// Specify the minimum trace level you want to see
Cassandra.Diagnostics.CassandraTraceSwitch.Level = TraceLevel.Info;
// Add a standard .NET trace listener
Trace.Listeners.Add(new ConsoleTraceListener());

From the docs:

  • listen_address:Cassandra 绑定的 IP 地址或主机名,用于连接到其他 Cassandra 节点。
  • broadcast_rpc_address:RPC 地址广播给驱动程序和其他 Cassandra 节点。这不能设置为 0.0.0.0。如果为空,则设置为 rpc_address 或 rpc_interface 的值。如果rpc_address或rpc_interface设置为0.0.0.0,则必须设置此属性。

我认为当您的 Cassandra 集群位于 NAT 设备(如防火墙或网关)后面时,了解 broadcast_addressbroadcast_rpc_address 的含义很重要。

broadcast_address是其他节点连接的地址。默认情况下,这与 listen_address 相同(通常您需要这样,因为节点位于同一网络中)。

如果您的集群跨两个网络并且发生 NAT,您必须将其设置为两个网络上的节点都可以访问的值(如 public IP,如果您进行多区域部署在 AWS 中)。这意味着网络内以及跨网络的流量将通过 NAT 设备,因为无法访问内部 IP。

broadcast_rpc_address是一个节点"advertizes"关于另一个节点的地址。

例如,节点A有broadcast_address=10.0.0.100和broadcast_rpc_address=52.2.3.100,节点B有broadcast_address=10.0.0.101和broadcast_rpc_address=52.2 .3.101

然后发生的是节点 A 将连接到 10.0.0.101 上的节点 B,但是如果客户端驱动程序询问 A "hey, what other nodes are in your cluster?",那么它将为 B 响应 52.2.3.101。

这种设计(我相信是在 Cassandra 2.0.10 中引入的)使网络外的客户端可以连接到集群中的任何节点(而不仅仅是种子节点)。

但是一个限制是你不能在网络内外都有客户端,否则你需要确保 public IP 在网络内外都可以访问(比如更改防火墙设置) .

我希望这能澄清一些事情。

加法

如果您热衷于此,您可以使用以下 cqlsh 命令查找一个节点对其他节点的了解:

select * from system.peers

peer列是节点的broadcast_addressrpc_address列是节点的broadcast_rpc_address