抽象层次

Flink提供不同级别的抽象来开发流/批处理应用程序。

抽象层次

  • 最低级抽象只提供有状态流。它通过Process Function嵌入到DataStream API中。它允许用户自由处理来自一个或多个流的事件,并使用一致的容错状态。此外,用户可以注册事件时间和处理时间回调,允许程序实现复杂的计算。

  • 实际上,大多数应用不需要上述低级抽象,而是针对Core API编程, 如DataStream API(有界/无界流)和DataSet API (有界数据集)。这些流动的API提供了用于数据处理的通用构建块,例如各种形式的用户指定的转换,连接,聚合,窗口,状态等。在这些API中处理的数据类型在相应的编程语言中表示为类。

低级Process Function与DataStream API集成,因此只能对某些操作进行低级抽象。DataSet API提供的有限数据集的其他原语,如循环/迭代。

  • Table API是以表为中心的声明性DSL,其可以是动态地改变的表(表示流时)。Table API遵循(扩展)关系模型:表附加了一个模式(类似于在关系数据库中的表),API提供了类似的操作,如选择,项目,连接,分组依据,聚合等。Table API程序以声明方式定义应该执行的逻辑操作,而不是准确指定 操作代码的外观。虽然Table API可以通过各种类型的用户定义函数进行扩展,但它的表现力不如Core API,但使用更简洁(编写的代码更少)。此外,Table API程序还会通过优化程序,在执行之前应用优化规则。

可以在表和DataStream / DataSet之间无缝转换,允许程序混合Table API以及DataStream 和DataSet API。

  • Flink提供的最高级抽象是SQL。这种抽象在语义和表达方面类似于Table API,但是将程序表示为SQL查询表达式。在SQL抽象与 Table API紧密地相互作用,和SQL查询可以在Table API中定义的表上执行。

程序和数据流

Flink程序的基本构建块是流和转换。(请注意,Flink的DataSet API中使用的DataSet也是内部流 - 稍后会详细介绍。)从概念上讲,流是(可能永无止境的)数据记录流,而转换是将一个或多个流作为输入,并产生一个或多个流输出的结果。

执行时,Flink程序映射到流数据流,由流和转换运算符组成。每个数据流都以一个或多个源开头,并以一个或多个接收器结束。数据流类似于任意有向无环图 (DAG)。尽管通过迭代结构允许特殊形式的循环 ,但为了简单起见,我们将在大多数情况下对此进行掩饰。

DataStream程序及其数据流

通常,程序中的转换与数据流中的运算符之间存在一对一的对应关系。但是,有时一个转换可能包含多个转换运算符。

源流和接收器记录在流连接器和批处理连接器文档中。DataStream运算符和DataSet转换中记录了转换。

并行数据流

Flink中的程序本质上是并行和分布式的。在执行期间,流具有一个或多个流分区,并且每个运算符具有一个或多个运算符子任务。运算符子任务彼此独立,并且可以在不同的线程中执行,并且可能在不同的机器或容器上执行。

运算符子任务的数量是该特定运算符的并行度。流的并行性始终是其生成运算符的并行性。同一程序的不同运算符可能具有不同的并行级别。

并行数据流

流可以以一对一(或转发)模式或以重新分发模式在两个算子之间传输数据:

  • 一对一流(例如,在上图中的Source和map()算子之间)保留元素的分区和排序。这意味着map()算子的subtask [1] 将以与Source算子的subtask [1]生成的顺序相同的顺序看到相同的元素。

  • 重新分配流(在上面的map()和keyBy / window之间,以及 keyBy / window和Sink之间)重新分配流。每个算子子任务将数据发送到不同的目标子任务,具体取决于所选的转换。实例是 keyBy() (其通过散列密钥重新分区),广播() ,或重新平衡() (其重新分区随机地)。在重新分配交换中,元素之间的排序仅保留在每对发送和接收子任务中(例如,map()的子任务[1] 和子任务[2]keyBy / window)。因此,在此示例中,保留了每个密钥内的排序,但并行性确实引入了关于不同密钥的聚合结果到达接收器的顺序的非确定性。

有关配置和控制并行性的详细信息,请参阅并行执行的文档。

视窗

聚合事件(例如,计数,总和)在流上的工作方式与批处理方式不同。例如,不可能计算流中的所有元素,因为流通常是无限的(无界)。相反,流上的聚合(计数,总和等)由窗口限定,例如“在最后5分钟内计数”或“最后100个元素的总和”。

Windows可以是时间驱动的(例如:每30秒)或数据驱动(例如:每100个元素)。一个典型地区分不同类型的窗口,例如翻滚窗口(没有重叠), 滑动窗口(具有重叠)和会话窗口(由不活动的间隙打断)。

时间和计数Windows

更多窗口示例可以在此博客文章中找到。更多详细信息在窗口文档中。

时间

当在流程序中引用时间(例如定义窗口)时,可以参考不同的时间概念:

  • 事件时间是创建事件的时间。它通常由事件中的时间戳描述,例如由生产传感器或生产服务附加。Flink通过时间戳分配器访问事件时间戳。

  • 摄取时间是事件在源操作员处输入Flink数据流的时间。

  • 处理时间是执行基于时间的操作的每个算子的本地时间。

事件时间,摄取时间和处理时间

有关如何处理时间的更多详细信息,请参阅事件时间文档

有状态的操作

虽然数据流中的许多操作只是一次查看一个单独的事件(例如事件解析器),但某些操作会记住多个事件(例如窗口操作符)的信息。这些操作称为有状态。

状态操作的状态保持在可以被认为是嵌入式键/值存储的状态中。状态被分区并严格地与有状态算子读取的流一起分发。因此,只有在keyBy()函数之后才能在键控流上访问键/值状态,并且限制为与当前事件的键相关联的值。对齐流和状态的密钥可确保所有状态更新都是本地操作,从而保证一致性而无需事务开销。此对齐还允许Flink重新分配状态并透明地调整流分区。

状态和分区

有关更多信息,请参阅有关状态的文档。

容错检查点

Flink使用流重放和检查点的组合实现容错。检查点与每个输入流中的特定点以及每个算子的对应状态相关。通过恢复算子的状态并从检查点重放事件,可以从检查点恢复流数据流,同时保持一致性(恰好一次处理语义)。

检查点间隔是在执行期间用恢复时间(需要重放的事件的数量)来折衷容错开销的手段。

容错内部的描述提供了有关Flink如何管理检查点和相关主题的更多信息。有关启用和配置检查点的详细信息,请参阅检查点API文档。

批处理流

Flink执行批处理程序作为流程序的特殊情况,其中流是有界的(有限数量的元素)。数据集做为数据流在内部处理。因此,上述概念以适用于流程序相同的方式应用于批处理程序,只是少数例外:

  • 批处理程序的容错不使用检查点。而是通过完全重放流来恢复。这是可能的,因为输入是有界的。这会使成本更多高,但却使常规处理更便宜,因为它避免了检查点。

  • DataSet API中的有状态操作使用简化的内存/核外数据结构,而不是键/值索引。

  • DataSet API引入了特殊的同步(基于超前的)迭代,这在有界流上是可行的。有关详细信息,请查看迭代文档

下一步

Flink的Distributed Runtime。

Apache Flink文档

本文档适用于Apache Flink master版。

Apache Flink是一个用于分布式流和批处理数据处理的开源平台。Flink的核心是流数据流引擎,为数据流上的分布式计算提供数据分发,通信和容错。Flink在流引擎之上构建批处理,涵盖原生的迭代支持,受管理的内存和程序优化。

第一步

概念:从Flink的数据流编程模型分布式运行时环境的基本概念开始。这将有助于您了解文档的其他部分,包括配置和编程指南。我们建议您先阅读这部分内容。

教程:

编程指南:您可以阅读我们关于基本API概念DataStream APIDataSet API的指南,以了解如何编写您的第一个Flink程序。

部署

在将Flink作业投入生产之前,请阅读生产准备清单

发行说明

发行说明涵盖了Flink版本之间的重要更改。如果您计划将Flink升级到更高版本,请仔细阅读这些说明。

外部资源

关于Flink项目,一般会经常被问到以下问题。

常见问题

Apache Flink仅用于(近)实时处理用例吗?

Flink是一个非常通用的系统,用于数据处理和数据驱动的应用程序,数据流作为核心构建块。这些数据流可以是实时数据流,也可以是存储的历史数据流。例如,在Flink的视图中,文件是存储的字节流。因此,Flink支持实时数据处理和应用,以及批处理应用。

流可以是无界的(没有结束,事件不断发生)或受限制(流有开始和结束)。例如,来自消息队列的Twitter馈送或事件流通常是无界流,而来自文件的字节流是有界流。

如果一切都是流,为什么Flink中有DataStream和DataSet API?

有界流通常比无界流更有效。在(近)实时处理无限事件流需要系统能够立即对事件起作用并产生中间结果(通常具有低延迟)。处理有界流通常不需要产生低延迟结果,因为无论如何数据都是旧的(相对而言)。这允许Flink以简单且更有效的方式处理数据。

DataStream API通过支持低延时的结果和对事件和时间(包括事件时间)灵活反应的模型捕获无界流和有界流的连续处理,

DataSet API具有加快有界数据流的处理的技术。将来,社区计划将这些优化与DataStream API中的技术相结合。

Flink如何与Hadoop堆栈相关?

Flink独立于Apache Hadoop,并且在没有任何Hadoop依赖性的情况下运行。

但是,Flink与许多Hadoop组件集成得非常好,例如HDFS,YARN或HBase。与这些组件一起运行时,Flink可以使用HDFS读取数据,或写入结果和检查点/快照。Flink可以通过YARN轻松部署,并与YARN和HDFS Kerberos安全模块集成。

Flink运行的其他堆栈是什么?

Flink可以在Kubernetes,Mesos, Docker上运行 ,甚至作为独立服务运行。

使用Flink有哪些先决条件?

您需要Java 8来运行Flink作业/应用。
Scala API(可选)依赖于Scala 2.11。
Apache ZooKeeper需要高度可用且没有单点故障的设置。
对于可以从故障中恢复的高可用流处理设置,Flink需要某种形式的分布式存储用于检查点(HDFS / S3 / NFS / SAN / GFS / Kosmos / Ceph / …)。

Flink支持多大的规模?

用户在非常小的设置(少于5个节点)和1000个节点以及状态的TB上运行Flink作业。

Flink是否仅限于内存数据集?

对于DataStream API,Flink支持大于内存的状态来配置RocksDB状态后端。

对于DataSet API,所有操作(delta迭代除外)都可以扩展到主内存之外。

常见错误消息

“ 获得帮助”页面上列出了常见错误消息。

参考资料

[1].https://flink.apache.org/faq.html

用例

Apache Flink因其丰富的功能集而成为开发和运行多种不同类型应用程序的绝佳选择。Flink的功能包括对流和批处理的支持,复杂的状态管理,事件时间处理语义以及状态的恰好一次一致性保证。此外,Flink可以部署在各种资源管理集群(如YARN,Apache Mesos和Kubernetes)上,也可以部署为裸机硬件上的单个群集。Flink配置为高可用性,没有单点故障。Flink已经被证明可以扩展到数千个核心和万亿字节的应用状态,提供高吞吐量和低延迟,并为世界上一些最苛刻的流处理应用程序提供支持。

下面,我们将探讨由Flink提供支持的最常见类型的应用程序,并指出实际示例。

  • 事件驱动的应用
  • 数据分析应用
  • 数据管道应用

事件驱动的应用

什么是事件驱动的应用?

事件驱动的应用程序是一个有状态的应用程序,它从一个或多个事件流中提取事件,并通过触发计算,状态更新或外部操作对传入事件做出响应。

事件驱动的应用程序是传统应用程序设计的演变,具有分离的计算和数据存储层。在传统应用的体系结构中,应用从远程事务数据库中读取数据并将数据持久化到远程事务数据库。

相比之下,事件驱动的应用程序基于有状态流处理应用程序。在这种设计中,数据和计算是共同定位的,这产生了本地(内存或磁盘)数据访问。通过定期将检查点写入远程持久存储来实现容错。下图描绘了传统应用程序体系结构和事件驱动应用程序之间的差异。

事件驱动的应用有哪些优点?

事件驱动的应用程序不是查询远程数据库,而是在本地访问其数据,从而在吞吐量和延迟方面发挥更好的性能。远程持久存储的定期检查点可以异步和递增完成。因此,检查点对常规事件处理的影响非常小。但是,事件驱动的应用程序设计提供的不仅仅是本地数据访问。在分层体系结构中,多个应用程序共享同一数据库是很常见的。因此,需要协调数据库的任何更改,例如由于应用程序更新或扩展服务而更改数据布局。由于每个事件驱动的应用程序都负责自己的数据,因此对数据表示的更改或扩展应用程序需要较少的协调。

Flink如何支持事件驱动的应用?

事件驱动应用程序的限制由流处理器处理时间和状态的程度来定义。Flink的许多杰出功能都围绕着这些概念。Flink提供了一组丰富的状态原语,可以管理非常大的数据量(最多几TB),并且具有恰好一次的一致性保证。此外,Flink支持事件时间,高度可定制的窗口逻辑,以及通过ProcessFunction实现高级业务逻辑提供的细粒度时间控制。此外,Flink还提供了一个用于复杂事件处理(CEP)的库,用于检测数据流中的模式。

但是,Flink针对事件驱动应用程序的突出特点是保存点功能。保存点是一致的状态图像,可用作兼容应用程序的起点。给定保存点,可以更新应用程序或调整其规模,或者可以启动应用程序的多个版本以进行A / B测试。

什么是典型的事件驱动应用?

  • 欺诈识别
  • 异常检测
  • 基于规则的警报
  • 业务流程监控
  • Web应用程序(社交网络)

数据分析应用

什么是数据分析应用?

分析工作从原始数据中提取信息和洞察力。传统上,分析是在有记录事件的有界数据集上作为批查询或应用程序来执行的。为了将最新数据合并到分析结果中,必须将其添加到分析的数据集中,并重新运行查询或应用程序。结果将写入存储系统或作为报告发出。

借助先进的流处理引擎,还可以实时地执行分析。流式查询或应用程序不是读取有限数据集,而是摄取实时事件流,并在消耗事件时不断生成和更新结果。结果要么写入外部数据库,要么保持为内部状态。仪表板应用程序可以从外部数据库读取最新结果或直接查询应用程序的内部状态。

Apache Flink支持流式和批量分析应用程序,如下图所示。

流式分析应用有哪些优势?

与批量分析相比,连续流分析的优势不仅限于因消除定期导入和查询执行而从事件到洞察的低得多的延迟。与批量查询相比,流式查询不必处理输入数据中的人为边界,这些边界是由定期导入和输入的有界性质引起的。

另一方面是更简单的应用程序架构。批量分析管道由若干独立组件组成,以周期性地调度数据提取和查询执行。可靠地操作这样的管道并非易事,因为一个组件的故障会影响管道的后续步骤。相比之下,在像Flink这样的复杂流处理器上运行的流分析应用程序包含从数据摄取到连续结果计算的所有步骤。因此,它可以依赖于引擎的故障恢复机制。

Flink如何支持数据分析应用?

Flink为连续流式传输和批量分析提供了非常好的支持。具体来说,它具有符合ANSI标准的SQL接口,具有用于批处理和流式查询的统一语义。无论是在记录事件的静态数据集上还是在实时事件流上运行,SQL查询都会计算相同的结果。对用户定义函数的丰富支持可确保在SQL查询中执行自定义代码。如果需要更多的自定义逻辑,Flink的DataStream API或DataSet API提供更多的低级控制。此外,Flink的Gelly库为批量数据集上的大规模和高性能图形分析提供算法和构建块。

什么是典型的数据分析应用?

  • 电信网络的质量监控
  • 分析移动应用程序中的产品更新和实验评估
  • 对消费者技术中的实时数据进行特别分析
  • 大规模图分析

数据管道应用

什么是数据管道?

提取 - 转换 - 加载(ETL)是在存储系统之间转换和移动数据的常用方法。通常会定期触发ETL作业,以便将数据从事务数据库系统复制到分析数据库或数据仓库。

数据管道与ETL作业具有相似的用途。它们可以转换和丰富数据,并可以将数据从一个存储系统移动到另一个存储系统 但是,它们以连续流模式运行,而不是周期性地触发。因此,他们能够从连续生成数据的源中读取记录,并以低延迟将其移动到目的地。例如,数据管道可能会监视文件系统目录中的新文件并将其数据写入事件日志。另一个应用程序可能会将事件流实现到数据库,或者逐步构建和优化搜索索引。

下图描述了定期ETL作业和连续数据管道之间的差异。

数据管道有哪些优势?

连续数据流水线优于周期性ETL作业的显著优势是减少了将数据移动到目的地的延迟。此外,数据管道更加通用,可用于更多用例,因为它们能够连续消耗和发送数据。

Flink如何支持数据管道?

Flink的SQL接口(或表API)可以解决许多常见的数据转换或丰富任务,并支持用户定义的函数。通过使用更通用的DataStream API,可以实现具有更高级要求的数据管道。Flink为各种存储系统(如Kafka,Kinesis,Elasticsearch和JDBC数据库系统)提供了丰富的连接器。它还具有连续的文件系统源,用于监视以时间分区方式写入文件的目录和接收器。

什么是典型的数据管道应用?

  • 电子商务中的实时搜索索引构建
  • 电子商务中持续的ETL

参考资料:

[1].https://flink.apache.org/usecases.html

Apache Flink是一个框架和分布式处理引擎,用于对无界和有界数据流进行有状态计算。Flink设计为在所有常见的集群环境中运行,以内存速度和任何规模执行计算。

在这里,我们解释了Flink架构的重要方面。

无界和有界数据的处理

任何类型的数据都是作为事件流产生的。信用卡交易,传感器测量,机器日志或网站或移动应用程序上的用户交互,所有这些数据都作为流生成。

数据可以作为无界或有界流处理。

  1. 无界流 有一个开始,但没有定义的结束。它们不会终止并提供其生成的数据。无界流必须持续处理,即必须在摄取事件后立即处理事件。不可能等待所有的输入数据都到达,因为输入是无界的,并且在任何时间点都不会结束。处理无界数据通常要求以特定顺序(例如事件发生的顺序)摄取事件,以便能够推断结果的完整性。

  2. 有界流具有定义的开始和结束。可以在执行任何计算之前,通过摄取所有数据来处理有界流。有界数据集是可以被排序的,因此处理有界流不需要有序摄取。有界流的处理也称为批处理。

Apache Flink擅长处理无界和有界数据集。精确控制时间和状态使Flink的运行时能够在无界流上运行任何类型的应用程序。有界流由算法和数据结构在内部处理,这些算法和数据结构专门针对固定大小的数据集而设计,从而发挥出性能优势。

随处部署应用

Apache Flink是一个分布式系统,需要计算资源才能执行的应用程序。Flink可以与所有常见的集群资源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也可以设置为独立的集群运行。

Flink旨在很好地适用于之前列出的每个资源管理器,这是通过特定于资源管理器的部署模式实现的,这些模式允许Flink以其惯用的方式与每个资源管理器进行交互。

部署Flink应用程序时,Flink会根据应用程序配置的并行性自动识别所需资源,并从资源管理器里申请它们。如果发生故障,Flink会通过申请新资源来替换发生故障的容器。所有提交或控制应用程序的通信都是通过REST调用来进行,这简化了Flink在许多环境中的集成。

以任何规模运行应用

Flink旨在以任何规模运行有状态的流应用,应用程序可以并行化为数千个在集群中分布和同时执行的任务。因此,应用程序可以利用几乎无限量的CPU、主内存、磁盘和网络IO。而且,Flink可以轻松维护数据量非常大的应用状态。其异步和增量检查点算法确保对处理的延迟影响最小,同时保证恰好一次状态的一致性。

用户报告了在其生产环境中运行的Flink集群的规模,这样的规模有点令人印象深刻,例如

  • 应用程序每天处理数万亿个事件,
  • 应用程序维护多个TB的状态,以及
  • 应用程序在数千个内核的运行。

内存的性能优势

有状态Flink应用针对本地状态的访问进行了优化。任务状态始终保留在内存中,或者,如果状态大小超过可用内存,则保存在可高效访问的磁盘上的数据结构中。因此,任务通过访问本地(通常是内存中)状态来执行所有计算,从而产生非常低的处理延迟。Flink通过定期并且异步地把本地状态打检查点并持久化到存储设备来保证在出现故障时的恰好一次状态的一致性。

参考资料

[1].https://flink.apache.org/flink-architecture.html

微服务解惑

微服务与容器

微服务又指的是在传统应用架构的基础上,按照业务能力将系统拆分成多个服务,每个服务都是一个独立的应用,对外提供一些列的公共服务API,服务之间以轻量的方式互相调用。
微服务里的每个服务都是一个组件,通过编排组合从而达到独立、解耦、组件化、易维护、可复用、可替换、高可用的设计原则。微服务后,自动化部署以及运维是比较头疼的事,容器技术解决了这个问题。

  • 好的架构需要考虑后面的扩展以及修改
  • 好的架构是解耦的,需改一个地方不会影响另外一个地方
  • 好的架构是轻便灵活的,一个应用最好只解决一个问题,而不是叠加功能

微服务的标签

  • 单一职责
  • 面向服务
  • 自治
  • 易扩展
  • 流程化

微服务的不足

  • 时效性·服务间的调用延时可能导致系统相应慢的问题
  • 一致性·微服务在保证一致性上需要做更多的工作

微服务的价值

  • 资源价值,资源不足是自动扩容,资源过量时自动缩容;
  • 业务价值,工作量、人员数量、交付质量、交付周期;
  • 技术价值,技术是为业务来服务的(个人标注:技术也是业务的一部分而不只是为业务而服务)
  • 用户价值,用户体验好,服务上线快
  • 未来价值,技术不成为业务的瓶颈

微服务的小目标

  • 持续交付
  • 业务敏捷
  • 独立演进
  • 高可用
  • 高性能

微服务的拆与不拆

依据:数据模型、业务模型、关键指标,粒度平衡,边界合理

DevOPS

开发与运维是一个整体,devops是一种思维方式,微服务与devops是天生一对

SpringCloud特点

  • 功能齐全
  • 标准化
  • 简单方便
  • 按需取用
  • 轻量
  • 易扩展、易维护
  • 可复用性

分布式系统组件及操作

配置管理(Spring cloud config)、服务发现/调用(Feign)、断路器、智能路由(ZUUL)、微代理、控制总线、一次性Token、全局锁、决策竞选、分布式会话、集群状态。

注册中心(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、服务追踪(Sleuth,zipkin)、权限(string security)、接口可视化(Swagger)。

以上内容为《微服务那些事儿》读书笔记。

参考资料

[1]. 微服务那些事儿,纪晓峰著

开篇,马斯克们的Hyperloop

我们先来看张图,下图上部分是现在的高铁,它是跑在露天的轨道上的,下图是Elon Musk’s 在正吹的hyperloop,类似于跑在真空管道里的未来高铁。相比跑在露天轨道里的高铁,跑真空管道里的高铁好处多了:快,节能,安全,比飞机便宜。。。
技术是可以自己进化的,相信类似hyperloop的”高铁+真空管道”的模式就是未来的一种交通出行方式。

hyperloop

那么HYPERLOOP跟本文又有什么关系呢? 是不是有点扯远了?其实本文讲的就是类似给高铁加上真空管道的活,二者本质上是相同的。

管道,Unix/Linux的设计哲学

在Linux或者Unix系统里,有时候我们为了查询某个信息,会输入类似如下的命令行:

1
#cat *.log | grep –v ‘pipeline’ | sort –nr | head –n 10 | tail -5 | awk ‘{print $2}’ | wc –l  > /dev/stdout

这个命令行通过“|”来分隔多个命令,前面命令的输出是紧接着的后面命令的输入,命令之间通过“|”彼此相连,并且一个命令只做一件事情。这里的“|”就是管道,把一个程序的输出和另一个程序的输入连起来的一根管子。

在Unix/Linux里存在这样的管道命令设计哲学:

  • 程序是个过滤器
  • 一个程序只做一件事并且做到最好
  • 一个程序的输入是另外一个程序的输出

下图体现了这样的管道设计哲学,应用之间通过管道相连相互作用:

Uniux/linux pipeline

管道所要解决的问题是:高内聚,低耦合。它以一种“链”的方式将这些程序组合起来,让这些程序组成一条工作流,而每个程序又只作一件事情,给定输入,经过各个程序的先后处理,最终得到输出结果,如下图所示:

Uniux/linux pipeline

Unix/Linux在"每个程序只做一件事并且做好,每个程序的输出是对另一个程序的输入,可组合性"方面是做的非常成功的。但是,UNIX/Linux也存在一些局限性,比如:"仅单机,只支持一对一通信,无容错,仅字节流,数据处理能力有限等"。意思是说 linux/unix的这些管道命令只能在一台机器上跑,没有分布式,并且只能支持一个命令和另外一个命令之间的一对一的输入输出,无法一对多或多对一;无容错,假如管道坏了数据就出错不能恢复;只支持字节流,不支持数据格式的多样性;处理的数据量有限。

因此,我们希望可以找到一个数据处理解决方案,这个方案在保留这些Unix/linux管道的设计哲学优点的同时还能克服其缺点。 幸运的是,我们通过Flink+Pravega打造的第三代“流原生”(stream native)式的大数据处理平台实现了这种设计思想。

流原生,第三代大数据处理平台

下图体现了“流原生”(stream native)式的设计哲学,Flink是“流原生”的计算,Pravega是“流原生”的存储管道,Flink + pravega 是“流原生”的大数据处理平台。数据从pravega管道输入经过map算子计算,输出中间计算结果到pravega的管道里,数据又从pravega的管道里读入到filter算子里,再经过计算,中间结果放到了pravega管道里,再最后的计算结果经过聚合算子的计算放到了目的地的pravega的管道里。这个过程体现了算子编排和管道式编程的设计哲学。在这里pravega起了大数据处理平台里的管道的作用。

Stream processing pipeline

在Unix/Linux中,系统提供管道和命令,用于从一个进程到另一个进程获取字节流。

在“流原生”处理平台上,Flink提供流处理服务,pravega提供流存储服务,数据源自pravega,被Flink算子们处理后输出到pravega,这是一种将事件从一个流处理作业转移到另一个流处理作业的机制。 Flink和Pravega 所遵循的流处理平台设计哲学是:

  • 每个算子都只做一件事,并且做到最好
  • 每个算子的输出是另一个算子的输入
  • 可组合
  • 流式传输:数据是动态的,算子是静态的
  • 算子可编排
  • Pravega是最好的Flink搭档
  • 分布式,扩展到多台机器
  • 可进化的编码/解码

当前的流式处理平台一般是 Flink 加传统的存储类型,这种是”半流原生“式的大数据处理平台,计算是原生的流计算而存储却不是原生的流存储。
而Pravega就是专门给Flink们设计的原生流存储,它的数据传输方式类似于“管道”,不同于传统的块存储,文件存储以及对象存储,它是一个”管道式流存储“。

通过Flink + Pravega的组合可以实现 “流原生”(stream native)式的第三代大数据处理平台,未来已来。。。。。

思考题

最后给大家留个思考题,“流原生”(stream native)的概念有了,Flink + Pravega 也有了,而且二者的代码都是开源的(flink.apache.org, pravega.io),那么怎么把这些开源的东西产品化? 或者这个问题太伤脑筋,我们换个简单的问题:“今天中午吃什么?”

作者简介

常平,毕业于中国科学技术大学,获硕士研究生学历学位,10年+ 存储、布式系统、云计算以及大数据经验,曾就职于Marvell、AMD等,现就职于EMC,资深首席工程师,主要负责流式大数据处理平台的架构设计、编码及产品交付等。

阴阳五行

一说到阴阳五行就容易让人想到大街上的算命先生,然而阴阳五行学说却是中国古代解释世间万物的起源和多样性的哲学理论依据,是中国古代朴素的唯物论和自发的辩证法思想。

中国古代哲学的核心思想之一用“老子”的话来说就是:

“道生一、一生二、二生三、三生万物,万物负阴而抱阳,冲气以为和。”。

而五行学说讲的是:“金 木 水 火 土”这五行,五行相生又相克。木头烧火——木生火;火烧木头成灰——火生土,土长期聚在一起生石头、石头里炼金——土生金,金销水——金生水,水又生土。,水克火,火克金,金克木,木克土,土克水。

但是如下图,五行虽然相生相克但都是为“和”字而服务的,即平衡:

五行

解读开来就是:

“天道生阴阳,阴阳成五行,五行变化成万物,而万物的存在方式和相互关系一直在追求一种“和谐”。“道”在阴阳的相互作用下,产生五行,五行之间相互作用产生世间万物的无穷变化,并且阴阳之间对立消长,五行之间相生相克,自此万物得以和谐发展。借助于阴阳五行的核心要素以及由此而生的非核心要素关系把宇宙看成一个统一的整体,这样的整体:循环平衡、相生相克、有刚有柔、和谐统一

那么这些玄乎的哲学理论跟码农又有什么关系呢?对于本人这么个靠技术混饭吃卖身又卖艺的码农来说,这实在太重要,归纳成一个字就是”和”,对应到技术实现体系里就是一个理念 ”权衡“,英文叫tradeoff“tradeoff”这词实在是太妙了,啥都可以往上套,比如你十一准备到哪旅游啦,中午到哪吃饭啦,买哪里的房子啦,准备追哪个姑娘做老婆啦…….,都需要 tradeoff。技术如此人生又何尝不如是。

分布式系统

通常来讲设计分布式系统的时候需要考虑的最重要的核心要素有五个,这里不是说其他要素就不重要,这是指经过tradeoff过的五个最重要的核心要素,如下图:

分布式系统要素

  1. Capacity,容量,其实这个词翻译成”能力“会更合适,指的是分布式系统里的CPU,内存,硬盘,网络,文件描述符,socket连接数,老板的预期,开发周期,成本预算之类的限制条件,以下所有的要素都受 “容量”的限制,这是前提条件,就比如一辆车最多能跑多快,一个人最多能跳多高都是受自身“容量/能力”的限制的;

  2. Performant, performance + conformant, performant这词也是造的,指的是合适的性能,分布式系统的IOPS,TPS, QPS,Latency,Jitter之类的性能指标要求,性能受限于容量,性能同时又影响了可靠性以及可用性;

  3. Availability,可用性,可用性通常指的是产品或服务在随机时间内调用时处于可服务状态的概率,通常被定义为正常运行时间除以总时间(正常运行时间加停机时间),比如 5个9,6个9,还有个厂家都喜欢的号称的9个9之类的,可用性受容量的限制同时也受可伸缩性的影响,可用性又影响了性能;

  4. Reliability,可靠性,一般指的是出保证不出故障的概率,比如,企业级产品 5个9是保底,可测试性和可维护性通常被定义为可靠性当中的一部分,可伸缩性影响了可靠性,而可靠性又影响了可用性,同时性能又影响了可靠性,可靠性也影响着性能。

  5. Scalability,可伸缩性,这里很容易跟“可扩展性”混淆,可伸缩性可以指的是集群处理越来越多或越来越少的工作的能力,或者是为了适应这种增长或减少而扩大或缩小其能力的能力。可伸缩性影响了可用性,也影响了性能与可靠性,受限于容量。

当然还有另外一些由此而衍生的非核心要素,就不多做详细解释了,比如:

  • Testability,可测试性
  • Security,安全性
  • Observability,可观测性
  • Predictability,可预测性
  • Extensibility,可扩展性
  • Maintainability,可维护性
  • Serviceability, 可服务性

这些非核心要素虽然是非核心但是也不是说就不重要,是开源产品与商业产品差异的关键,关键在如何tradeoff

阴阳五行与分布式系统

将阴阳五行理论与分布式系统设计理论结合起来解读就是:

分布式系统里的“道”就是“产品”,“阴阳“ 就是 ”功能“ 与 “非功能”,五行就是 ”容量、性能、可用性、可伸缩性以及可靠性“,阴阳五行衍生的一些其他关系对应分布式系统五要素衍生的一些其他要素。

用人话来讲就是 开发产品的时候需要考虑功能与非功能两个方面,而要保证产品质量又需要考虑”容量、性能、可用性、可伸缩性以及可靠性“这些核心要素,但是也不能忽略由此而生的一些非核心要素。

那么从这些理论到产品又需要怎么做才能落地呢? 那自然是需要 懂得如何把从这些概念性的、功能的、非功能的、这些核心的、非核心的要素进行设计实现成代码,这就涉及到 “术”的层面了,“道”的层面可以通过看书看论文获得,而“术”的获得除了自身努力还得靠机会,而且每个人的悟性还不一样,这些个”术“以后有空慢慢讲。

思考题

最后给大家留一个思考题: 前面提过老子曰:”道生一、一生二、二生三、三生万物,万物负阴而抱阳,冲气以为和。“, 三之后就是万物,为什么不是 五、不是六、不是七之类的呢?为什么三之后就是万物了?

作者简介

常平,毕业于中国科学技术大学,获硕士研究生学历学位,10年+ 存储、布式系统、云计算以及大数据经验,曾就职于Marvell、AMD等,现就职于EMC,资深首席工程师,主要负责流式大数据处理平台的架构设计、编码及产品交付等。


注:

  1. 这个用五行解释分布式系统的观点,以前在一个业内微信群里提出并且聊过,所以这个解读的方式为本人原创非COPY.
  2. 个人愚钝,悟性有限,欢迎拍砖,砖多了我就拿回去砌墙。

参考资料:

[1]. https://baike.sogou.com/v7556185.htm