(九)Flink Datastream API 编程指南 UDF(用户自定义函数)

大多数操作需要一个用户定义的函数。本节列出了指定它们的不同方法。我们还介绍了Accumulators,它可以用来深入了解你的Flink应用程序。

函数实现方式

实现一个接口

最基本的实现就是如下,实现MapFunction接口下map方法。

class MyMapFunction implements MapFunction<String, Integer> {
  public Integer map(String value) { return Integer.parseInt(value); }
}
data.map(new MyMapFunction());

匿名类

你可以将函数作为匿名类传递:

data.map(new MapFunction<String, Integer> () {
  public Integer map(String value) { return Integer.parseInt(value); }
});

Java 8 Lambdas

Flink还在Java API中支持Java 8 Lambdas。

data.filter(s -> s.startsWith("http://"));
data.reduce((i1,i2) -> i1 + i2);

Rich functions(富函数)

所有需要用户定义函数的转换都可以使用富函数作为参数。
例如,implements MapFunction 可以写成extends RichMapFunction

class MyMapFunction implements MapFunction<String, Integer> {
  public Integer map(String value) { return Integer.parseInt(value); }
}

用富函数表示

class MyMapFunction extends RichMapFunction<String, Integer> {
  public Integer map(String value) { return Integer.parseInt(value); }
}

## 并像往常一样将该函数传递给映射转换
data.map(new MyMapFunction());

富函数也可以定义为匿名类:

data.map (new RichMapFunction<String, Integer>() {
  public Integer map(String value) { return Integer.parseInt(value); }
});

富函数除了提供用户定义的函数(map、reduce等)外,还提供了四种方法:open、close、getRuntimeContext和setRuntimeContext。这对于参数化函数(请参阅向函数传递参数)、创建和终结局部状态、访问广播变量(请参阅广播变量)、访问运行时信息(如累加器和计数器(请参阅累加器和计数器)以及关于迭代的信息(请参阅迭代)都很有用。

累加器和计数器

累加器是带有添加操作和最终累积结果的简单构造,在作业结束后可用。

最简单的累加器是一个计数器:您可以使用累加器增加它。添加(V值)的方法。在作业结束时,Flink将汇总(合并)所有部分结果,并将结果发送给客户端。累加器在调试期间很有用,或者如果你想快速找到更多关于数据的信息。

Flink目前有以下内置的累加器。它们都实现了Accumulator接口:

  • IntCounter, LongCounter和DoubleCounter:下面是一个使用计数器的例子。
  • Histogram:一个histogram实现的离散数量的箱子。在内部,它只是一个从Integer到Integer的映射。你可以使用它来计算值的分布,例如单词计数程序的每行单词分布。

如何使用累加器:

首先,您必须在用户定义的转换函数中创建一个累加器对象(这里是一个计数器),以便在需要使用它的地方使用它。

private IntCounter numLines = new IntCounter();

其次,必须注册累加器对象,通常是在rich函数的open()方法中。这里还定义了名称。

getRuntimeContext().addAccumulator("num-lines", this.numLines);

现在可以在算子函数的任何地方使用累加器,包括open()和close()方法。

this.numLines.add(1);

整个结果将存储在执行环境的execute()方法返回的JobExecutionResult对象中(目前只有在执行等待作业完成时才有效)。

myJobExecutionResult.getAccumulatorResult("num-lines");

所有累加器对每个作业共享一个名称空间。因此,您可以在您工作的不同算子函数中使用相同的累加器。Flink将在内部合并所有具有相同名称的累加器。

关于累加器和迭代的说明:目前累加器的结果只有在整个作业结束后才可用。我们还计划让上一个迭代的结果在下一个迭代中可用。您可以使用aggregator来计算每个迭代的统计信息,并根据这些统计信息来终止迭代。

自定义累加器

要实现自己的累加器,只需编写accumulator接口的实现。如果您认为您的自定义累加器应该与Flink一起,请随意创建一个拉请求。

您可以选择实现Accumulator或SimpleAccumulator。

Accumulator<V,R>是最灵活的:它为要添加的值定义了一个类型V,并为最终结果定义了一个结果类型R。例如,对于histogram,V是一个数字,R是一个histogram。SimpleAccumulator用于两种类型相同的情况,例如计数器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

京河小蚁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值