Kafka Streams实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-08-13 05:56:48

点击下载

作者:(美)小威廉·P. 贝杰克(William P. Bejeck Jr.)

出版社:人民邮电出版社有限公司

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Kafka Streams实战

Kafka Streams实战试读:

前言

在我作为软件开发人员期间,我有幸在一些令人兴奋的项目上使用了当前软件。起初我客户端和后端都做,但我发现我更喜欢后端开发,因此我扎根于后端开发。随着时间的推移,我开始从事分布式系统相关的工作,从Hadoop开始(那时还是在1.0版本之前)。快进到一个新项目,我有机会使用了Kafka。我最初的印象是使用Kafka工作起来非常简单,也带来很多的强大功能和灵活性。我发现越来越多的方法将Kafka集成到交付项目数据中。编写生产者和消费者的代码很简单,并且Kafka提升了系统的性能。

然后我学习Kafka Streams相关的内容,我立刻意识到:“我为什么需要另一个从Kafka读取数据的处理集群,难道只是为了回写?”当我查看API时,我找到了我所需的流式处理的一切——连接、映射值、归约以及分组。更重要的是,添加状态的方法比我在此之前使用过的任何方法都要好。

我一直热衷于用一种简单易懂的方式向别人解释概念。当我有机会写关于Kafka Streams的书时,我知道这是一项艰苦的工作,但是很值得。我希望为本书付出的辛勤工作能证明一个事实,那就是Kafka Streams是一个简单但优雅且功能强大的执行流式处理的方法。资源与支持

本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。配套资源

本书提供源代码下载,要获得以上配套资源,请在异步社区本书页面中点击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。提交勘误

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,点击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。与我们联系

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/ selfpublish/submission即可)。

如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。关于异步社区和异步图书“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。异步社区微信服务号致谢

首先,我要感谢我的妻子Beth,感谢她在这一过程中给予我的支持。写一本书是一项耗时的任务,没有她的鼓励,这本书就不会完成。Beth,你太棒了,我很感激你能成为我的妻子。我也要感谢我的孩子们,他们在大多数周末都忍受整天坐在办公室里的爸爸,当他们问我什么时候能写完的时候,我总模糊地回答“很快”。

接下来,我要感谢Kafka Streams的核心开发者Guozhang Wang、Matthias Sax、Damian Guy和Eno Thereska。如果没有他们卓越的洞察力和辛勤的工作,就不会有Kafka Streams,我也就没机会写这个颠覆性的工具。

感谢本书的编辑,Manning出版社的Frances Lefkowitz,她的专业指导和无限的耐心让写书变得很有趣。我还要感谢John Hyaduck提供的准确的技术反馈,以及技术校对者Valentin Crettaz对代码的出色审查。此外,我还要感谢审稿人的辛勤工作和宝贵的反馈,正是他们使本书更高质量地服务于所有读者,这些审稿人是Alexander Koutmos、Bojan Djurkovic、Dylan Scott、Hamish Dickson、James Frohnhofer、Jim Manthely、Jose San Leandro、Kerry Koitzsch、László Hegedüs、Matt Belanger、Michele Adduci、Nicholas Whitehead、Ricardo Jorge Pereira Mano、Robin Coe、Sumant Tambe和Venkata Marrapu。

最后,我要感谢Kafka的所有开发人员,因为他们构建了如此高质量的软件,特别是Jay Kreps、Neha Narkhede和Jun Rao,不仅是因为他们当初开发了Kafka,也因为他们创办了Confluent公司——一个优秀而鼓舞人心的工作场所。关于作者

William P. Bejeck Jr.(本名Bill Bejeck),是Kafka的贡献者,在Confluent公司的Kafka Streams团队工作。他已从事软件开发近15年,其中有6年专注于后端开发,特别是处理大量数据,并在数据提炼团队中,使用Kafka来改善下游客户的数据流。他是Getting Started with Google Guava(Packt,2013)的作者和“编码随想”(Random Thoughts on Coding)的博主。关于本书

我写本书的目的是教大家如何开始使用Kafka Streams,更确切地说,是教大家总体了解如何进行流式处理。我写这本书的方式是以结对编程的视角,我假想当你在编码和学习API时,我就坐在你旁边。你将从构建一个简单的应用程序开始,在深入研究Kafka Streams时将添加更多的特性。你将会了解到如何对Kafka Streams应用程序进行测试和监控,最后通过开发一个高级Kafka Streams应用程序来整合这些功能。读者对象

本书适合任何想要进入流式处理的开发人员。虽然没有严格要求,但是具有分布式编程的知识对理解Kafka和Kafka Streams很有帮助。Kafka本身的知识是有用的,但不是必需的,我将会教你需要知道的内容。经验丰富的Kafka开发人员以及Kafka新手将会学习如何使用Kafka Streams开发引人注目的流式处理应用程序。熟悉序列化之类的Java中、高级开发人员将学习如何使用这些技能来构建Kafka Streams应用程序。本书源代码是用Java 8编写的,大量使用Java 8的lambda语法,因此具有lambda(即使是另一种开发语言)程序的开发经验会很有帮助。本书组织结构:路线图

本书有4部分,共9章。第一部分介绍了一个Kafka Streams的心智模型,从宏观上向你展示它是如何工作的。以下章节也为那些想学习或想回顾的人提供了Kafka的基础知识。● 第1章介绍流式处理如何以及为何成为处理大规模实时数据的必

需方式的历史,并提出Kafka Streams的心智模型,没有详细介

绍任何代码,而是描述Kafka Streams是如何工作的。● 第2章为Kafka新手介绍一些Kafka入门知识。Kafka经验丰富的读

者可以跳过这一章,直接进入Kafka Streams。

第二部分继续讨论Kafka Streams,从基础API开始,一直到更复杂的特性,第二部分各章介绍如下。● 第3章介绍一个Hello World应用程序,然后介绍一个更实际的应

用程序示例——为虚构的零售商开发应用程序,包括高级特

性。● 第4章讨论状态,并解释流式应用程序有时是如何需要状态的。

同时读者还将了解如何实现状态存储以及如何在Kafka Streams

中执行连接。● 第5章讨论表和流的二元性,并引入一个新概念——KTable。

KStream是事件流,而KTable是相关事件的流或者更新流。● 第6章介绍低阶处理器API。到此时,一直使用的是高阶DSL,但

是在这里,读者将学习如何在编写应用程序的自定义部分时使用

处理器API。

第三部分将从开发Kafka Streams应用程序转到对Kafka Streams的管理知识的讨论。● 第7章介绍如何监控Kafka Streams应用程序,以查看处理记录所

需要的时间以及定位潜在的处理瓶颈。● 第8章介绍如何测试Kafka Streams应用程序。读者将学习如何对

整个拓扑进行测试,对单个处理器进行单元测试,以及使用嵌入

式Kafka代理进行集成测试。

第四部分是本书的压轴部分,在这里你将深入研究使用Kafka Streams开发高级应用程序。● 第9章介绍使用Kafka Connect将现有的数据源集成到Kafka

Streams中。你将会学习如何在流式应用程序中包括数据库表。

然后你将看到数据在Kafka Streams中流动时如何使用交互式查

询来提供可视化和仪表板应用程序,而无需关系型数据库。这一

章还会介绍KSQL,可以使用它在Kafka运行连续的查询,除了使

用SQL之外并不需要编写任何代码。关于代码

本书包含了很多源代码的例子,包括书中编号的代码清单所标明的代码,以及内联在普通文本中的代码。在这两种情况下,源代码都采用固定宽度字体的格式,以便与普通文本区分开。

在很多情况下,原始源代码已经被重新格式化了。我们增加了断行以及重新缩进,以适应书中可用的页面空间。在极少数情况下,甚至空间还不够,代码清单中包括续行标识()。此外,当在文本中描述代码时,源代码中的注释常常从代码清单中删除。代码清单中附带的许多代码注释,突出显示重要的概念。

最后,需要注意的是:许多代码示例并不是独立存在的,它们只是包含当前讨论的最相关部分代码的节选。你在本书附带的源代码中将会找到所有示例的完整代码。

本书的源代码是使用Gradle工具构建的一个包括所有代码的项目。你可以使用合适的命令将项目导入IntelliJ或Eclipse中。在附带的README.md文件中可以找到使用和导航源代码的完整说明。图书论坛

购买本书可以免费访问一个由Manning出版社运营的私人网络论坛,可以在论坛上对本书进行评论、咨询技术问题、接受本书作者或者其他用户的帮助。要访问该论坛,请访问Manning出版社官方网站本书页面。你还可以从Manning出版社官方网站了解更多关于Manning论坛及其行为规则。

Manning的论坛承诺为我们的读者提供一个可以在读者之间,以及读者与作者之间进行有意义对话的地方,但并不承诺作者的参与程度,作者对论坛的贡献是自愿的(并没有报酬)。建议你试着问他一些有挑战性的问题,以免他对你的问题没有兴趣!只要本书在印刷中,论坛和之前所讨论的问题归档就会从出版社的网站上获得。其他在线资源● Apache Kafka文档:见Apache Kafka官方网站。● Confluent文档:见Confluent官方网站。● Kafka Streams文档:见Confluent官方网站。● KSQL文档:见Confluent官方网站。关于封面插图

本书封面上的图片描述的是“18世纪一位土耳其绅士的习惯”,这幅插图来自Thomas Jefferys的A Collection of the Dresses of Different Nations, Ancient and Modern(共4卷),于1757年和1772年之间出版于伦敦。扉页上写着:这些是手工着色的铜版雕刻品,用阿拉伯胶加深了颜色。Thomas Jefferys(1719—1771)被称为“乔治三世的地理学家”。他是一位英国制图师,是当时主要的地图供应商。他为政府和其他官方机构雕刻和印刷地图,制作了各种商业地图和地图集,尤其是北美地区的。作为一名地图制作者,他在所调查和绘制的地区激起了人们对当地服饰习俗的兴趣,这些都在这本图集中得到了很好的展示。向往远方、为快乐而旅行,在18世纪后期还是相对较新的现象,类似于这套服饰集的书非常受欢迎,把旅行者和神游的旅行者介绍给其他国家的居民。Jefferys卷宗中绘画的多样性生动地说明了200多年前世界各国的独特性和个性。从那时起,着装样式已经发生了变化,各个国家和地区当时非常丰富的着装多样性也逐渐消失。现在仅依靠衣着很难把一个大陆的居民和另一个大陆的居民区分开来。或许我们已经用文化和视觉上的多样性换取了个人生活的多样化——当然是更为丰富和有趣的文化和艺术生活。

在一个很难将计算机书籍区分开的时代,Manning以两个世纪以前丰富多样的地区生活为基础,通过以Jefferys的图片作为书籍封面来庆祝计算机行业的创造性和首创精神。第一部分 开启Kafka Streams之旅

在本书第一部分,我们将论述大数据时代的起源,以及它是如何从最初为了满足处理大量数据的需求,到最终发展成为流式处理——当数据到达时立即被处理。本部分还会讨论什么是Kafka [1]Streams,并向大家展示一个没有任何代码的“心智模型” (mental model)是如何工作的,以便大家可以着眼于全局。我们还将简要介绍Kafka,让大家快速了解如何使用它。[1] 心智模型(mental model)又叫心智模式。心智模型的理论是基于一个试图对某事做出合理解释的个人会发展可行的方法的假设,在有限的领域知识和有限的信息处理能力上,产生合理的解释。心智模型是对思维的高级建构,心智模型表征了主观的知识。通过不同的理解解释了心智模型的概念、特性、功用。(引自百度百科)——译者注第1章 欢迎来到Kafka Streams

本章主要内容● 了解大数据的发展是如何改变程序设计方式的。● 了解流式处理是如何工作的以及我们为什么需要它。● Kafka Streams简介。● 看看Kafka Streams能解决的问题。

在本书中,你将学习如何使用Kafka Streams来解决流式应用程序的需求问题。从基本的提取、转换、加载(ETL)到复杂的有状态转换再到连接记录,将会覆盖Kafka Streams的各组件,这样你就能够应对流应用程序中遇到的这些挑战。

在深入研究Kafka Streams之前,我们将简要地探索一下大数据处理的历史。当我们在确定问题和解决方案时,将会清楚地看到对Kafka和Kafka Streams的需求是如何演变的。让我们看看大数据时代是如何开始的,是什么导致了应用Kafka Streams的解决方案。1.1 大数据的发展以及它是如何改变程序设计方式的

随着大数据框架和技术的出现,现代编程语言出现了爆炸式增长。当然,客户端开发经历了自身的转变,移动设备应用程序的数量也出现了爆炸式增长。但是,无论移动设备市场有多大,客户端技术如何革新,有一个不变的事实:我们每天需要处理的数据越来越多。随着数据量的增长,分析和利用这些数据带来的好处的需求也在同时增长。

然而,有能力批量处理大量数据(批处理)还不够。越来越多的组织机构发现它们需要在数据到达时就要对其进行处理(流式处理)。Kafka Streams提供一种前沿的流式处理方式,它是一个对记录的每个事件进行处理的库。基于每个事件进行处理意味着每个单独的数据记录一到达就能够被及时处理,并不需要将数据分成小批量(微批处理)。注意 当数据到达时即对其进行处理的需求变得越来越明显时,一种新的策略应运而生——微批处理。顾名思义,所谓微批处理也是批处理,只不过数据量更小。通过减少批尺寸,微批处理有时可以更快地产生结果;但是微批处理仍然是批处理,尽管间隔时间更短。它并不能真正做到对每个事件进行处理。1.1.1 大数据起源

20世纪90年代中期,互联网才开始真正影响人们的日常生活。从那时起,网络提供的互联互通给我们带来了前所未有的信息访问以及与世界任何地方的任何人即时沟通的能力。在所有这些互联互通访问过程中,一个意想不到的副产品出现了——大量数据的生成。

但在我看来,大数据时代正式始于Sergey Brin和Larry Page创立了谷歌公司的1998年。Sergey Brin和Larry Page开发了一种新的网页搜索排名方法——PageRank算法。在一个很高的层面上来说,PageRank算法通过计算链接到网站的数量和质量来对该网站进行评级。该算法假定一个Web页面越重要或越相关,就会有越多的站点引用它。

图1-1提供了PageRank算法的图形化表示。图1-1 PageRank算法应用。圆圈代表网站,其中较大的圆圈表示有更多的其他站点链接到它● 网站A是最重要的,因为有最多引用指向它。● 网站B有些重要,尽管没有很多引用指向它,但有一个重要网站

指向它。● 网站C没有网站A或网站B重要。虽然指向网站C的引用比指向网

站B的多,但是这些引用的质量较低。● 底部的网站(从D到I)没有引用指向它们,这就使得这些网站的

价值最小。

虽然图1-1是对PageRank算法的极度简化,但展示出该算法实现原理的基本思想。

当时,PageRank是一种革命性的方法。以前,Web上的搜索更倾向于使用布尔逻辑来返回结果。如果一个网站包含了你想要搜索的所有或大部分词条,那么这个网站就会出现在搜索结果中,而不管内容的质量如何。但在所有互联网内容上运行PageRank算法需要一种新的方法——传统的数据处理方法耗时太长。谷歌公司要生存和成长,就需要快速索引所有的内容(“快速”是一个相对的术语),并向公众展示高质量的结果。

谷歌公司为处理所有这些数据开发了另一种革命性的方法——MapReduce范式。MapReduce不仅使谷歌能够做一个公司需要的工作,而且无意中还催生了一个全新的计算产业。1.1.2 MapReduce中的重要概念

在谷歌公司开发MapReduce时,map和reduce函数并不是什么新概念。谷歌方法的独特之处在于在许多机器上大规模地应用这些简单的概念。

MapReduce的核心在于函数式编程。一个map函数接受一些输入,并在不改变原始值的情况下将这些输入映射到其他对象。下面是一个用Java 8实现的一个简单实例,该实例将一个LocalDate对象映射为一个字符串消息,而原始的LocalDate对象则不会被修改。代码片段如下:Function addDate = (date) -> "The Day of the week is " + date.getDayOfWeek();

尽管简单,但这个简短的例子足以展示出了一个映射函数是做什么的。

但reduce函数接受一组参数,并将这些参数归约成一个值或者归约后至少参数规模更小。取一组数字并将它们加在一起是一个reduce操作的很好例子。

对一组数字执行归约,首先要初始化一个起始值,本例将起始值设置为0(加法的恒等值)。下一步是将起始值与数字列表中的第一个数相加,然后将第一步相加的结果与列表中的第二个数相加。函数重复执行这个过程,直到列表中最后一个数字,产生一个数值。

下面是归约处理一个包括整型数字1、2、3的列表的步骤,代码片段如下:0 + 1 = 1 ←--- 将起始值与第一个数相加1 + 2 = 3 ←--- 将第一步计算结果与列表中的第二个数相加3 + 3 = 6 ←--- 将第二步的相加之和与列表中第三个数也就是列表中最后一个数相加

正如所看到的,reduce函数将结果集合并在一起形成更小规模的结果集。与映射函数类似,reduce函数也不会修改原始数字列表。

现在,让我们来看看如何使用Java 8的lambda表达式来实现这样一个简单的reduce函数,代码片段如下:List numbers = Arrays.asList(1, 2, 3);int sum = numbers.reduce(0, (i, j) -> i + j );

由于本书的主要话题不是讲解MapReduce,因此在这里对其背景不做探讨。但是,可以看到MapReduce范式(后来在Hadoop中实现了,最初的开源版本基于谷歌的MapReduce白皮书)引入的一些重要概念在Kafka Streams中依然适用。● 如何在一个集群中分发数据以达到易处理的规模。● 使用键/值对和分区将分布式数据分组在一起。● 利用副本来容忍故障而不是避免故障。

接下来,将对这些概念做概括性的论述。需要注意的是,这些概念的介绍将会穿插在整本书当中,因此在下文它们会再次被提及。1.在集群中分布数据以达到处理的规模

对一台机器来说,处理5 TB(5000 GB)的数据可能是非常困难的。但是,如果将这些数据按每台服务器易处理的数据量进行分割,让多台机器去处理,那么数据量巨大的问题就会被最小化。表1-1清晰地说明了这一点。表1-1 如何分割5 TB数据以提高数据处理吞吐量服务器数量每台服务器处理的数据量10500 GB10050 GB10005 GB50001 GB

从表1-1可知,一开始可能需要处理大量的数据,但是通过将负载分散到更多的机器上,数据的处理就不再是一个问题了。表1-1中的最后一行中1 GB的数据由一台笔记本电脑就可以很轻松地处理。

这是理解关于MapReduce的第一个关键概念:通过在计算机集群中分散负载,可以将数据的巨大规模转换为可管理的数量。2.使用键/值对和分区对分布式数据分组

键/值对是一个具有强大含义的简单数据结构。在上一节中,我们看到了将大量数据散布到计算机集群上的价值。分散数据解决了数据处理的问题,但现在的问题是如何将分布在不同机器上的数据汇集起来。

要重新组合分布式数据,可以使用键/值对的键来对数据进行分区。术语“分区”意味着分组,但并不是指使用完全相同的键,而是使用具有相同散列码的键进行分组。要按键将数据分割成分区,可以使用以下公式:int partition = key.hashCode() % numberOfPartitions;

图1-2展示了如何应用散列函数来获取存储在不同服务器上的奥运赛事的结果,并将其分组到不同赛事的分区上。所有的数据都以键/值对存储,在图1-2中,键是赛事的名称,值是单个运动员的比赛结果。图1-2 按键对分区上的记录进行分组。尽管记录开始在不同的服务器上,但它们最终会在适当的分区中

分区是一个重要概念,在后面的章节我们将会看到详细的例子。3.通过使用复制来接受故障

谷歌MapReduce的另一个重要组件是谷歌文件系统(Google File System,GFS)。正如Hadoop是MapReduce的开源实现,Hadoop文件系统(Hadoop File System,HDFS)是GFS的开源实现。

从较高层次来看,GFS和HDFS都将数据分割成很多个数据块,并将这些数据块分布到集群中。但是GFS或HDFS的精髓部分在于如何处理服务器和硬盘故障,该处理框架不是试图阻止失败,而是通过跨集群复制数据块来接受失败(默认复制因子是3)。

通过复制不同服务器上的数据块,就不必再担心磁盘故障甚至整个服务器故障而导致停产。数据复制对于分布式应用提供容错能力至关重要,而容错能力对于分布式应用的成功是必不可少的。稍后将看到分区和复制是如何在Kafka Streams中工作的。1.1.3 批处理还不够

Hadoop迅速在计算领域流行起来,它允许在使用商业硬件时能够处理巨大数量的数据并具有容错性(节约成本)。但是Hadoop/MapReduce是面向批处理的,面向批处理意味着先收集大量数据,然后处理它,再将处理后的输出结果进行存储以便以后使用。批处理非常适合类似PageRank之类的场景,因为你无法通过实时观察用户的点击来判断整个互联网上哪些资源是有价值的。

但是企业也越来越面临着要求他们更快地响应重要问题的压力,这些问题诸如:● 现在的趋势是什么?● 在最近10分钟内有多少次无效登录尝试?● 用户群是如何利用我们最近发布的特性的?

显然,需要另一种解决方案,而这种解决方案就是流式处理。1.2 流式处理简介

虽然流式处理有不同的定义,但在本书,我们将流式处理定义为当数据到达系统时就被处理。进一步提炼流式处理的定义为:流式处理是利用连续计算来处理无限数据流的能力,因为数据流是流动的,所以无须收集或存储数据以对其进行操作。

图1-3所示的这个简单的图表示一个数据流,线上的每个圆圈代表一个时间点的数据。数据不断地流动,因为在流式处理中的数据是无限的。图1-3 这个弹珠图是流式处理的一个简单表示。图中每个圆圈代表某一特定时间点的某些信息或发生的事件,事件的数量是无限的,并且不断地从左向右移动

那么,谁需要使用流式处理呢?需要从可观察到的事件中得到快速反馈的任何人都需要用到流式处理。让我们来看一些例子。何时使用流式处理和何时不使用它

和任何技术解决方案一样,流式处理也不是适用于所有情况的解决方案。对传入数据快速响应或报告的需求是流式处理的一个很好的用例。下面是几个例子。● 信用卡诈骗——信用卡持有者可能未注意到卡被盗,但当碰巧

根据既定模式(消费地点,一般消费习惯)来审查购买情况时,

就可能检测到信用卡被盗刷,并提醒信用卡持有者。● 入侵检测——在遭到破坏后分析应用程序日志文件,或许有助

于防止在未来受到攻击或者提高安全性,但是实时监控异常行为

的能力至关重要。● 大型赛事,如纽约市马拉松赛——几乎所有的赛跑运动员都会

有一个芯片安装在他们的鞋子上,当赛跑运动员通过跑道上的传

感器时,可以使用这些信息来跟踪他们的位置。通过使用传感器

的数据,可以确定领跑者,识别出潜在的作弊者,同时也能检测

出是否有赛跑运动员可能会遇到问题。● 金融业——实时跟踪市场价格和方向的能力对于经纪人和消费

者择时买卖交易必不可少。

然而,流式处理不是所有问题领域的通用解决方案。例如,为了有效地预测未来的行为,需要使用大量的数据来消除异常并识别模式和趋势。这里的重点是随着时间的推移分析数据,而不仅仅是最新的数据。● 经济预测——多维度收集一个较长时间段的信息是做出准确预

测的一种尝试,例如房地产市场的利率趋势。● 学校实施课程改变的效果——只有在一两个测试周期之后,学

校管理者才能估量出课程的改变是否到了预期目标。

这里要记住一个要点:如果数据到达时需要被立即报告或处理,那么流式处理是一个不错的选择;如果需要对数据进行深入分析,或是为了编制一个大的数据仓库以备后期分析,那么流式处理方式可能就不合适了。现在来看一个流式处理的具体例子。1.3 处理购买交易

让我们从应用一般的流式处理方法对零售处理的示例开始。然后,我们将了解如何使用Kafka Streams来实现流式处理应用程序。

假定ane Doe在下班回家的路上想起需要一个牙膏。于是她在回家路上的一家ZMart超市停下来,进去拿了一盒牙膏,然后径直到收银台去支付她购买的物品。收银员问Jane是否是ZClub的会员,然后收银员扫描Jane的会员卡,这里Jane的会员信息就是购买事物中的一部分。

当总价算好之后,Jane将信用卡递给收银员,收银员刷卡并递给Jane收据。当Jane走出商店时,她查看她的电子邮件,收到了一条来自ZMart超市的信息,感谢Jane的惠顾,并附上各种优惠券在Jane下次光顾时可享受折扣。

这个交易是客户不会多加考虑的常见事件,然而你会意识到这意味着什么:丰富的信息可以帮助ZMart更高效地经营,更好地服务客户。让我们向前追溯一下,看看如何使这种交易成为现实。1.3.1 权衡流式处理的选择

假设你是ZMart流数据团队的开发负责人,ZMart是一个大型连锁零售店,分布在全国各地。ZMart经营得很好,每年的销售总额都在10亿美元以上。你想要从公司的交易数据中挖掘数据,以提高业务效率。由于你知道要处理的来自ZMart销售数据的数据量非常大,因此无论你选择哪一种技术去实现,这种技术都需要能够快速和大规模处理这些大量数据。

你最终选择流式处理技术,因为当有交易发生时可以利用业务决策和机会,而无须先收集数据然后等几个小时之后再做决策。你召集管理层和你团队的成员商讨并提出了保证流式处理方案成功所必需的4个基本要求。● 隐私——首先也是最重要的是重视与客户的关系。鉴于当前社

会所关注的隐私问题,第一个目标就是要保护客户的隐私,将保

护客户的信用卡号码列为最高优先级,无论怎么使用上面提到的

交易信息数据,客户的信用卡信息都不会有暴露的风险。● 客户奖励——要有一个新的客户奖励计划,以记录基于客户在

某些物品上花费的金额所获得的奖励积分。目的是一旦客户得到

奖励就要很快地通知他们,希望他们回到店里来消费。同时,也

需要有适当的活动监测系统。还记得Jane离开商店后是如何立

即收到一封电子邮件的吗?这就是你想让公司展现的方式。● 销售数据——ZMart公司希望进一步优化其广告和销售策略,同

时公司希望按地区追踪客户的购买情况,以确定哪些产品在该国

的某些地区更受欢迎。目的是在该国的特定区域进行精准营销,

并对某些畅销的物品特价销售。● 存储——所有的购买记录都保存在一个非现场的存储中心,以

用于历史和特定分析。

这些需求本身已经足够明确了,但是对于Jane Doe这样的单笔购买交易,如何实现这些需求呢?1.3.2 将需求解构为图表

查看前面的需求,我们可以很快地把它们重塑为一个有向无环图(directed acyclic graph,DAG)。客户在注册地完成的交易点是整个图的源节点,那么需求就变成了主源节点的子节点,如图1-4所示。图1-4 流应用程序的业务需求以有向无环图的形式呈现,图中每个顶点表示一个需求,边表示通过图表的数据流

接下来,我们将介绍如何将购买交易映射到需求图。1.4 改变看待购买交易的视角

在本节中,我们将遍历购买的每一个步骤,并从一个较高层次上了解如何与图1-4中的需求图相关联。在下一节中,我们将介绍如何将Kafka Streams应用到这个过程中。1.4.1 源节点

图的源节点是应用程序消费购买交易数据的地方,如图1-5所示。该节点是将流经该图的销售交易信息的来源。图1-5 销售交易图的简单开始,该节点是流经该图的原始销售交易信息的来源1.4.2 信用卡屏蔽节点

图中源节点的子节点是信用卡屏蔽操作所发生的地方,如图1-6所示,它在图中用来表示业务需求的第一个顶点或节点,也是从源节点接收原始销售数据的唯一节点,有效地使该节点成为连接到它的所有其他节点的源。图1-6 图中的第一节点代表业务需求。这个节点负责屏蔽信用卡号码,并且是唯一一个从源节点接收原始销售数据的节点,有效地使该节点成为连接到它的所有其他节点的源

对于信用卡号屏蔽操作,先复制信用卡号码数据,然后将信用卡号码除最后4位数字之外的其他数字都转化为“x”字符。数据流经图中其余节点将信用卡号码转化为“xxxx-xxxx-xxxx-1122”格式的数据。1.4.3 模式节点

模式节点(如图1-7所示)抽取相关信息以确定客户在全国哪个地方购买产品。模式节点不是将数据进行复制,而是从数据中检索出购买相关的物品、日期以及邮政编码,并创建一个包含这些字段的新对象。图1-7 图中添加了模式节点,该节点从屏蔽节点消费购买信息,并将这些信息转化为一条记录,该记录包括客户何时购买物品以及客户最终完成交易地点对应的邮政编码1.4.4 奖励节点

这个流程中的下一个子节点是奖励累加器,如图1-8所示。ZMart有一个客户奖励计划,给在ZMart门店购买物品的客户积分。这个节点的职责就是从购买信息中抽取客户的ID和花费的金额,并创建一个包括这两个字段的新对象。图1-8 奖励节点负责从屏蔽节点消费销售记录,并将其转换为包含购买总额和客户ID的记录1.4.5 存储节点

最后的子节点将购买数据写入NoSQL数据存储中以供进一步分析,如图1-9所示。图1-9 存储节点也使用来自屏蔽节点的记录。这些记录不会转换为任何其他格式, 而是存储在NoSQL数据存储中,以便后期进行专门分析

现在,我们已通过ZMart的需求图跟踪示例购买交易,让我们看看如何使用Kafka Streams将此图转换为函数流式应用程序。1.5 Kafka Streams在购买处理节点图中的应用

Kafka Streams是一个允许对记录的每个事件执行处理的库,可以在数据到达时使用它来处理数据,而不需要在微批中对数据进行分组。可以在每条记录可用时立即对其进行处理。

ZMart的大多数需求的目标都是对时间敏感的,要能够尽可能快地对数据进行处理,最好能够在事件发生的时候就收集数据。此外,由于ZMart在全国有很多的分店,为了对数据进行分析就需要将所有的交易记录汇集成一个单个流或数据流。基于这些原因,Kafka Streams是非常合适的,当数据到达时用户就可以对其进行处理,并且提供所需的低延迟处理。

在Kafka Streams中,定义了一个处理节点的拓扑结构(我们交替使用处理器和节点这两个术语)。一个或多个节点将Kafka的一个或多个主题作为数据源,还可以添加其他节点,这些节点被认为是子节点(如果对Kafka主题不熟悉,不用担心,第2章中会详细解释)。每个子节点可以定义其他子节点。每个处理节点执行分配给它的任务,然后将记录向前发送给它的每个子节点。这个执行过程以此类推,每个处理节点处理完后就将数据继续发送给它的所有子节点,直到每个子节点都执行了各自的功能。

这个过程听起来熟悉吗?应该熟悉,因为我们做过与其类似的操作,即将ZMart的业务需求转换为处理节点的图。遍历图就是Kafka Streams的工作方式,该图是一个有向无环图(DAG)或处理节点的拓扑结构。

从源节点或父节点开始,该节点有一个或多个子节点,数据总是从父节点流向子节点,永远不会从子节点流向父节点。依此类推,每个子节点依次可以定义自己的子节点。

记录以深度优先的方式流过图表。这种深度优先的方法具有重要的意义:每条记录(键/值对)都被整个图完整地处理完才接受另一条记录进行处理。由于每条记录都以深度优先的方式在整个有向无环图中被处理,因此无须在Kafka Streams中内置背压。定义 虽然背压(backpressure)有不同的定义,但这里将背压定义为通过缓冲或使用阻塞机制来限制数据流的需要。当源产生数据比接收器能够接收和处理这个数据的速度更快时,背压是必需的。

通过连接或链接多个处理器,可以快速构建复杂的处理逻辑,同时每个组件保持相对简单。正是在处理器这种组合中,Kafka Streams的强大和复杂性才开始发挥作用。定义 拓扑(topology)是一种将整个系统的各部分进行整理并将它们连接起来的方式。当我们说Kafka Streams有一个拓扑结构时,指的是通过在一个或多个处理器中运行来转换数据。

 Kafka Streams与Kafka 正如我们可能已从名字中猜到的一样,Kafka Streams是运行在Kafka之上的,在这个介绍性章节中Kafka相关知识并不是必需的,因为我们更多地从概念上关注Kafka Streams是如何工作的。虽然可能会提到一些Kafka特定的术语,但在大多数情况下,我们关注的是Kafka Streams流式处理方面。对于新接触Kafka或不熟悉Kafka的读者,第2章将会讲解需要了解的相关知识。了解Kafka的知识是有效使用Kafka Streams的基础。1.6 Kafka Streams在购买交易流中的应用

我们再构建一张处理图,不过这次我们将创建一个Kafka Streams程序。提醒一下,图1-4展示了ZMart业务需求的需求图。请记住,顶点是处理数据的处理节点,而边显示数据流。

虽然在构建新图时,将会创建一个Kafka Streams程序,这依然是一个高层次的方式,将忽略一些细节。在本书后面部分,当我们看到实际代码时会有更多的细节。

一旦Kafka Streams程序开始消费消息记录,就会将原始记录转换为Purchase对象。以下信息将构成一个Purchase对象:● ZMart的客户ID(从会员卡扫描);● 花费总额度;● 购买的物品;● 发生购买的ZMart店所在地的邮政编码;● 交易的日期和时间;● 客户的借记卡或信用卡号码。1.6.1 定义源

设计任何Kafka Streams程序的第一步都是为流建立一个源。源可以是以下任何一种:● 单个主题;● 以逗号分隔的多个主题列表;● 可以匹配一个或多个主题的正则表达式。

对于本例,源将是一个名为“transactions”的单个主题。如果不熟悉Kafka术语,记住,我们将会在第2章中对这些术语进行解释。

需要注意的是,对于Kafka,Kafka Streams程序看起来像任何其他消费者和生产者的组合。任何数量的应用程序都可以与流式程序一起订阅同一个主题。图1-10表示拓扑中的源节点。图1-10 源节点:一个Kafka主题1.6.2 第一个处理器:屏蔽信用卡号码

现在已定义好了一个源节点,就可以开始创建一些处理数据的处理器。第一个目标就是屏蔽购买记录中所记录的信用卡号码。第一个处理器用来转换信用卡号码,例如,将1234-5678- 9123-2233的信用卡号码转换为xxxx-xxxx-xxxx-2233。

由KStream.mapValues方法将执行如图1-11所展示的屏蔽操作,它将返回一个新的KStream实例,其值由指定的ValueMapper进行屏蔽处理。这个特别的KStream实例将是我们定义的其他任何处理器的父处理器。图1-11 屏蔽处理器是主源节点的一个子节点。该处理器接收所有的原始销售交易记录,然后发出将信用卡号码进行屏蔽后的新记录创建处理器拓扑

每次通过一个转换方法创建一个新的KStream实例,其本质是创建了一个新的处理器,这个新处理器会连接到已创建好的其他处理器。通过组合的处理器,我们可以使用Kafka Streams优雅地创建复杂的数据流。

需要特别注意的是,通过调用一个方法返回一个新的KStream实例不会导致原实例停止消费消息。一个转换方法创建一个新的处理器,并添加到现有的处理器拓扑中。然后用更新后的拓扑作为一个参数来创建新的KStream实例,新的KStream实例从创建它的节点处开始接受消息。

你很可能会构建新的KStream实例来执行额外的转换,为其原来的目的而保留原来的流。当我们定义第二个和第三个处理器时,你就会看到这样的例子。

虽然可以让ValueMapper将传入的值转换为一个完全新的类型,但在本例它只返回一个更新后的Purchase对象的副本。使用映射器更新一个对象是在我们在KStream中经常看到的一种模式。

现在你应该清楚地了解了如何构建处理器管道来转换和输出数据。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载