首页>参考读物>计算机科学与技术>软件与程序设计

实时流计算系统设计与实现
作者 : 周爽 著
丛书名 : 架构师书库
出版日期 : 2020-01-08
ISBN : 978-7-111-64580-1
定价 : 79.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 238
开本 : 16
原书名 :
原出版社:
属性分类: 店面
包含CD : 无CD
绝版 : 未绝版
图书简介

全书分为11章。第1章介绍了实时流计算技术的产生背景、使用场景和通用架构。第2章通过实时流计算数据的采集,详细分析了Java高性能编程的理论基础。第3-6章通过从头构造一个分布式实时流计算框架,详细剖析了实时流计算中的几个核心概念和技术重点,并通过多个开源流计算平台的实现来验证这些核心概念和技术重点。第7章谈论了当实在做不到“实时”时,我们应该作出的备选方案。第8-10章阐述了构建一个完整实时流计算系统时,必要的周边辅助系统。第11章给出实时流计算应用案例。

图书特色

透过现象看本质,掌握高性能、高并发、实时系统设计与权衡之道
高度抽象出实时流计算系统的技术支撑、架构模式、编程模式、系统实现与协同系统,并从零编写一个分布式实时流计算系统

图书前言

为什么要写这本书
大概但凡写文章,都应该是在夜深人静的时候吧。
回顾来沪四年,思绪一下子回到了到沪的第一天。那是我第一次来上海。虽然没有小马哥勇闯上海滩的豪情万丈,但似乎也并未十分惆怅。拖着行李箱去新公司报到,当时住的地方尚未找好,新公司的名字竟也还未确定。报到的新公司,真的是一家“新”公司,刚刚成立不久,办公室在一个略显陈旧的大楼内,后来才知道那个办公室内还有另外一个公司的人员在那儿办公。当时辉哥接待了我,交给我一个Mac电脑,给我讲了一下公司的业务和系统现状。那是我第一次使用Mac电脑,操作还十分生疏。而现在,我正用着这台电脑,写着这篇自序(前言)。后来海阳到了,他给我展示和讲解了公司当时的产品。再后来,他还教了我怎样用Mac电脑。下午的时候我提前下班,拖着行李箱找住的地方去了。那天,当忙完一切躺到床上时,我意识到一切真的都是新的开始了。新的城市、新的公司、新的同事、新的业务、新的领域和新的工作内容。
之后就是正式的工作了。
因为是做Java开发的,所以花一天半时间学了Django,之后接手了Python后台开发。
因为是做Java开发的,所以花一天时间装了Android Studio,开始了SDK与后台的适配。
因为是做Java开发的,所以Java后台服务更是当仁不让了。
因为是做Java开发的,所以也要负责业务核心算法的开发。
因为是做Java开发的,所以DevOps也得负责推进吧。
因为是做Java开发的,所以……
那应该是我最专心地做开发的一段时间,甚至在一年之后的公司年会上,我还因此获得了一个“最佳沉默奖”。其实并非我不说话,而是每次市场部的同事看到我时,我都是在座位上写程序,好像我从来没离开过座位一样。是的,我一直在开发着,但是并不感到忙碌和紧迫,因为有充足的时间去思考问题、验证猜想并最终解决问题。
从2015年开始,公司因为业务需要,开始涉及实时流计算领域。当时流计算技术远非像现在这样普及,Flink还没有在国内流行起来,Spark Streaming处于“半吊子”状态,Storm则还是简单的TopologyBuilder。不过最主要的问题还是,虽然当时公司意识到要使用实时流计算技术,但没有人真正理解实时流计算系统到底该怎么用,应该怎样将流计算真正贴切地运用到我们的业务需求中。
在这种情况下,作为后台开发的我开始了自己的思考和探索。其实解决问题的思路非常简单,用最自然、最贴切、最实际、最节省资源的方式去解决真实的业务问题。最开始,我们选择Akka来作为流计算框架,但是因为对Akka的特性理解不到位,后来开发出的程序出现各种问题。例如,在Actor中光明正大地休眠(sleep)、对反向压力不管不顾,结果程序总是时不时宕掉、错误使用Akka Cluster导致集群脑裂等。
在程序开发过程中,我是一个谨小慎微的人,对于任何不确定性的因素,只要想到了就一定会尽力去避免,即使当时其他人不甚理解。所以从一开始,我就在自己负责的模块中,对Akka添加了反向压力的支持,就是为了避免执行步调不一致时导致的OOM。从后来的结果看,当时的做法是非常正确的。虽然在Akka中添加了反向压力的支持,但回看起来,实现得过于复杂。虽然保证了反向压力带来的程序稳定性,可是在50行的代码中,只有1行代码是涉及业务处理的。这种解决方案显然非常不明智。
当时,我还在极力尝试尽可能提高程序的性能,希望充分“榨干”机器的CPU和I/O资源,以尽可能降低硬件成本。经过一段时间的调研和思考,我逐渐发现,NIO和异步才是彻底“榨干”CPU与I/O资源的关键所在。虽然纤程(或协程)也是一种充分利用资源的完美手段,但可惜当时JVM领域尚无一个公开好用的完美纤程实现方案。
那时候,我开始隐隐约约地意识到,似乎“流”是一种非常好的编程模式。
首先,“流”与“异步”不谋而合。“流”的各个节点通过队列传递消息,不同节点的执行正好就是完全异步的。另外,由于队列隔离,不同节点的执行完全不用考虑并发安全的问题。
其次,如果“流”的执行节点间使用的是阻塞队列,那么整个流的各个执行环节就天然地带有了反向压力能力,不需要像之前在Akka中那样非常复杂的实现。
再次,“流”能够非常自然地描述业务执行的流程。不管是大到整个产品线的各个服务模块,还是小到每个服务模块中的具体实现步骤,就像“分形”一样,“流”能够做任意细粒度的划分。这是一种非常普遍的描述事情发生过程的模式。
最后,通过Kafka这种消息中间件的隔离,我可以非常清晰地定义好自己负责开发模块的责任边界,与其他同事的程序隔离开来,避免纠缠不清。当然,这是一种自私的想法,但是从设计模式高内聚、低耦合的角度来看,这又何尝不是一种非常不错的实践呢?更何况Kafka这种好用到“爆”的消息队列,真的是让人爱不释手!
于是,说干就干,我花了一个周末的时间,编写了第一个版本的流计算框架。之后又经过几次大大小小的调整和改进,最终,这个流计算框架进入了公司所有产品的主要业务模块中。再后来,我又在这个流计算框架上开发了一个特征引擎,支持DSL和脚本,可以非常灵活、方便、快速地在流数据上即写即算地实现各种特征计算。所有特征计算都是并发处理,并且自动解析特征依赖与优化执行过程,可以说还是有一丁点儿小小的惊艳了。
4年的时光转瞬即逝。其实这4年还有太多太多的事情,从后台到前端、从开发到运维、从数据到系统、从服务器到嵌入式,编写程序、负责项目、担任架构师,一路走来,我有太多的收获,也有太多的感触。所以,我希望赶在而立之年前,对自己的这些收获和感触做一个总结,一方面是给自己人生阶段的交代,另一方面希望这些经验能够给后来的开发者带来些许帮助。
读者对象
本书主要适合于以下读者:
Java软件开发人员;
实时计算工程师和架构师;
分布式系统工程师和架构师。
本书特色
本书总结了实时流计算系统的通用架构模式。通过从无到有构建一个流计算编程框架,让读者了解流计算应用计算的任务类型,学会解决计算过程遇到的各种问题和难点。本书希望让读者领会Java程序开发中“流”这种编程方式的优势和乐趣所在。另外,通过将单节点流计算应用扩展为分布式集群,让读者理解分布式系统的架构模式,并能准确看待开源社区中各种眼花缭乱的流计算框架,看透这些流计算框架的本质,避免选择恐惧症。本书还探讨了实时流计算能够与不能够解决的问题,让读者对流计算系统的能力了然于胸,不至于钻牛角尖。总而言之,读者在阅读本书后,能够对实时流计算系统有清晰的认识和理解,在架构设计、系统实现和具体应用方面都能做到心有丘壑,最终做出优秀的实时流计算应用产品。
如何阅读本书
首先需要澄清的是,本书的“非目标”是什么:
各种流计算框架实战,诸如教读者如何使用Storm、Spark、Flink等流计算框架。笔者相信,针对每一种具体的流计算框架已经有许多优秀的书籍了。如果笔者再讲,就是不自量力、班门弄斧、狗尾续貂了。
澄清了本书的“非目标”,就可以定义本书的“目标”了:
总结实时流计算系统的通用架构模式。所谓架构模式,是一种“形而上”的东西,也就是所谓的“道”。实时流计算系统体现出的软件设计之“道”,是笔者试图阐述的东西。
从无到有构建一个“麻雀虽小,五脏俱全”的单节点实时流计算框架。通过这个造轮子的过程,我们会深入理解流计算系统中最本质、最困难、最容易混淆的概念。之后通过在多种开源流计算框架中多次验证这些概念,实现“道”向“形而
下”的具象,让我们以后面对各种流计算框架时,都能够做到胸有成竹。
通过将单节点的实时流计算框架扩展为分布式实时流计算框架,让读者理解多种不同的分布式系统构建模式。
通过“流”这种异步编程模式,让读者理解并掌握编写高性能程序的编程之道,领略Java高并发编程的乐趣。
不仅探讨实时流计算能够解决的问题,而且要明白当实在做不到“实时”时该如何进行架构设计。
尽可能全面覆盖一个完整的实时流计算系统,包括许多周边系统,如存储系统、服务治理和配置管理等。如果这些“绿叶”点缀得不好,有时也会给实时流计算系统带来不利影响。
整体而言,本书的内容按照“总分”的结构组织。全书分为11章。
第1章介绍实时流计算技术的产生背景、使用场景和通用架构。
第2章通过实时流计算数据的采集,详细分析Java平台NIO和异步编程的基础,并初步讨论了“异步”和“流”这两种编程模式之间的关系。
第3~5章通过从零开始构造分布式实时流计算应用,详细剖析了实时流计算系统的计算任务类型、核心概念和技术关键点。
第6章通过多种开源流计算框架,验证第3~5章所讨论的实时流计算系统核心概念和技术关键点。
第7章讨论当实在做不到“实时”时,我们应该做出的备选方案。
第8~10章讨论构建完整实时流计算系统时必要的周边辅助系统。
第11章详细讨论两个实时流计算应用的具体案例。
另外,本书包含许多示例代码,但由于篇幅有限,这些代码不能完全展现在书中。读者可从GitHub仓库(https://github.com/alain898/real_time_stream_computing_book_source_code)获取本书完整的配套源代码。
勘误和支持
由于笔者水平有限,编写时间仓促,书中难免有一些错误或者不准确的地方,恳请读者批评指正。大家可以通过电子邮箱347041583@qq.com联系笔者。期待得到大家的真挚反馈,在技术之路上互勉共进。
致谢
首先要感谢来沪四年遇到的许多同事,辉哥、海阳、克克、波叔、Lex、沛沛、亘哥、佳哥、牙膏、Kevin、军军、建军、叶晗、Mike、国聪、俊华、培良、凯哥、国圣、志源、顾大神、渊总、荣哥、君姐、Vivi姐及其他更多同事,我从你们身上学到了太多太多,这些知识会让我受用终身!
感谢挚友飞哥、乔姐和Lisa,是你们让我在沪四年不再有漂泊感。
感谢机械工业出版社华章分社的高婧雅编辑,给予这本书出版的机会,并在写作期间一直给予我支持和鼓励,并引导我顺利完成全部书稿。
最后感谢我的爸爸、妈妈、弟弟、三叔、四叔、小姨、爷爷和奶奶,感谢你们伴随我成长。虽然很多话我说不出口,但我是在乎你们的!
谨以此书献给我最亲爱的家人,以及众多热爱Java的朋友们!

周爽
2019年10月

上架指导

计算机\分布式

封底文字

阅读了本书的第3~5章,作者用深入浅出的语言辅以代码,带读者了解流式系统的内部实现。例如,如何实现常用的流式算子,如何对流式计算进行状态管理。我认为非常有特色的地方是,作者在所有章节中都给出了大量代码示例来帮助理解。作者先通过从零实现简单的流式计算节点(并结合Java的CompletableFuture来增加更多功能)而非直接参考开源框架实现,这更能让读者理解流式计算的基本原理。在介绍流式计算算子的章节中,也结合实际应用带领读者理解如何组合不同的基本算子来实现复杂的业务逻辑,如时间维度/关系图谱特征提取及一些统计模型。相信对于使用过流式系统,并且想要知其所以然的读者会很有帮助。
——顾仲贤,北美某互联网公司技术负责人(Tech Lead)
刚看到这本书的书名时我以为又是一本对某个开源流计算框架的技术解读书籍。但看完整本书之后,我发现作者选择了一个很不错的方向:向读者介绍如何从0到1地构建一个实时流计算系统;当我们在原型系统上需要某个特性(比如状态管理)时,作者又能够适时地将相关的知识点阐述到位。整个过程自然流畅,过渡得相当平滑。除此之外,书中介绍了当下开源界的一些主流的流计算框架。无论是设计、实现的细节层面,还是业界框架、架构层面上都覆盖得比较全面。无论是那些刚刚接触实时流计算,还是已经在流计算领域深耕多时的研发人员,我相信这本书都有比较好的阅读价值和借鉴意义。
——杨华,前腾讯高级工程师(Flink引擎核心研发)、某出行公司大数据基础平台负责人

图书目录

前言
第1章 实时流计算 …… 1
1.1 大数据时代的新挑战:实时流计算 …… 1
1.2 实时流计算使用场景 …… 2
1.3 实时流数据的特点 …… 4
1.4 实时流计算系统架构 …… 6
1.4.1 数据采集 …… 6
1.4.2 数据传输 …… 7
1.4.3 数据处理 …… 8
1.4.4 数据存储 …… 8
1.4.5 数据展示 …… 9
1.5 本章小结 …… 10
第2章 数据采集 …… 11
2.1 设计数据采集的接口 …… 11
2.2 使用Spring Boot实现数据采集服务器 …… 12
2.3 BIO与NIO …… 14
2.3.1 BIO连接器 …… 14
2.3.2 NIO连接器 …… 17
2.4 NIO和异步 …… 19
2.4.1  CPU密集型任务 …… 19
2.4.2 I/O密集型任务 …… 20
2.4.3 I/O和CPU都密集型任务 …… 21
2.4.4 纤程 …… 22
2.4.5 Actor …… 24
2.4.6 NIO配合异步编程 …… 25
2.5  使用Netty实现数据采集服务器 …… 26
2.5.1 使用Netty实现数据采集API …… 27
2.5.2 异步编程 …… 29
2.5.3 流量控制和反向压力 …… 31
2.5.4 实现反向压力 …… 32
2.5.5 异步的不足之处 …… 36
2.6 本章小结 …… 36
第3章 实现单节点流计算应用 …… 38
3.1 自己动手写实时流计算框架 …… 38
3.1.1 用DAG描述流计算过程 …… 38
3.1.2 造一个流计算框架的轮子 …… 39
3.1.3 实现特征提取DAG节点 …… 42
3.1.4 实现特征提取DAG拓扑 …… 45
3.2 CompletableFuture方法与原理 …… 46
3.2.1 常用的CompletableFuture类方法 …… 47
3.2.2 CompletableFuture的工作原理 …… 49
3.3 采用CompletableFuture实现单节点流处理 …… 51
3.3.1 基于CompletableFuture实现流计算应用 …… 51
3.3.2 反向压力 …… 53
3.3.3 死锁 …… 54
3.3.4 再论流与异步的关系 …… 55
3.4 流计算应用的性能调优 …… 56
3.4.1 优化机制 …… 56
3.4.2 优化工具 …… 56
3.4.3 线程状态 …… 62
3.4.4 优化方向 …… 66
3.5 本章小结 …… 67
第4章 数据处理 …… 68
4.1 流计算到底在计算什么 …… 68
4.2 流数据操作 …… 70
4.2.1 过滤 …… 70
4.2.2 映射 …… 70
4.2.3 展开映射 …… 71
4.2.4 聚合 …… 72
4.2.5 关联 …… 73
4.2.6 分组 …… 75
4.2.7 遍历 …… 75
4.3 时间维度聚合特征计算 …… 76
4.4 关联图谱特征计算 …… 78
4.4.1 一度关联 …… 79
4.4.2 二度关联 …… 81
4.5 事件序列分析 …… 85
4.5.1 CEP编程模式 …… 86
4.5.2 Flink CEP实例 …… 87
4.6 模型学习和预测 …… 89
4.6.1 统计学习模型 …… 90
4.6.2 P-value检验 …… 90
4.6.3 机器学习模型 …… 91
4.7 本章小结 …… 93
第5章 实时流计算的状态管理 …… 94
5.1 流的状态 …… 94
5.1.1 流数据状态 …… 96
5.1.2 流信息状态 …… 97
5.2 采用Redis实现流信息状态管理 …… 98
5.2.1 时间维度聚合特征计算 …… 98
5.2.2 一度关联特征计算 …… 99
5.3 采用Apache Ignite实现流信息状态管理 …… 100
5.3.1 时间维度聚合分析 …… 101
5.3.2 一度关联特征计算 …… 103
5.4 扩展为集群 …… 105
5.4.1 基于Redis的状态集群 …… 106
5.4.2 局部性原理 …… 106
5.4.3 批次请求处理 …… 108
5.4.4 基于Apache Ignite的状态集群 …… 109
5.4.5 基于分布式文件系统的状态管理集群 …… 109
5.5 本章小结 …… 110
第6章 开源流计算框架 …… 111
6.1 Apache Storm …… 112
6.1.1 系统架构 …… 112
6.1.2 流的描述 …… 113
6.1.3 流的执行 …… 113
6.1.4 流的状态 …… 116
6.1.5 消息传达可靠性保证 …… 116
6.2 Spark Streaming …… 117
6.2.1 系统架构 …… 117
6.2.2 流的描述 …… 117
6.2.3 流的执行 …… 118
6.2.4 流的状态 …… 119
6.2.5 消息传达可靠性保证 …… 120
6.3 Apache Samza …… 120
6.3.1 系统架构 …… 120
6.3.2 流的描述 …… 121
6.3.3 流的执行 …… 123
6.3.4 流的状态 …… 126
6.3.5 消息传达可靠性保证 …… 126
6.4 Apache Flink …… 127
6.4.1 系统架构 …… 127
6.4.2 流的描述 …… 128
6.4.3 流的执行 …… 128
6.4.4 流的状态 …… 130
6.4.5 消息传达可靠性 …… 131
6.5 本章小结 …… 132
第7章 当做不到实时 …… 133
7.1 做不到实时的原因 …… 133
7.2 Lambda架构 …… 134
7.2.1 数据系统和Lambda架构思想 …… 135
7.2.2 Lambda架构 …… 135
7.2.3 Lambda架构在实时流计算中的运用 …… 137
7.3 Kappa架构与架构实例 …… 138
7.3.1 Kappa架构 …… 138
7.3.2 Kappa架构实例 …… 140
7.4 本章小结 …… 143
第8章 数据传输 …… 144
8.1 消息中间件 …… 144
8.1.1 为什么使用消息中间件 …… 145
8.1.2 消息中间件的工作模式 …… 146
8.1.3 消息模式 …… 147
8.1.4 使用消息中间件的注意事项 …… 149
8.2 Apache Kafka …… 150
8.2.1 Kafka架构 …… 150
8.2.2 Kafka生产者 …… 152
8.2.3 Kafka消费者 …… 154
8.2.4 将Kafka用于数据总线 …… 156
8.3 RabbitMQ …… 157
8.3.1 RabbitMQ架构 …… 157
8.3.2 RabbitMQ的使用 …… 158
8.3.3 将RabbitMQ用于配置总线 …… 160
8.4 Apache Camel …… 161
8.4.1 使用Apache Camel集成系统 …… 162
8.4.2 使用Apache Camel管理流数据路由 …… 163
8.5 本章小结 …… 166
第9章 数据存储 …… 167
9.1 存储的设计原则 …… 167
9.2 点查询 …… 169
9.2.1 数据灵活性 …… 170
9.2.2 MongoDB数据库 …… 171
9.2.3 数据过期和按时间分表 …… 172
9.3 Ad-Hoc查询 …… 174
9.3.1 倒排索引 …… 175
9.3.2 ElasticSearch …… 176
9.3.3 分索引存储 …… 177
9.4 离线分析 …… 178
9.4.1 存储 …… 179
9.4.2 处理和分析 …… 182
9.4.3 调度 …… 183
9.5 关系型数据库查询 …… 185
9.6 本章小结 …… 186
第10章 服务治理和配置管理 …… 188
10.1 服务治理 …… 188
10.1.1 流服务和微服务 …… 188
10.1.2 微服务框架Spring Cloud …… 190
10.2 面向配置编程 …… 195
10.2.1 面向配置编程思想 …… 195
10.2.2 更高级的配置:领域特定语言 …… 196
10.3 动态配置 …… 196
10.4 将前端配置与后端服务配置隔离开 …… 201
10.5 本章小结 …… 202
第11章 实时流计算应用案例 …… 204
11.1 实时流数据特征提取引擎 …… 204
11.1.1 流数据特征提取引擎DSL定义 …… 204
11.1.2 实现原理 …… 208
11.1.3 具体实现 …… 210
11.2 使用Flink实现风控引擎 …… 216
11.2.1 实现原理 …… 217
11.2.2 具体实现 …… 218
11.3 本章小结 …… 225

教学资源推荐
作者: 郑阿奇 梁敬东
作者: 哈罗德·阿贝尔森(Harold Abelson)[美] 杰拉尔德•杰伊·萨斯曼(Gerald Jay Sussman) 著朱莉·萨斯曼(Julie Sussman)
作者: 刘振安
参考读物推荐
作者: [美] 吉米·宋(Jimmy Song)著
作者: 王哲 张良均 李国辉 卢军 梁晓阳 著
作者: IBM公司