我想在Google Compute Engine上读取MariaDB的数据并通过DataFlow将数据写入BigQuery,但是当我在DataFlowRunner上运行DataFlow程序时,我总是得到如下例外。
java.lang.RuntimeException:org.apache.beam.sdk.util.UserCodeException:java.sql.SQLException:无法创建PoolableConnectionFactory(无法连接到地址=(host = xxx.xxx.xxx.xxx)(端口) = 3306)(type = master):连接超时)
可以给我一些理想,谢谢。
答案 0 :(得分:1)
要限制它以便只有Dataflow作业可以访问它,您可以利用Dataflow的线束VM使用dataflow
标记创建的事实。否则,您可以在特定网络/子网上分配GCE实例和DF工作程序。
例如,使用网络标记(例如mariadb
)创建GCE实例,以便将其用作将防火墙规则应用于和/或选择特定VPC网络/子网的目标。安装MariaDB(另一种选择是通过Cloud Launcher使用初始化脚本或预安装的解决方案)。
对于防火墙规则,您需要在端口tcp:3306
上访问数据库。对于GCE实例(目标标记mariadb
),您需要允许来自源标记dataflow
的入口流量或来自上述端口上的子网内的流量。请注意,对于后一种选择,您还需要允许子网内DF工作人员之间的内部通信。
现在,在数据流方面,将JdbcIO
和mariadb
连接器依赖项添加到pom.xml
文件中:
<!-- https://mvnrepository.com/artifact/org.apache.beam/beam-sdks-java-io-jdbc -->
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-io-jdbc</artifactId>
<version>2.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>1.1.7</version>
</dependency>
要连接的示例数据流代码段(如果使用子网方法,则使用JDBC连接字符串中的内部IP):
public class MariaDB {
public static void main(String[] args) {
PipelineOptions options = PipelineOptionsFactory.fromArgs(args).withValidation().as(PipelineOptions.class);
Pipeline p = Pipeline.create(options);
PCollection<String> account = p.apply(JdbcIO.<String>read()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create("org.mariadb.jdbc.Driver", "jdbc:mariadb://INTERNAL_IP:3306/database").withUsername("root").withPassword("pwd"))
.withQuery("SELECT … FROM table")
.withCoder(SerializableCoder.of(String.class))
.withRowMapper(new JdbcIO.RowMapper<String>() {
public String mapRow(ResultSet rs) throws Exception {
...
}}
));
p.run();
}
}
如果需要,启动指定子网和匹配区域的作业:
mvn compile exec:java \
-Dexec.mainClass=com.example.MariaDB \
-Dexec.args="--project=PROJECT_ID \
--stagingLocation=gs://BUCKET_NAME/mariadb/staging/ \
--output=gs://BUCKET_NAME/mariadb/output \
--network="dataflow-network" \
--subnetwork="regions/europe-west1/subnetworks/subnet-europe-west" \
--zone="europe-west1" \
--runner=DataflowRunner"