本文将带领大家透过现象看本质,掌握高性能、高并发、实时系统设计与权衡之道;

高度抽象出实时流计算系统的技术支撑、架构模式、编程模式、系统实现与协同系统,并从零编写一个分布式实时流计算系统!

 

本文总结了实时流计算系统的通用架构模式。

通过从无到有构建一个流计算编程框架,让读者了解流计算应用计算的任务类型,学会解决计算过程遇到的各种问题和难点。

本文希望让读者领会Java程序开发中“流”这种编程方式的优势和乐趣所在。另外,通过将单节点流计算应用扩展为分布式集群,让读者理解分布式系统的架构模式,并能准确看待开源社区中各种眼花缭乱的流计算框架,看透这些流计算框架的本质,避免选择恐惧症。

本文还探讨了实时流计算能够与不能够解决的问题,让读者对流计算系统的能力了然于胸,不至于钻牛角尖。

总而言之,读者在阅读本文后,能够对实时流计算系统有清晰的认识和理解,在架构设计、系统实现和具体应用方面都能做到心有丘壑,最终做出优秀的实时流计算应用产品。

 

第1章实时流计算;整体而言,本文内容按照“总分”的结构组织。阅读本章,我们对实时流计算系统的使用场景和通用架构组成有了一个整体的了解。在后续的章节中,我们将对实时流计算系统的各个部分进行具体的分析和讨论。

 

第2章数据采集;本章围绕着数据采集模块,详细分析了NIO和异步编程相关的问题。

当读者读到这里的时候可能会感到疑惑,本文的主题是实时流计算,但到目前为止,讨论最多的却是异步和NIO,是不是跑题了?其实不然,“流”与“异步”之间存在千丝万缕的关系,“流”是“异步”的一种重要表现方式,“异步”则是“流”在执行时的内禀性质。现在流式编程越来越流行,一方面是因为“流”本身是对真实世界事件发生过程的自然表示,另一方面则是由于“流”在内部执行时是异步和并行的,能最大限度提高资源使用效率,提高程序执行性能。在前面讲解有关异步编程的内容时,我们已经非常自然地使用诸如“上游”“下游”这些很明显有关“流”的概念了。可以说,理解透彻NIO和异步是编写高性能程序的基础,即使不实现流计算系统,这些知识也会非常有用。以上正是本章如此着重讨论NIO和异步的原因所在。

在接下来的章节中,我们将详细地讲解如何以流的方式来设计和实现金融风控系统中的特征提取模块。在此过程中,我们会更加真切地体会到流和异步这两种编程方式的异曲同工之妙!

 

第3章实现单节点流计算应用;本章通过构建一个单节点的实时流计算框架,分析了流计算中较重要的两个基本组件,即用于传递事件的队列和用于执行计算逻辑的线程。虽然在本文后续的章节中,我们会看到更加复杂的分布式流计算框架,但这改变不了流计算应用的这种基本组成结构。

流计算是异步的系统,所以我们需要严格控制异步系统中各子系统执行步调不一致的问题。为此,我们反复强调了反向压力功能对流计算系统的重要性。只有在内部支持了反向压力功能的流计算应用,才能长期稳定、可靠地运行下去。相比“异步”而言,“流”这种计算模式更加自然地描述了真实世界中事情发生的过程,也更加符合我们在分析业务执行流程时的思维方式。所以,“流”降低了构建异步和高并发系统的难度。

针对流计算应用的优化是非常有意义和价值的事情,这会让我们对自己构建的系统(不管是在业务逻辑上,还是技术细节上)有更加深刻的认识,所以我们必须重视程序优化。

本章构建了特征提取模块的流计算应用框架,但是并没有涉及具体的特征计算。特征计算属于流数据处理的内容,在接下来的章节中,我们将讨论有关流数据处理的方方面面。

 

第4章数据处理;本章从流数据操作、时间维度聚合特征计算、关联图谱特征计算、事件序列分析、模型学习和预测这5个方面讨论了实时流计算系统中数据处理的问题。

总体来说,我们在以后的流计算应用开发过程中,遇到的计算任务大部分会被归于以上5类计算类型。在具体实现各类计算的过程中,我们遇到了各种矛盾,如在关联操作时长周期窗口和受限内存之间的矛盾,在时间维度聚合特征计算时高势数据和有限存储空间之间的矛盾,在关联图谱特征计算时复杂的图计算算法和实时计算之间的矛盾等。最终,我们都通过采取各种优化、权衡或妥协的措施化解了这些矛盾。但由于本书作者的知识范围和能力有限,加上时代和科技也在不停进步,本章介绍的许多解决问题的方法或许并非最优的。读者在以后的开发过程中,不妨以本章的内容作为基础或参考,不断探索出更好的解决实时流计算中数据处理问题的方法。

 

第5章实时流计算的状态管理;本章讨论了实时流计算应用中状态管理的问题。我们将实时流计算应用中的状态分为了流数据状态和流信息状态。

可以说,这两种状态分别从两个不同的维度对流进行管理。流数据状态从时间角度对流进行管理,而流信息状态则从空间角度对流进行管理。流信息状态弥补了流数据状态只是对事件在时间序列上做管理的不足,将流的状态扩展到了任意空间。

将流数据状态和流信息状态这两个概念区分开,会指引我们将流计算应用本身的执行过程和流数据的信息管理机制解耦,这使得实时流计算系统的整体结构更加清晰。如果我们将前者理解为CPU的执行流水线,那么后者就相当于内存。

 

第6章开源流计算框架;除了前面章节介绍的开源流计算框架外,还有很多其他流计算框架或平台,如Akka Streaming、Apache Beam等。这些流计算框架各具特色,例如,Akka Streaming支持丰富灵动的流计算编程API,可谓惊艳卓卓;而Apache Beam则是流计算模式的集大成者,大有准备一统流计算江湖的势头。

目前大多数的流计算框架已经或正计划着支持SQL查询。这是一个非常好的特性,给流计算也添加上了大家都熟悉的操作界面。但是由于本文主要聚焦的是“流”这种计算模式最本质的东西,所以就略去了对SQL这层“皮肤”的讨论。不管怎样,如果SQL非常适合读者的使用场景的话,那么不妨去了解和使用它们。毕竟SQL也会成为未来流计算编程的一种普遍模式。

 

第7章当做不到实时;本章主要讨论了当我们实在不能通过单一的流计算框架来实现计算目标时,采用Lambda架构来间接实现我们的实时计算目标。

Lambda架构是一种构建数据系统的思想,将数据分析的过程定义为在不可变数据集合上的纯函数计算。数据系统的构建过程分成了两步,第一步是收集一批数据形成不可变数据集,第二步是在不可变数据集上进行数据处理和分析。这种数据系统的构建思路,不仅可以应用于离线处理部分,而且可以应用于实时处理部分。离线处理部分和实时处理部分分别衍生出了Lambda架构的批处理层和快速处理层。

 

第8章数据传输;在本章中,我们针对流计算系统中的数据传输,讲述了3种不同功能和角色的消息传递中间件。

其中,Apache Kafka由于其优秀的吞吐能力和流数据存储能力,非常适于承担大数据时代的数据总线角色;RabbitMQ由于遵从AMQP标准实现,数据可靠性更高,实时性更好,并且支持丰富的不同语言客户端,在实时流计算系统中非常适合用做配置总线;Apach.Camel则由于其灵活的路由功能,以及对底层消息中间件和各种数据协议端口的一致性封装,是不错的消息服务层中间件,可以有效管理底层消息中间件。

本章虽然讲解了3个具体的消息中间件,但它们的功能角色是不一样的。笔者更在意的是让读者了解并领悟3种不同角色消息中间件在流计算系统中各自的作用及承担的职责。至于具体的消息中间件,除了本章讲解的3种消息中间件外,其实还有很多种,如ZeroMQ、ActiveMQ、Apache RocketMQ及Apach.PulsarApache Kafka查阅相关资料。

 

第9章数据存储;本章讨论了实时流计算系统涉及的各种数据存储问题。

其实不仅仅在实时流计算系统中,几乎在任何相对复杂的系统中,数据存储方案的设计都是非常重要的事情。如果数据存储方案设计不当,当系统中的数据积累到一定量后,必然会造成服务时延增大,最终导致服务不可用。一般这个时候,由于系统已经具有了相当规模的数据和状态,任何修复和改动操作都将变得费时费力,甚至只能暂停业务,离线解决问题。

 

第10章服务治理和配置管理;本章主要讨论了服务治理和动态配置的问题。

之所以要讨论这两个流计算系统主体之外的问题,是因为我们为解决具体业务问题而构建的系统是一个有机的整体,而绝非只有一个流计算应用。即使以实时流计算应用为核心,如果其与周边系统集成得不好,这也会让我们后续的开发、运维及产品迭代变得困难重重。

 

第11章实时流计算应用案例;本章使用两个实时流计算应用案例对前面章节中的零碎知识点进行了汇总,目的是让读者能够在这两个案例中更加清晰地了解这些知识点在流计算系统中扮演的角色及所处的位置。

我们使用CompletableFuture框架实现的带DSL使用界面的特征引擎,是一个针对数据流进行特征提取的通用工具。虽然这个工具还比较简陋,但是它代表了构建一个特征引擎的通用组成模式。例如,我们可以将执行计划执行层用Flink来替换自己实现的流计算框架,那么就可以弥补自己构建的这个轮子的诸多缺陷,如事件处理顺序的保证、对故障恢复后状态一致性的保障、更灵活的资源调度和更方便的分布式状态管理等。

 

这份【实时流计算系统设计与实现】 文档共有418页,因为文章内容的限制,小编在这里就不多做介绍了,需要完整版的小伙伴,可以转发此文关注小编,扫码下方来获取!!

读者对象

本文主要适合于以下读者:

  • Java软件开发人员;
  • 实时计算工程师和架构师;
  • 分布式系统工程师和架构师。