随着诸如Apache Flink,Apache Spark,Apache Storm之类的开源框架以及诸如Google Dataflow之类的云框架的增多,建立实时数据处理做业变得很是容易。这些API定义明确,而且诸如Map-Reduce之类的标准概念在全部框架中都遵循几乎类似的语义。数据库
可是,直到今天,实时数据处理领域的开发人员都在为该领域的某些特性而苦苦挣扎。所以,他们在不知不觉中建立了一条路径,该路径致使了应用程序中至关常见的错误。服务器
让咱们看一下在设计实时应用程序时可能须要克服的一些陷阱。网络
源生成数据的时间戳称为“ 事件时间”,而应用程序处理数据的时间戳称为“ 处理时间”。在实时数据流应用程序中,最多见的陷阱是没法区分这些时间戳。并发
让咱们详细说明一下。框架
因为诸如代理中的GC较高或太多数据致使背压之类的多个问题,数据队列易出现延迟。我将事件表示为(E,P),其中E是事件时间戳(HH:MM:SS格式),P是处理时间戳。在理想世界中,E == P,但这在任何地方都不会发生。分布式
假设咱们收到如下数据函数
('05:00:00','05:00:02'),('05:00:01','05:00:03'),('05:00:01','05:00: 03'),('05:00:01','05:00:05'), ('05:00:02','05:00:05'),('05:00:02',' 05:00:05')
如今,咱们假设有一个程序能够计算每秒接收到的事件数。根据事件时间,程序返回微服务
[05:00:00,05:00:01)= 1 [05:00:01,05:00:02)= 3 [05:00:02,05:00:03)= 2
可是,基于处理时间,输出为工具
[5时○○分00秒,5点00分01秒)= 0 [5点00分01秒,5点00分02秒)= 0 [5点00分02秒,5时00分03秒)= 1 [05:00: 03,05:00:04)= 2 [05:00:04,05:00:05)= 0 [05:00:05,05:00:06)= 3
如您所见,这两个都是彻底不一样的结果。设计
大多数实时数据应用程序使用来自分布式队列的数据,例如Apache Kafka,RabbitMQ,Pub / Sub等。队列中的数据由其余服务生成,例如消费者应用程序的点击流或数据库的日志。
问题队列容易受到延迟的影响。即便在几十毫秒内,生成的事件也可能到达您的工做中,或者在最坏的状况下可能会花费一个多小时(极高的背压)。因为如下缘由,数据可能会延迟:
假设数据将永远不会延迟是一个巨大陷阱。开发人员应始终具备测量数据延迟的工具。例如,在Kafka,您应该检查偏移量滞后。
您还应该监视做业中的背压以及延迟(即事件时间与处理时间之间的差)。没有这些将致使数据意外丢失,例如10分钟。时间窗口彷佛没有数据,而且窗口显示10分钟。以后,其指望值将是预期值的两倍。
在批处理数据处理系统中,将两个数据集合并起来比较简单。在流处理世界中,状况变得有些麻烦。
//数据集的格式为(时间戳,键,值) //数据组1 (05:00: 00,A,值A), (05:00: 01,B,值B),(05:00: 04,C,值C),(05:00:04,D,值D) //数据流2 (05:00:00,A,值A'),(05:00:02,B,值B' ), (05:00:00,C,值C')
如今,咱们将两个数据流都放在它们的Key上。为简单起见,咱们将进行内部联接。
Key A — 值A和值A'都同时到达。所以,咱们能够轻松地将它们组合为一个函数并发出输出
Key B — 值B比值B`早1秒。所以,咱们须要在数据流1上等待至少1秒钟,才能使链接正常工做。所以,您须要考虑如下内容-
Key C —值C比值C'晚4秒钟到达。这与之前相同,可是如今您在数据流1和2中都具备不规则的延迟,而且没有固定的模式将其值设为1。
Key D —值D到达,可是没有观察到值D'。考虑如下-
以上全部问题的答案将取决于您的用例。重要的是要考虑全部这些问题,而不是忽略流系统的复杂性。
必定要注意 不要回避这些问题
在标准微服务中,配置位于做业内部或数据库中。您能够在数据流应用程序中执行相同的操做。可是,在继续使用此方法以前,您须要考虑如下事项。
若是须要为每一个事件访问配置,而且事件数量不少(超过一百万RPM),那么您也能够尝试其余方法。一种是将配置存储在做业状态中。这可使用状态处理在Flink和Spark中完成。可使用文件读取器或Kafka中的其余流以状态填充该配置。
在流处理世界中,针对每一个事件进行数据库调用可能会使您的应用程序变慢并致使背压。选择是使用快速数据库,仍是经过在应用程序内部存储状态来消除网络调用。
若是配置很大,则仅当配置能够拆分到多个服务器时才应使用应用程序内状态,例如,一个配置为每一个用户保留一些阈值。能够基于用户ID密钥将这样的配置拆分到多台计算机上。这有助于减小每台服务器的存储量。
若是没法在节点之间拆分配置,请首选数据库。不然,全部数据将须要路由到包含配置的单个服务器,而后再次从新分发。惟一包含配置的服务器充当该方案的瓶颈。
设计实时数据流应用程序彷佛很容易,可是开发人员会犯不少上述错误,特别是若是它们来自微服务领域。
重要的部分是了解数据流的基础知识以及如何处理单个流,而后转处处理多个联接,实时配置更新等的复杂应用程序。
更多实时数据分析相关博文与科技资讯,欢迎关注 “实时流式计算”