首页 > 解决方案 > 是否可以通过 SSH 隧道使用 Apache Beam jdbcIO?

问题描述

我需要通过 ssh 隧道从 Mysql 服务器获取数据。我在 Google Dataflow 上使用 Apache Beam 2.19.0 Java JdbcIO 连接到数据库。但由于数据库位于专用网络内,我需要通过 ssh 服务器之间的一个通过 ssh 隧道访问数据库。

使用 apache beam jdbc IO 可以实现吗?

标签: jdbcgoogle-cloud-dataflowapache-beamssh-tunnelapache-beam-io

解决方案


此功能未内置在 Apache Beam 中,但是有几个选项。JdbcIO 使用标准的 Java JDBC 接口连接到您的数据库。使用您自己的包装器在连接之前设置 SSH 隧道来重载 Mysql JDBC 驱动程序并不难。我在 Google 上进行了快速搜索,发现了一个使用 SSHJ 将任意 JDBC 驱动程序与 SSH 隧道封装在一起的项目:jdbc-sshj(副本以 com.cekrlic:jdbc-sshj:0.1.0 的形式发布到 maven)。该项目看起来有些无人管理,但它会做你想做的事。将此添加到您的运行时依赖项,然后将您的配置更新为如下内容(此示例不安全):

pipeline.apply(JdbcIO.<KV<Integer, String>>read()
  .withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create(
    "com.cekrlic.jdbc.ssh.tunnel.SshJDriver",
    "jdbc:sshj://sshbastion?remote=database:3306&username=sshuser&password=sshpassword&verify_hosts=off;;;jdbc:mysql://localhost:3306/mydb")
    .username("username")
    .withPassword("password"))
  .withQuery("select id,name from Person")
  .withCoder(KvCoder.of(BigEndianIntegerCoder.of(), StringUtf8Coder.of()))
  .withRowMapper(new JdbcIO.RowMapper<KV<Integer, String>>() {
    public KV<Integer, String> mapRow(ResultSet resultSet) throws Exception {
      return KV.of(resultSet.getInt(1), resultSet.getString(2));
    }
  })
);

如果你使用 Dataflow,你可以设置一个 GCE VM 作为你的网关。在该 VM 上,使用 SSH 转发将数据库隧道传输到 VM 的外部接口 ( ssh -R \*:3306:database:3306 sshbastion),使端口在 VPC 中可用,然后在 VPC 上运行 Dataflow作业。如果您的数据库已经在 GCP 中运行,您可以使用此方法在与数据库相同的 VPC 上运行您的数据流作业并删除 SSH 步骤。


推荐阅读