赞
踩
知道大数据的同学也应该知道 Flink 吧,最近在中国的热度比较高,在社区的推动下,Flink 技术栈在越来越多的公司开始得到应用。
据不完全统计,Flink 在中国公司的采用情况(部分)
其中, 他们用 Flink 做了什么?
https://cwiki.apache.org/confluence/display/FLINK/Powered+by+Flink 更多公司查看点这里。
**上面我们看到很多公司在用 Flink,构建了不少的应用,接下来用数据说话,**在 **Google Trends **上查看关键词 ,看一下 Flink 的搜索用户画像,如图:
国内热度一只独秀,中国的开发者对 Flink 的热情更高。国内的公司更愿意拥抱新鲜事物,用于尝试。
回到百度指数,查看 Flink 关键次在全国城市的搜索热度分布。(额,数据可能不是很准确,大部分程序员可能不用百度搜索)
再回到 Google 搜索,查看相应数据。
浙江上榜是因为阿里,阿里的程序员为社区贡献了 Blink 分支,后续会把一些优秀的特性合并到主分支上。
在这里感谢默默付出的参与者们,正是你们的开源奉献,才使得需求端(公司)能够更多的把 Flink 应用到实际的业务中,提升业务水平。同时社区积极推进 Flink 相关课程培训,培训更多的 Flink 开发者,建设人才。
一个技术火不火?除了底层的设计框架之外,参与者的热情也是一方面,大家愿意学习它,愿意使用它,更愿意维护它。我想,开源的魅力大抵如此。
搬砖、搬砖,还在等什么呢?
官网的一段话,最准确的 DenFination
Apache Flink is a framework and** distributed processing engine for stateful** computations over unbounded and bounded data streams.
首先它是一个框架,框架的作用就是隐藏底层细节,使用起来更加简单,让开发者更关注与业务的实现。其次他也是分布式的处理引擎,单机的处理能力有限,那就多节点计算,这就涉及到分布式,它解决了很多分布式计的问题。有状态和有界无界的数据流,这里先买个不做介绍。
接下里 介绍 Flink 最核心的三个语义,希望读者可以深刻理解。
Stream , 翻译过来是流,那 Data Steam 就是数据流。在 Flink 中,一切数据都是 Stream,分为 unbounded (无界)和 bounded(有界)。使用过 Hive 或 Mapreduce 或 mysql 的同学应该知道,数据存在 hdfs 或其他文件系统上,并且是一个固定的大小,我们把这些数据称为一批数据。使用过 Spark Streaming 或 Storm 的同学也应该知道数据源源不断的流入,流出,计算,这个过程的数据称为数据流。但是在 Flink 里,把批/流数据全部抽象成流,分为有界的流和无界的流。
注:这里在语义上的把数据统一成流,更好的实现了流批统一,底层公共一套 API,这个后面会讲到,看不明白没关系。
State , 翻译过来是状态。它是一个有状态的计算引擎,举一个例子,我们要统计一个用户最近一个小时的访问次数, Flink 会在系统内部会把这个 count 值保存成状态,一直累加或删除。状态就像记忆,而且这个份记忆是保存在自身的。
它的优势:
Time 时间。Flink 有三种时间,分别是 event time ,数据产生的时间。ingestion time 数据到达 Flink DateFlow 的时间。processing time 数据到达每个算子的时间。
Flink 提供了丰富的时间语义支持。
注:Flink 为什么引入了时间的概念呢?因为在 Flink 内部数据是流,需要有一个来度量流计算处理进度的标识。所以引入了时间这个概念。
接下来,我们来简单了解下 Flink 的分层 API,在这一部分,本篇文章不会太深入,会在后面的文章中讲解每一层的具体应用以及实现。
如图,Flink 根据抽象程度分层了三层,提供了三种不同的 API。每一种 API 在简洁性和表达力上有着不同的侧重,并且针对不同的应用场景。
ProcessFunction 是 Flink 所提供的最具表达力的接口。下面这个例子充分展现了 KeyedProcessFunction
强大的表达力,也因此是一个实现相当复杂的接口。
/** * 将相邻的 keyed START 和 END 事件相匹配并计算两者的时间间隔 * 输入数据为 Tuple2<String, String> 类型,第一个字段为 key 值, * 第二个字段标记 START 和 END 事件。 */ public static class StartEndDuration extends KeyedProcessFunction<String, Tuple2<String, String>, Tuple2<String, Long>> { private ValueState<Long> startTime; @Override public void open(Configuration conf) { // obtain state handle startTime = getRuntimeContext() .getState(new ValueStateDescriptor<Long>("startTime", Long.class)); } /** Called for each processed event. */ @Override public void processElement( Tuple2<String, String> in, Context ctx, Collector<Tuple2<String, Long>> out) throws Exception { switch (in.f1) { case "START": // set the start time if we receive a start event. startTime.update(ctx.timestamp()); // register a timer in four hours from the start event. ctx.timerService() .registerEventTimeTimer(ctx.timestamp() + 4 * 60 * 60 * 1000); break; case "END": // emit the duration between start and end event Long sTime = startTime.value(); if (sTime != null) { out.collect(Tuple2.of(in.f0, ctx.timestamp() - sTime)); // clear the state startTime.clear(); } default: // do nothing } } /** Called when a timer fires. */ @Override public void onTimer( long timestamp, OnTimerContext ctx, Collector<Tuple2<String, Long>> out) { // Timeout interval exceeded. Cleaning up the state. startTime.clear(); } }
DataStream API 为许多通用的流处理操作提供了处理原语。DataStream API 支持 Java 和 Scala 语言,预先定义了例如map()
、reduce()
、aggregate()
等函数。你可以通过扩展实现预定义接口或使用 Java、Scala 的 lambda 表达式实现自定义的函数。
用过 spark 的同学看到这里一定很熟悉。
下面的代码示例展示了如何捕获会话时间范围内所有的点击流事件,并对每一次会话的点击量进行计数。
// 网站点击 Click 的数据流 DataStream<Click> clicks = ... DataStream<Tuple2<String, Long>> result = clicks // 将网站点击映射为 (userId, 1) 以便计数 .map( // 实现 MapFunction 接口定义函数 new MapFunction<Click, Tuple2<String, Long>>() { @Override public Tuple2<String, Long> map(Click click) { return Tuple2.of(click.userId, 1L); } }) // 以 userId (field 0) 作为 key .keyBy(0) // 定义 30 分钟超时的会话窗口 .window(EventTimeSessionWindows.withGap(Time.minutes(30L))) // 对每个会话窗口的点击进行计数,使用 lambda 表达式定义 reduce 函数 .reduce((a, b) -> Tuple2.of(a.f0, a.f1 + b.f1));
Flink 支持两种关系型的 API,Table API 和 SQL。这两个 API 都是批处理和流处理统一的 API,这意味着在无边界的实时数据流和有边界的历史记录数据流上,关系型 API 会以相同的语义执行查询,并产生相同的结果。
SELECT userId, COUNT(*)
FROM clicks
GROUP BY SESSION(clicktime, INTERVAL '30' MINUTE), userId
最后,这几点 Flink 的架构方面的设计,或许是你说服别人使用 Flink 的理由。
1、处理有界和无界的数据。任何类型的数据都可以形成一种事件流。信用卡交易、传感器测量、机器日志、网站或移动应用程序上的用户交互记录,所有这些数据都形成一种流。
Flink 擅长处理无界和有界数据流,得益于精确的时间控制和状态化。
**2、部署灵活。**Flink 集成了所有常见的集群资源管理器,例如 Hadoop YARN、 Apache Mesos 和 Kubernetes,但同时也可以作为独立集群运行。
3、极高的可伸缩性。阿里去年双十一的数据处理峰值 17亿条/秒。
4、极致的流式处理性能。
如图,数据经过计算,会被保存在state中。这里 Flink 做了优化,计算结果一开始保存在内存中,如果超出一定大小,就会保存在可高效访问的磁盘结构中。也就是说,Flink 本地状态尽可能的保存在内存中。为了保证容错和数据准确性,Flink 也会定期和异步的把本地状态进行持久化存储来保证故障场景下精确一次的状态一致性。(有点绕!其实就是解决分布式场景下数据不一致的问题)
**
Flink 非常注重流数据处理的可运维性。下面介绍 Flink 的故障恢复机制,并介绍其管理和监控应用的功能。
在分布式系统中,服务故障是常有的事,如何保证服务能够7*24小时稳定运行?
就两个需求:任务失败了可以重启;重启之后还会和没发生故障一样。
Flink通过几下多种机制维护应用可持续运行及其一致性:
Flink 作为一个优秀的实时计算框架,不可能仅凭一篇文章就能全部讲清楚,所以遵循循序渐进的原则,本文主要介绍一些了Flink在全球的趋势,为什么火,基础语义,架构等基础知识作为入门,更好的理解它的设计初衷,真正明白 Flink 到底好在哪?如果您看完本文能够了解这些,点赞(再看)转发走一波,谢谢支持。
获取文章第一时间更新,欢迎扫码关注微信公众号:cuteximi
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。