java dataset join,在Flink DataSet 上应用多个 join的java分区策略

我使用的是Flink1.4.0。

假设我有一个POJO,如下所示:

public class Rating {

public String name;

public String labelA;

public String labelB;

public String labelC;

...

}

以及 join函数:

public class SetLabelA implements JoinFunction, Tuple2, Tuple2> {

@Override

public Tuple2<String, Rating> join(Tuple2<String, Rating> rating, Tuple2<String, String> labelA) {

rating.f1.setLabelA(labelA)

return rating;

}

}

假设我想应用一个JOIN操作来设置DataSet>中每个字段的值,我可以这样做:

DataSet> ratings = // [...]

DataSet> aLabels = // [...]

DataSet> bLabels = // [...]

DataSet> cLabels = // [...]

...

DataSet>

newRatings =

ratings.leftOuterJoin(aLabels, JoinOperatorBase.JoinHint.REPARTITION_SORT_MERGE)

// key of the first input

.where("f0")

// key of the second input

.equalTo("f0")

// applying the JoinFunction on joining pairs

.with(new SetLabelA());

不幸的是,这是必要的,因为评级和所有xlabel都是非常大的 DataSet ,我被迫查看每个xlabel以找到我需要的字段值,但同时并非所有的评级 key都存在于每个xlabel中。

这实际上意味着我必须为每个xlabel执行一个leftOuterJoin,为此我还需要创建相应的JoinFunction实现,该实现使用来自评级POJO的正确setter。

有没有更有效的方法来解决这个问题,任何人都能想到?

至于分区策略,我已经确保将 DataSet >的评级排序为:

DataSet> sorted_ratings = ratings.sortPartition(0, Order.ASCENDING).setParallelism(1);

通过将parallelism设置为1,我可以确定整个 DataSet 将被排序。然后使用.partitionByRange:

DataSet> partitioned_ratings = sorted_ratings.partitionByRange(0).setParallelism(N);

我的核数是。另一个附带的问题是,设置为1的第一个.setparallellelism是否限制了 pipeline 其余部分的执行方式,即follow.setParallelism(N)是否可以更改 DataSet 的处理方式?

最后,我做了所有这些,这样当分区的评等与xlabels DataSet join时,JOIN操作将使用JoinOperatorBase.JoinHint.REPARTITION_SORT_MERGE. root据Flink针对v.1.4.0的文档:

repartition[排序] coalesce :系统对每个输入进行分区(无序处理)(除非输入已分区)并对每个输入进行排序(除非已排序)。输入通过已排序输入的流式 coalesce 进行 join。如果一个或两个输入都已排序,则此策略是好的。

所以在我的例子中,评级是排序的(我认为),而每个xlabels DataSet 没有排序,因此这是最有效的策略。这个有什么问题吗?有其他方法吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用FlinkDataSet API和JDBC连接Oracle数据库来实现左连接查询两个表。具体步骤如下: 1. 在Flink中使用JDBC连接Oracle数据库。可以使用Flink提供的JDBCInputFormat读取表数据,示例代码如下: ```java String driverName = "oracle.jdbc.driver.OracleDriver"; String dbURL = "jdbc:oracle:thin:@localhost:1521:ORCL"; String username = "username"; String password = "password"; JDBCInputFormat inputFormat = JDBCInputFormat.buildJDBCInputFormat() .setDrivername(driverName) .setDBUrl(dbURL) .setUsername(username) .setPassword(password) .setQuery("SELECT * FROM table1") .setRowTypeInfo(rowTypeInfo) .finish(); ``` 2. 使用DataSet API进行左连接查询。可以使用leftOuterJoin方法将两个DataSet进行左连接,示例代码如下: ```java DataSet<Tuple2<String, String>> table1 = ... DataSet<Tuple2<String, String>> table2 = ... DataSet<Tuple2<String, String>> result = table1.leftOuterJoin(table2) .where(0) // 指定table1的join字段 .equalTo(1) // 指定table2的join字段 .with(new JoinFunction<Tuple2<String, String>, Tuple2<String, String>, Tuple2<String, String>>() { @Override public Tuple2<String, String> join(Tuple2<String, String> first, Tuple2<String, String> second) throws Exception { if (second == null) { // 表示table2中没有与table1匹配的记录 return new Tuple2<>(first.f0, ""); } else { return new Tuple2<>(first.f0, second.f1); } } }); ``` 在上面的代码中,我们使用了JoinFunction自定义了一个左连接函数,如果table2中没有与table1匹配的记录,我们将第二个字段设为空字符串。 3. 将查询结果输出到控制台或其他存储介质中。可以使用print或write方法输出结果,示例代码如下: ```java result.print(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值