Cassandra Python驱动自定义重试策略无法捕获ReadFailure异常
Cassandra Python驱动自定义重试策略无法捕获ReadFailure异常
我来帮你排查这个问题——你遇到的ReadFailure没有触发自定义重试策略,核心原因是在你使用的cassandra-driver 3.25.0版本中,ReadFailure异常并不由on_request_error方法处理,它需要单独实现对应的重试回调方法。
问题根源
Cassandra Python驱动把不同类型的异常拆分到了不同的重试钩子中:
on_read_timeout处理读取超时类异常on_read_failure专门处理ReadFailure这类副本读取失败的异常on_request_error则负责处理一些通用的请求错误(比如连接问题、协议错误等)
你的自定义策略里只覆盖了前几个方法,但漏掉了on_read_failure,所以遇到ReadFailure时驱动找不到对应的重试逻辑,直接抛出了异常。
解决方案
在你的KeyspacesRetryPolicy类中添加on_read_failure方法,逻辑和其他重试方法保持一致即可:
from cassandra.policies import RetryPolicy import time # 注意补充导入time,原代码中使用了time.sleep但未声明 class KeyspacesRetryPolicy(RetryPolicy): def __init__(self, RETRY_MAX_ATTEMPTS=5, base_delay=0.5, max_delay=10): # retry_num starts at 0 self.max_retry_num = RETRY_MAX_ATTEMPTS-1 self.base_delay = base_delay self.max_delay = max_delay def __backoff(self, retry_num): # exponential backoff delay delay = min(self.base_delay * (2 ** (retry_num + 1)), self.max_delay) print(f"Backing off for {delay} seconds (retry number {retry_num})") time.sleep(delay) def on_read_timeout(self, query, consistency, required_responses, received_responses, data_retrieved, retry_num): if retry_num <= self.max_retry_num: self.__backoff(retry_num) print("retry on_read_timeout") return self.RETRY, consistency else: return self.RETHROW, None def on_write_timeout(self, query, consistency, write_type, required_responses, received_responses, retry_num): if retry_num <= self.max_retry_num: self.__backoff(retry_num) print("retry on_write_timeout") return self.RETRY, consistency else: return self.RETHROW, None def on_unavailable(self, query, consistency, required_replicas, alive_replicas, retry_num): if retry_num <= self.max_retry_num: self.__backoff(retry_num) print("retry on_unavailable") return self.RETRY, consistency else: return self.RETHROW, None def on_request_error(self, query, consistency, error, retry_num): if retry_num <= self.max_retry_num: self.__backoff(retry_num) print("retry on_request_error") return self.RETRY, consistency else: return self.RETHROW, None # 新增方法处理ReadFailure异常 def on_read_failure(self, query, consistency, required_responses, received_responses, failures, retry_num): if retry_num <= self.max_retry_num: self.__backoff(retry_num) print("retry on_read_failure") return self.RETRY, consistency else: return self.RETHROW, None
额外提示
如果你之后遇到类似的WriteFailure异常,也需要添加对应的on_write_failure方法,逻辑和上面的on_read_failure类似。
修改后,当集群返回ReadFailure时,驱动就会调用你新增的on_read_failure方法,执行你定义的退避和重试逻辑了。
备注:内容来源于stack exchange,提问作者sechstein
相关产品推荐
相关产品推荐

