带有 JdbcIO 编写器的 ApacheBeam/DataFlow 运行器创建了太多连接
Posted
技术标签:
【中文标题】带有 JdbcIO 编写器的 ApacheBeam/DataFlow 运行器创建了太多连接【英文标题】:ApacheBeam/DataFlow runner with JdbcIO writer creates too many connections 【发布时间】:2019-09-23 08:28:56 【问题描述】:我正在使用 GCP 云 SQL、mysql 实例并使用 JdbcIo 将数据从 DataFlow 管道写入 MySQL。
似乎DataFlow生成的连接太多,达到了DB限制(4000),即使我在连接池中指定,最大大小:1000
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try
dataSource.setDriverClass("org.mysql.Driver");
catch (PropertyVetoException e)
throw new RuntimeException("Failed set mysql driver",e);
dataSource.setJdbcUrl("jdbc:mysql://google/live-data?cloudSqlInstance<INSTANCE_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&useSSL=false&user=<USER>&password=<PASSWORD>");
dataSource.setMaxPoolSize(1000);
dataSource.setInitialPoolSize(1000);
此外,在仪表板中,我可以看到比查询更多的连接:
我的 pom.xml
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
<dependency>
<groupId>com.google.cloud.sql</groupId>
<artifactId>mysql-socket-factory</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-io-jdbc</artifactId>
<version>$beam.version</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
【问题讨论】:
【参考方案1】:DataFlow 生成的连接太多,达到了 DB 限制(4000),即使我在连接池中指定,最大大小:1000
快速猜测是,由于 Dataflow 可以有多个运行器,每个运行器可能都有自己的连接池。这意味着每个池将有 1000 个单独的连接。这很可能比您实际使用的连接要多 - 请参阅 pool sizing 上的 HikariCP 的 wiki。
此外,在仪表板中,我可以看到比查询更多的连接:
由于您设置了setInitialPoolSize(1000)
,池不会根据需要延迟建立连接,而是在池初始化时创建 1000。从提供的示例中,您没有对连接寿命提供任何限制,因此这些连接可能会尽可能长时间地持续存在。
【讨论】:
是的,这似乎是因为连接池的许多实例。我将允许的连接数减少到 10 个,然后每个 DataFlow 工作人员创建自己的连接池,所有实例的总和仍然更低。 我还为每个工作人员创建了一个连接池实例,之前,我在 @SetUp 方法中为每个 ParDo 函数初始化了连接池。我将其更改为每个工作人员(单例)初始化一次以上是关于带有 JdbcIO 编写器的 ApacheBeam/DataFlow 运行器创建了太多连接的主要内容,如果未能解决你的问题,请参考以下文章