由于线上业务量特别大,线上clickhouse集群出现异常,执行一个特别长的sql出现如下报错:
code: 279, message: All connection tries failed. Log: \n\nCode: 32, e.displayText() = DB::Exception: Attempt to read after eof (version 21.3.9.83 (official build))\nCode: 32, e.displayText() = DB::Exception: Attempt to read after eof (version 21.3.9.83 (official build))\nCode: 32, e.displayText() = DB::Exception: Attempt to read after eof (version 21.3.9.83 (official build))\n\n: While executing Remote
涉及到的sql有时候能执行有时候又执行失败,不必现,从表面上看这个报错的意思:执行远程连接的时候,连接断开,然后我看了一下这一段报错之后的sql,发现sql被截断了。大概的情况是这样,然后我去查相关解决方案。
首先我通过clickhouse的issue找到相关的类似的问题,查到相关关键性词,查到一个比较近似的问题,地址如下:
https://github.com/ClickHouse/ClickHouse/issues/33553
里面有这样一段话:
Scince we use non-blocking reading from the socket in HedgedConnectionsFactory, most likely the error SOCKET_TIMEOUT occures is the first connection to the socket or while writing data to socket. You can try to tune timeouts connect_timeout_with_failover_ms/connect_timeout_with_failover_secure_ms for connection to the socket and send_timeout for writing data to socket.
通过这一段话,怀疑可能是连接远程服务器超时,造成sql都没有发送完,然后远程服务器就开始执行sql,造成异常。所以我们尝试先设置
connect_timeout_with_failover_ms
这个参数设置更大一点。
经过一两周观察,发现还是会存在报错,经过一系列排查,怀疑是clickhouse集群的网络架构存在问题。非HA模式下,zk和ck服务器部署在同一个节点,有insert query语句的时候,内部会存在大量的remote连接,短时间内会造成较大的网络压力。最后我们发现此问题之后,通过设置
connections_with_failover_max_tries
从默认的3改大,通过重试次数来降低执行sql的失败率。