您的问题中有一些误解,所以让我从纠正它们开始。
误解#1
<1234565>
我建立了一个带有多个协调节点的 Cassandra 集群。
Cassandra 集群中的所有节点都是相同的。这是让 Cassandra 很棒的属性之一。集群中的任何节点都可以被选为协调器。您不能将节点配置/提名/设置为协调者,而其他节点则不是。
误解#2
<1234565>
... 如果协调节点不断抛出 OperationTimedOutException ...
Cassandra 节点无法抛出 OperationTimedOutException。 OperationTimedOutException 是一个客户端异常,当它在配置的客户端超时期限内没有从协调器获得响应时,它会被驱动程序抛出。
这是与读取或写入超时异常不同的异常,后者是在服务器端读取或写入请求超时时协调器向驱动程序发送回响应时引发的。
挑选节点
您没有指定您使用的是哪个驱动程序 + 版本。 OperationTimedOutException is in Java driver v3.x 但不在 v4.x 中(它是 replaced with DriverTimeoutException,这更清楚地表明异常是客户端的)所以为了我的回复,我假设您使用的是 Java 驱动程序 v3。 11(v3 系列的最新版本)。
您也没有指定您配置了哪个load balancing policies (LBP) 以及哪个retry policies。如果您使用the latency-aware LBP LatencyAwarePolicy,,可能的情况是有问题的节点具有最低延迟,因此它被策略列为“首选节点”。
处理行为不端的节点对于驱动程序来说是一件非常困难的事情,尤其是在节点没有响应的情况下,因为如果节点根本没有响应,驱动程序将不知道真正发生了什么。驱动程序在将节点标记为“关闭”时不能过于激进,因为如果节点只是暂时不可用(例如,由于 GC 暂停),它在一段时间内不会再次被选为协调器。
有时,来自有问题节点的延迟“信号”需要一段时间才能让驱动程序有效地绕过它,因为驱动程序使用的算法在一两分钟内平均报告的延迟,按比例缩放旧延迟的权重低于新延迟。在节点无响应的情况下,驱动程序只能基于节点上次报告其延迟的时间来计算平均值/缩放。
出于这个原因,LatencyAwarePolicy 在 Java 驱动程序 v4 中被删除,而不是 the new DefaultLoadBalancingPolicy,后者对慢速副本有更好的检测算法。
您使用tryNextHost() 的解决方法有点笨拙,因为您必须有效地等待重试策略启动。您真正需要关注的是您的节点变得无响应的事实。如果您的集群过载,您应该考虑通过添加更多节点来增加容量。
从长远来看,试图为基础设施容量问题提供软件解决方案永远不会成功。干杯!