为什么即使驱动程序不断抛出OperationTimedOutException,Cassandra节点仍被选为协调器?

ia2d9nvy  于 2022-11-05  发布在  Cassandra
关注(0)|答案(2)|浏览(150)

我设置了一个Cassandra集群,其中包含多个协调器节点。
有时,其中一个协调器节点变得不可用......我的代码使用重试策略来处理此问题,该策略移动到下一个节点,问题就解决了。
然而,即使驱动程序不断抛出OperationTimedOutException,似乎有问题的节点仍会接收流量...这是一个耗时的过程,因为此节点无用。
更多详情:Cassandra驱动程序-我使用的Cassandra驱动程序版本3.11.0(cassandra-driver-core-3.11.0.jar)负载平衡策略-我没有设置任何负载平衡策略-因此,使用默认值。重试策略-我实现了自己的重试策略-在读/写超时或重试原因不可用的情况下-我正在使用重试,同时将一致性级别降低到1。在请求错误的情况下-我正在尝试一个不同的主机。
如果驱动程序在向特定协调器节点发送查询时一直抛出OperationTimedOutException,那么是否有任何方法可以配置在一段时间内不调用此节点?

ryevplcw

ryevplcw1#

Cassandra客户端连接执行Cassandra协调器节点缓存。因此,它将继续向同一节点发送查询。使用客户端连接超时调整您的应用层套接字配置。

SocketOptions options = new SocketOptions();
options.setConnectTimeoutMillis(30000);
options.setReadTimeoutMillis(30000);
options.setTcpNoDelay(true);
9njqaruj

9njqaruj2#

你的问题中有一些误解,让我开始纠正一下。

误解#1

我设置了一个Cassandra集群,其中包含多个协调器节点。
Cassandra群集中的所有节点都是相同的。这是Cassandra最棒的属性之一。群集中的任何节点都可以被选为协调器。您不能在其他节点不是协调器的情况下将某个节点配置/指定/设置为协调器。

误解二

...如果协调器节点一直抛出OperationTimedOutException...
Cassandra节点不能抛出OperationTimedOutExceptionOperationTimedOutException是客户端异常,当驱动程序在配置的客户端超时期限内未从协调器获得响应时,驱动程序会抛出该异常。
它与读取或写入超时异常不同,读取或写入超时异常是在服务器端读取或写入请求超时时协调器将响应发送回驱动程序时引发的。

拾取节点

您没有指定您正在使用的驱动程序+版本。OperationTimedOutException is in Java driver v3.x,但在v4.x中没有(它是replaced with DriverTimeoutException,这更清楚地表明例外是客户端),因此为了我的回应,我将假设您正在使用Java驱动程序v3.11(v3系列中的最新版本)。
您也没有指定您配置了哪个load balancing policies(LBP)和哪个retry policies。如果您使用的是延迟感知LBP LatencyAwarePolicy,则可能的情况是,有问题的节点具有最低延迟,因此它被策略列为“首选节点”。
对于驱动程序来说,处理行为异常的节点是一件非常坚韧的事情,特别是在节点没有响应的情况下,因为如果节点根本没有响应,驱动程序将不知道实际发生了什么。(例如,由于GC暂停),它在一段时间内不会再次被选为协调器。
有时,来自有问题的节点的延迟“信号”需要一段时间才能出现,以使驱动程序有效地绕过该节点进行路由,这是因为驱动程序使用的算法在一分钟或两分钟的时段内对所报告的延迟进行平均,驱动器只能将平均/缩放基于节点报告其等待时间的最后时间。
由于这个原因,LatencyAwarePolicy在Java驱动程序v4中被删除,而the new DefaultLoadBalancingPolicy对于慢速副本具有更好的检测算法。
使用tryNextHost()的解决方案有点笨拙,因为您必须有效地等待重试策略生效。您真正需要关注的是节点变得没有响应这一事实。如果群集过载,您应该考虑通过添加更多节点来增加容量。
从长远来看,试图为基础设施容量问题提供软件解决方案永远不会成功。干杯!

相关问题