flink 并行计数器实现
1、flink实现计数器的灵感来源于Hadoop的MapReduce计算框架里的理念。
flink通过实现Accumulator接口实现并行计数。并行管理是由flink实现的。
public interface Accumulator<V, R extends Serializable> extends Serializable, Cloneable
计数的结果通过JobExecutionResul的getAccumulatorResult方法t获取。
2、示例,在正常业务处理流程中对空字段计数,空字段包括null、空格、TAB等内容。这场景比较多见。
public class EmptyFieldsCountAccumulator {
private static final String EMPTY_FIELD_ACCUMULATOR= "empty-fields";
public static void main(String args[]) throws Exception{
final ParameterTool params = ParameterTool.fromArgs(args);
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
// make parameters available in the web interface
env.getConfig().setGlobalJobParameters(params);
// get the data set
final DataSet<StringTriple> file = getDataSet(env, params);
// filter lines with empty fields
final DataSet<StringTriple> filteredLines = file.filter(new EmptyFieldFilter());
// Here, we could do further processing with the filtered lines...
JobExecutionResult result;
// output the filtered lines
if (params.has("output")) {
filteredLines.writeAsCsv(params.get("output"));
// execute program
result = env.execute("Accumulator example");
} else {
System.out.println("Printing result to stdout. Use --output to specify output path.");
filteredLines.print();
result = env.getLastJobExecutionResult();
}
// get the accumulator result via its registration key
final List<Integer> emptyFields = result.getAccumulatorResult(EMPTY_FIELD_ACCUMULATOR);
System.out.format("Number of detected empty fields per column: %s\n", emptyFields);
}
@SuppressWarnings("unchecked")
private static DataSet<StringTriple> getDataSet(ExecutionEnvironment env, ParameterTool params) {
if (params.has("input")) {
return env.readCsvFile(params.get("input"))
.fieldDelimiter(";")
.pojoType(StringTriple.class);
} else {
System.out.println("Executing EmptyFieldsCountAccumulator example with default input data set.");
System.out.println("Use --input to specify file input.");
return env.fromCollection(getExampleInputTuples());
}
}
private static Collection<StringTriple> getExampleInputTuples() {
Collection<StringTriple> inputTuples = new ArrayList<StringTriple>();
inputTuples.add(new StringTriple("John", "Doe", "Foo Str."));
inputTuples.add(new StringTriple("Joe", "Johnson", ""));
inputTuples.add(new StringTriple(null, "Kate Morn", "Bar Blvd."));
inputTuples.add(new StringTriple("Tim", "Rinny", ""));
inputTuples.add(new StringTriple("Alicia", "Jackson", " "));
inputTuples.add(new StringTriple("Alicia", "Jackson", " "));
inputTuples.add(new StringTriple("Alicia", "Jackson", " "));
inputTuples.add(new StringTriple("Tom", "Jackson", "A"));
inputTuples.add(new StringTriple("Amy", "li", "B "));
return inputTuples;
}
/**
* This function filters all incoming tuples that have one or more empty fields.
* In doing so, it also counts the number of empty fields per attribute with an accumulator (registered under
* {@link EmptyFieldsCountAccumulator#EMPTY_FIELD_ACCUMULATOR}).
*/
public static final class EmptyFieldFilter extends RichFilterFunction<StringTriple> {
// create a new accumulator in each filter function instance
// accumulators can be merged later on
private final VectorAccumulator emptyFieldCounter = new VectorAccumulator();
@Override
public void open(final Configuration parameters) throws Exception {
super.open(parameters);
// register the accumulator instance
getRuntimeContext().addAccumulator(EMPTY_FIELD_ACCUMULATOR,
this.emptyFieldCounter);
}
@Override
public boolean filter(final StringTriple t) {
boolean containsEmptyFields = false;
// iterate over the tuple fields looking for empty ones
for (int pos = 0; pos < t.getArity(); pos++) {
final String field = t.getField(pos);
if (field == null || field.trim().isEmpty()) {
containsEmptyFields = true;
// if an empty field is encountered, update the
// accumulator
this.emptyFieldCounter.add(pos);
}
}
return !containsEmptyFields;
}
}
/**
* This accumulator maintains a vector of counts. Calling {@link #add(Integer)} increments the
* <i>n</i>-th vector component. The size of the vector is automatically managed.
* 这个向量计数器输入是整数,输出是List,并按字段位置计数,List里的索引就是字段计数位置,其值就是计数结果
*/
public static class VectorAccumulator implements Accumulator<Integer,ArrayList<Integer>>{
//存储计数器向量
private final ArrayList<Integer> resultVector;
public VectorAccumulator() {
this(new ArrayList<>());
}
public VectorAccumulator(ArrayList<Integer> resultVector) {
this.resultVector = resultVector;
}
private void updateResultVector(int position,int delta){
//如果给出的位置不够就扩充向量容器
while (this.resultVector.size()<=position){
this.resultVector.add(0);
}
final int component = this.resultVector.get(position);
this.resultVector.set(position,component+delta);
}
//在指定位置加1
@Override
public void add(Integer position) {
updateResultVector(position,1);
}
@Override
public ArrayList<Integer> getLocalValue() {
return this.resultVector;
}
@Override
public void resetLocal() {
this.resultVector.clear();
}
@Override
public void merge(Accumulator<Integer, ArrayList<Integer>> other) {
//合并两个向量计数器容器,按容器的索引合并
final ArrayList<Integer> otherVector = other.getLocalValue();
for(int i=0;i<otherVector.size();i++){
updateResultVector(i,otherVector.get(i));
}
}
@Override
public Accumulator<Integer, ArrayList<Integer>> clone() {
return new VectorAccumulator(new ArrayList<>(this.resultVector));
}
@Override
public String toString() {
return StringUtils.join(this.resultVector,':');
}
}
public static class StringTriple extends Tuple3<String, String, String> {
public StringTriple() {}
public StringTriple(String f0, String f1, String f2) {
super(f0, f1, f2);
}
}
}
flink 并行计数器实现的更多相关文章
- 一文让你彻底了解大数据实时计算引擎 Flink
前言 在上一篇文章 你公司到底需不需要引入实时计算引擎? 中我讲解了日常中常见的实时需求,然后分析了这些需求的实现方式,接着对比了实时计算和离线计算.随着这些年大数据的飞速发展,也出现了不少计算的框架 ...
- [源码解析] 当 Java Stream 遇见 Flink
[源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...
- Flink 的运行架构详细剖析
1. Flink 程序结构 Flink 程序的基本构建块是流和转换(请注意,Flink 的 DataSet API 中使用的 DataSet 也是内部流 ).从概念上讲,流是(可能永无止境的)数据记录 ...
- C# Parallel.Invoke 实现
Parallel.Invoke应该是Parallel几个方法中最简单的一个了,我们来看看它的实现,为了方法大家理解,我尽量保留源码中的注释: public static class Parallel ...
- Flink01
1. 什么是Flink? 1.1 4代大数据计算引擎 第一代: MapReducer 批处理 Mapper, Reducer Hadoop的MapReducer将计算分为两个阶段, 分别为Map和Re ...
- Flink Program Guide (1) -- 基本API概念(Basic API Concepts -- For Java)
false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...
- Flink项目实战(一)---核心概念及基本使用
前言.flink介绍: Apache Flink 是一个分布式处理引擎,用于在无界和有界数据流上进行有状态的计算.通过对时间精确控制以及状态化控制,Flink能够运行在任何处理无界流的应用中,同时对有 ...
- flink03-----1.Task的划分 2.共享资源槽 3.flink的容错
1. Task的划分 在flink中,划分task的依据是发生shuffle(也叫redistrubute),或者是并行度发生变化 1. wordcount为例 package cn._51doit ...
- Flink调优
第1章 资源配置调优 Flink性能调优的第一步,就是为任务分配合适的资源,在一定范围内,增加资源的分配与性能的提升是成正比的,实现了最优的资源配置后,在此基础上再考虑进行后面论述的性能调优策略. ...
随机推荐
- linux下搭建jenkins
为了配合上一篇的ant+jenkins做持续集成,需要在linux环境下搭建一个jenkins平台.网上有很多安装的例子,我主要记录一下自己遇到的问题,真真的是特别惆怅的,每次我遇到的问题都格外多. ...
- 记录Flex布局的属性
容器属性 flex-dirextion(主轴的方向):>>row(水平) | row-reverse(水平取反) | column(垂直) | column-reverse(垂直取反) f ...
- Mysql 连接提示 Client does not support authentication protocol requested by server 客户端不支持服务器请求的身份验证协议;考虑升级MySQL客户端
由于查阅了很多百度文档发现很多方法比较复杂,所以写个备忘: 首先,进入MySQL 8.0Command Line Client -Unicode,输入密码,登录进去. 然后,在命令行输入:ALTER ...
- HTML&CSS基础-子元素和后代元素选择器
HTML&CSS基础-子元素和后代元素选择器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.html源代码 <!DOCTYPE html> <html ...
- 6.3 使用Spark SQL读写数据库
Spark SQL可以支持Parquet.JSON.Hive等数据源,并且可以通过JDBC连接外部数据源 一.通过JDBC连接数据库 1.准备工作 ubuntu安装mysql教程 在Linux中启动M ...
- axios如何先请求A接口然后在请求B接口
总结:在第一个then的请求结束后,在添加一个then,表示请求第二个接口,在第二个then里面写第二个接口的请求方式 axios.get("./a.json").then(res ...
- Git之SSH公钥与私钥
今天来探讨一下如何使用Git的操作,来进一步的实现代码的下载到本地,我原来也不是很明白git中生成公钥和私钥的作用,我一直在想,git里面你把自己的公钥发给了git的服务器,他是怎么判断的,每一次我换 ...
- day67_10_11
一.路由跳转 在vue中,路由条状有很多种. 其中有点击事件触发的路由跳转: this.$router.push('/course'); 和通过名字跳转的: this.$router.push({na ...
- BZOJ2733/LG3324 「HNOI2014」永无乡 权值线段树合并
问题描述 BZOJ2733 LG3224 题解 对于每个结点建立一棵权值线段树. 查询操作就去查询第 \(k\) 大,合并操作就合并两颗权值线段树. 并查集维护连通性. 同时 STO hkk,zcr, ...
- EM-高斯混合模型
EM-高斯混合模型 认识 前面为了直观认识 EM 算法, 用的"扔硬币"的案例, 是为了简化和直观, 而稍微偏应用和深入一点是高斯模型分类,这样一个话题. 就好比我们现在有一堆的数 ...