You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To apply ClickHouse server settings only to read requests (not writes), use `spark.clickhouse.read.settings` set via `spark.conf.set(...)` instead of catalog-level `option.clickhouse_setting_*` entries. Catalog properties apply to all operations for the lifetime of the catalog and cannot be scoped to reads only.
1755
1833
:::
1756
1834
1835
+
## Timeout configuration {#timeout-configuration}
1836
+
1837
+
Timeouts in the Spark connector operate at three independent layers. Misdiagnosing which layer is responsible for a timeout is the most common source of confusion.
The connector enforces its own timeouts that are independent of any Spark or ClickHouse setting:
1842
+
1843
+
| Behavior | Value | Configurable |
1844
+
|---|---|---|
1845
+
| Query timeout |**60 seconds**| No — hard-coded in the connector |
1846
+
| Insert timeout |**None**| No — inserts run until the network drops the connection |
1847
+
1848
+
The 60-second query cap is enforced by the connector regardless of `max_execution_time` or any other server setting. If a read query takes longer than 60 seconds end-to-end, the connector will abort it. There is no `spark.clickhouse.*` setting to override this value.
1849
+
1850
+
Inserts have no connector-level timeout. This means a stalled or very slow insert will hang until a network device terminates the connection — which can produce a **"Broken pipe"** error (see [Connection resets on AWS PrivateLink or NLB](#troubleshooting-connection-resets) below).
These are passed through to the underlying ClickHouse Java client using the `option.<key>` prefix on catalog properties. They control the TCP/HTTP connection lifecycle.
1855
+
1856
+
| Catalog property | Default | Unit | What it controls |
1857
+
|---|---|---|---|
1858
+
|`option.socket_timeout`|`0` (unlimited) | ms | Deadline for each TCP read/write operation. `0` means no deadline — the call blocks indefinitely if the server stops responding. |
1859
+
|`option.connection_timeout`| not set | ms | Time allowed to establish a new TCP connection to ClickHouse. |
1860
+
|`option.connection_ttl`|`-1` (unlimited) | ms | Maximum lifetime of a pooled connection. After this time, the connection is retired and not reused. **Set this below the idle timeout of any network appliance between Spark and ClickHouse** (e.g., `300000` for AWS NLB). |
1861
+
|`option.http_keep_alive_timeout`| server default | ms | Overrides the HTTP keep-alive timeout. Set to `0` to disable keep-alive on network paths with aggressive idle-connection cutoffs. |
These are ClickHouse query settings sent with each request. They instruct the ClickHouse server to enforce a limit, independent of what the connector or TCP layer does.
1866
+
1867
+
| Catalog property | Default | Unit | What it controls |
1868
+
|---|---|---|---|
1869
+
|`option.clickhouse_setting_max_execution_time`|`0` (unlimited) | seconds | Server-side hard cap on query execution time. Useful for preventing runaway reads from consuming server resources, but **does not override the connector's 60-second query timeout**. |
1870
+
|`option.clickhouse_setting_session_timeout`|`60`| seconds | HTTP session lifetime on the server. |
1871
+
1872
+
### Common timeout scenarios {#timeout-scenarios}
1873
+
1874
+
**Long-running reads (>60 seconds)**
1875
+
1876
+
The connector's hard-coded 60-second query timeout will abort reads that take longer, even if the server could complete them. There is no configuration knob to extend or disable this cap. The only workaround is to reduce the amount of data returned by a single query so each read completes within 60 seconds:
1877
+
1878
+
- Add `WHERE` predicates to filter rows before they reach Spark.
1879
+
- Use partition pruning so the connector issues one query per partition rather than one large scan.
1880
+
1881
+
**Insert "Broken pipe" or "Connection reset" errors**
1882
+
1883
+
Typically caused by a network appliance (AWS NLB, PrivateLink, corporate proxy) silently dropping idle connections. The connector's connection pool holds connections open between operations; if the appliance's idle timeout (350 seconds for AWS NLB) expires, the connection is dropped at the network level without notification. The connector then tries to reuse a dead connection and gets a broken pipe.
Setting `connection_ttl` below the appliance's idle timeout forces the connector to retire connections proactively. See [Connection resets on AWS PrivateLink or NLB](#troubleshooting-connection-resets) for full details.
### Connection resets on AWS PrivateLink or NLB {#troubleshooting-connection-resets}
1972
+
1973
+
**Symptom**: Reads or writes intermittently fail with `Broken pipe`, `Connection reset by peer`, or `java.io.IOException: Connection closed` — particularly on longer-running jobs or after a period of inactivity.
1974
+
1975
+
**Cause**: AWS Network Load Balancers (NLB) and PrivateLink silently drop TCP connections that have been idle for **350 seconds**. The connector's connection pool keeps HTTP connections alive between operations. When the NLB drops a pooled connection, neither the connector nor ClickHouse is notified. The next operation that picks up that connection fails immediately.
1976
+
1977
+
Inserts are especially vulnerable: there is no connector-level insert timeout, so a slow or large insert can stall mid-flight when the underlying connection is cut.
1978
+
1979
+
**Fix**: Retire pooled connections before the NLB does by setting `connection_ttl` below 350 seconds. Also set `socket_timeout` to bound individual operations and disable HTTP keep-alive to prevent stale connections from persisting in the pool:
For very large inserts that are genuinely expected to take several minutes, switch to async inserts so the server acknowledges receipt quickly and the connector is not waiting on a long-lived open connection:
### KEEPER_EXCEPTION during writes {#troubleshooting-keeper-exception}
1835
1997
1836
1998
**Symptom**: Writes fail with `Coordination::Exception: Can't get data for node ... node doesn't exist (KEEPER_EXCEPTION)`. Retries may produce duplicate data.
0 commit comments