Spring JDBC连接ClickHouse集群遇超时及地址占用问题求助
问题排查请求
我们通过JDBC连接器连接一个包含4个节点、3个ClickHouse-keepers的ClickHouse集群。用100/200/300线程做性能测试时,约5分钟后出现以下异常:
- 生产环境:连接读取超时错误
- 本地环境:Address already in use错误(无资源占用异常)
集群表结构与数据流程
目前使用三张表:
- main_table
- replication_table:2分片,每分片2副本
- buffer_table:用于缓解
too many parts错误
数据写入流程:先插入buffer_table,刷新至replication_table,再按分片键分发到4个节点副本。
JDBC连接配置代码
@Value("${clickhouse.datasource.url}") private String url; @Value("${clickhouse.datasource.username}") private String username; @Value("${clickhouse.datasource.password}") private String password; @Value("${clickhouse.datasource.driver-class-name}") private String driverClass; @Value("${clickhouse.datasource.connection-timeout}") private String connectionTimeout; @Value("${clickhouse.datasource.socket-timeout}") private String socketTimeout; @Value("${clickhouse.datasource.ssl}") private String ssl; @Value("${clickhouse.datasource.load-balancing-policy}") private String loadBalancingPolicy; @Bean public DataSource dataSource() throws SQLException { Properties properties = new Properties(); properties.setProperty("user", username.trim()); properties.setProperty("password", password.trim()); properties.setProperty("connection_timeout", connectionTimeout.trim()); properties.setProperty("socket_timeout", socketTimeout.trim()); properties.setProperty("ssl", ssl.trim()); properties.setProperty("load_balancing_policy", loadBalancingPolicy.trim()); ClickHouseDataSource dataSource = new ClickHouseDataSource(url.trim(), properties); return dataSource; }
配置属性
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.minimum-idle=200 spring.datasource.hikari.maximum-pool-size=200 spring.datasource.hikari.idle-timeout=600000 spring.datasource.hikari.max-lifetime=1800000 spring.datasource.hikari.auto-commit=true clickhouse.datasource.url=jdbc:clickhouse://server1:8123,server2:8123,server3:8123,server4:8123/dap_dev clickhouse.datasource.driver-class-name=com.clickhouse.jdbc.ClickHouseDriver clickhouse.datasource.connection-timeout=30000 clickhouse.datasource.socket-timeout=300000 clickhouse.datasource.ssl=false clickhouse.datasource.load-balancing-policy=roundRobin
问题排查与优化建议
1. 本地Address already in use问题
该错误是客户端短时间内创建大量连接,导致本地端口耗尽,结合配置分析:
- 测试线程数(300)超过Hikari连接池最大容量(200),会触发频繁创建新连接而非复用池内连接
auto-commit=true会让连接在每次操作后立即归还,但高并发下仍可能出现端口快速耗尽
优化方案:
- 调整测试线程数不超过连接池最大数,或把
maximum-pool-size调至300 - 开启TCP端口复用:Linux系统执行
sysctl -w net.ipv4.tcp_tw_reuse=1,或添加JVM启动参数-Djava.net.preferIPv4Stack=true
2. 生产环境连接读取超时问题
配置冲突
配置中同时存在Hikari和ClickHouse JDBC的连接超时参数,Hikari的connection-timeout优先级更高,可能导致ClickHouse JDBC的connection_timeout未生效,需统一配置逻辑。
集群负载与写入压力
roundRobin负载均衡策略会平均分配请求,但replication_table是2分片2副本结构,高并发下部分节点可能因数据分发压力过载,导致响应变慢触发socket超时- buffer_table的刷新策略可能不合理,短时间大量数据刷入replication_table会加剧集群压力
优化方案:
- 检查ClickHouse节点的CPU、内存、磁盘IO状态,定位过载节点
- 适当调大
socket_timeout(当前5分钟),同时优化buffer_table的flush_interval/max_rows_in_buffer参数,避免批量刷写压力 - 查看ClickHouse服务器端
keep_alive_timeout配置,确保Hikari的max-lifetime(30分钟)小于该值,避免无效连接留在池中
JDBC驱动问题
旧版本ClickHouse JDBC驱动可能存在连接泄漏或负载均衡bug,建议升级到最新稳定版本(如0.4.x系列)
内容的提问来源于stack exchange,提问作者Shivam
相关产品推荐
相关产品推荐

