云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

负载均衡_阿里云备案变更_返现

小七 141 0

连续应用程序:ApacheSpark2.0中不断发展的流媒体

自发布以来,Spark Streaming已经成为使用最广泛的分布式流引擎之一,这要归功于它的高级API和一次性语义。尽管如此,随着这些类型的引擎变得越来越普遍,我们注意到开发人员需要的不仅仅是一个流式编程模型来构建实时应用程序。在Databricks,我们与成千上万的用户合作,以了解如何简化实时应用程序。在这篇文章中,我们介绍了由此产生的概念,即连续应用程序,我们已经开始通过ApacheSpark2.0中的结构化流式API来实现它。大多数流引擎专注于在流上执行计算:例如,可以映射一个流以在每个记录上运行一个函数,按时间将其缩减为聚合事件,等等。但是,当我们与用户一起工作时,我们发现流引擎的几乎没有用例只涉及在流上执行计算。相反,流处理作为更大的应用程序的一部分发生,我们称之为连续应用程序。以下是一些示例:更新将实时提供服务的数据。例如,开发人员可能希望更新用户将通过web应用程序查询的摘要表。在这种情况下,很大程度上的复杂性在于流引擎和服务系统之间的交互:例如,当流引擎更新表时,您能在表上运行查询吗?"完整"应用程序是一个实时服务系统,而不是流上的映射或reduce。提取、转换和加载(ETL)。一个常见的使用情形是不断地将数据从一个存储系统移动到另一个存储系统(例如,JSON日志到Apache配置单元表)。这需要与两个存储系统进行仔细的交互,以确保没有数据复制或丢失—大部分逻辑都在这项协调工作中。创建现有批处理作业的实时版本。这很困难,因为许多流媒体系统不能保证它们的结果与批处理作业匹配。例如,我们看到一些公司使用流式引擎构建实时仪表板,使用批处理作业构建每日报告,结果客户抱怨他们的每日报告(或者更糟的是,他们的账单!)与实时指标不匹配。在线机器学习。这些连续的应用程序通常将使用批处理作业处理的大型静态数据集与实时数据和实时预测服务相结合。这些示例表明流计算是大型应用程序的一部分,这些应用程序包括服务、存储或批处理作业。不幸的是,在当前的系统中,流计算是在一个只关注流的引擎中运行的。这使得开发人员负责和外部系统交互(例如管理事务)并使其结果和应用程序的其余部分一致(例如,批处理作业)的复杂任务。这就是我们希望通过连续应用程序解决的问题。连续应用我们将连续应用程序定义为对数据进行实时响应的端到端应用程序。特别是,我们希望开发人员使用单一的编程接口来支持当前在独立系统中处理的连续应用程序的方面,例如查询服务或与批处理作业的交互。例如,下面是我们如何处理上述用例:更新将实时提供服务的数据。开发人员可以编写一个同时处理更新和服务的Spark应用程序(例如通过Spark的JDBC服务器),或者使用API在服务系统(如MySQL、Redis或Apache Cassandra)上自动执行事务性更新。提取、转换和加载(ETL)。开发人员只需在批处理作业中列出所需的转换,流式处理系统将处理与两个存储系统的协调,以确保只进行一次处理。创建现有批处理作业的实时版本。流式系统将保证结果始终与同一数据上的批处理作业一致。在线机器学习。机器学习库将被设计成将实时训练、周期性批量训练和预测服务结合在同一API后面。下图显示了流引擎通常处理哪些关注点,以及在连续应用程序中需要哪些关注点:结构化流媒体结构化流是我们为ApacheSpark2.0提供的一个新的高级API,用于支持连续应用程序。首先,它是一个比Spark Streaming更高级别的API,引入了Spark中其他结构化API(数据帧和数据集)的思想,最明显的是,它是一种执行类似数据库的查询优化的方法。然而,更重要的是,结构化流媒体还结合了连续应用程序的思想,以提供许多其他流媒体引擎无法提供的功能。对批处理作业的一致性有很强的保证。用户通过编写批处理计算(使用Spark的DataFrame/Dataset API)来指定流计算,引擎会自动递增该计算(连续运行)。在任何时候,结构化流作业的输出都与在输入数据的前缀上运行批处理作业相同。大多数当前的流媒体系统(例如Apache Storm、Kafka Streams、Google Dataflow和Apache Flink)都不提供这种"前缀完整性"属性。与存储系统的事务性集成。我们在内部设计中注意只处理一次数据并以事务方式更新输出接收器,以便服务应用程序始终可以看到一致的数据快照。虽然Spark 2.0版本只支持少数几个数据源(HDFS和S3),但我们计划在未来的版本中添加更多数据源。事务性更新是Spark和其他流式系统用户的最大痛点之一,需要手动操作,因此我们很高兴将这些更新作为核心API的一部分。与Spark的其他部分紧密结合。结构化流支持使用sparksql和JDBC对流状态进行交互查询,并与MLlib集成。这些集成在Spark 2.0中才刚刚开始,但在将来的版本中会有所增长。因为结构化流是建立在数据帧上的,所以Spark的许多其他库自然会覆盖它(例如,MLlib中的所有特性转换都是针对数据帧编写的)。除了这些独特的特性外,结构化流还有其他简化流式处理的新功能,例如明确支持"事件时间"来聚合无序数据,以及对窗口和会话的更丰富支持。以一种容错的方式实现其一致性语义也不是一件容易的事,请参阅我们关于API和执行模型的姊妹博客文章。在Spark 2.0中,结构化流仍然是alpha版本,但我们希望您尝试一下并发送反馈。我们的团队和许多其他社区成员将在接下来的几个版本中扩展它。一个例子作为结构化流的一个简单示例,下面的代码显示了一个将数据从JSON转换为apacheparquet的提取、转换和加载(ETL)作业。注意结构化流媒体如何简单地使用dataframeapi,因此代码几乎与批处理版本相同。流媒体版本//从S3连续读取JSONlogsDF=spark.readStream.json("s3://日志")//使用数据帧API转换并保存logsDF.select("用户","网址","日期").writeStream.拼花地板("s3://出")。开始()批处理版本//从S3读取一次JSONlogsDF=spark.read.json("s3://日志")//使用数据帧API转换并保存logsDF.select("用户","网址","日期").写作.拼花("s3://出") 虽然代码看似简单,但Spark在幕后做了很多工作,比如将数据分组到拼花分区中,确保每个记录在输出中只出现一次,以及在重新启动作业时恢复作业的状态。最后,为了以交互方式提供这些数据,而不是将其写入Parquet,我们可以将writeStream更改为使用(当前为alpha)内存接收器,并将JDBC客户机连接到Spark来查询它。长期愿景我们对Spark流媒体的长期愿景是雄心勃勃的:我们希望Spark中的每个库都能以渐进的方式处理结构化流。虽然这是一个很大的目标,但apachespark完全有能力实现它。它的库已经建立在通用的、狭窄的api(rdd和dataframe)之上,结构化流的设计是为了提供与这些统一接口一致的结果。Spark自诞生以来最大的见解就是开发人员需要统一的接口。例如,集群上的批处理计算通常需要许多不相交的系统(MapReduce用于ETL,Hive用于SQL,Giraph用于图形等),这使得开发和操作都变得复杂。Spark将这些工作负载统一到一个引擎上,大大简化了这两个任务。同样的见解也适用于流媒体。由于流式工作负载通常是更大的连续应用程序(可能包括服务、存储和批处理作业)的一部分,因此我们希望为构建端到端连续应用程序提供统一的API和系统。阅读更多我们的Structured Streaming model博客文章更详细地探讨了流式API和执行模型。我们建议您阅读这篇文章开始结构化流媒体。此外,以下资源涵盖结构化流媒体:Spark 2.0和结构化流媒体结构化火花:数据帧、数据集和流媒体深入研究结构化流媒体结构化流媒体编程指南 免费试用Databricks。今天就开始吧