下一层是流处理器,它从流处理数据平台中获取事件,并对其进行一系列操作。流处理器消费来自一个或多个主题的数据,然后通过函数对每个事件进行处理。这些函数可以用编程语言编写,也可以是SQL转换。一旦函数被调用,其输出将被写入接收器系统,例如流处理数据平台中的不同主题,甚至另一个数据库。此外,流处理器还可能触发其他分支功能,如发送电子邮件或Slack通知。请参考图2-11。
如果流数据平台中的事件已经符合服务层所需的格式,那么就可能不需要经过流处理器的处理。
图2-11:流处理层
流处理器有三种使用模式,如图2-12所示。
图2-12:流处理器的使用模式
接下来,我们将重点阐述以下模式:
流式分析
流式分析是指对输入数据流进行连续的计算处理。举例来说,我们能够实施各种聚合操作,包括计数,寻找最大值、最小值或计算平均值等。这些处理结果一般由流处理引擎保存在内存中,同时也可能以容错的方式存储,确保流处理引擎能从故障中迅速恢复。
事件驱动的微服务
事件驱动的微服务是一种架构模式,在这种模式下,微服务通过初始的事件消费来进行交互。这种技术能够显著降低延迟,因此非常适合用于欺诈检测等场景。
流式ETL
流式ETL在构建实时数据管道方面扮演着关键角色。我们编写独立的函数,并将它们串联起来,最终利用它们完成有意义的任务。当事件在管道中传递时,我们可以灵活地对事件进行无状态操作,例如过滤、路由或映射。同时,我们还可以进行有状态操作,比如利用窗口技术将不同的数据流连接起来,或者将数据流与静态数据集结合,从而丰富流数据的信息内容。
在实时分析的场景中,流处理器主要应用于流式ETL和流式分析处理。
在与流数据平台的比较中,流处理技术领域显得尤为丰富多彩,涵盖了从基于JVM的传统流处理引擎,如Flink、Spark Structured Streaming、Apache Beam以及Kafka Streams等,到基于Python的现代化工具,比如Bytewax、Faust和Quix。当你阅读本文的时候,新的工具可能已经在该领域涌现。
面对众多选择,如何决定使用哪种流处理器呢?关键在于,首先明确是否需要支持有状态处理。若仅需无状态处理,那么可以从众多选项中灵活挑选;然而,如果涉及有状态处理,选择范围将显著缩小。
确定了这一点后,接下来需要考虑流处理器所支持的编程语言。某些流处理器可能需要特定的编程语言,如Java或Python,但许多现代工具已经将SQL作为首选的支持语言。
正如选择流处理平台时一样,为了确保所选工具能够满足可扩展性和延迟的需求,进行基准测试是不可或缺的步骤。
服务层代表了对事件流处理平台生成的实时分析进行消费的主要途径。该层可以是键值存储(例如NoSQL数据库)或实时OLAP数据库,具体取决于我们的需求。服务层为各种应用提供了数据接入点,包括实时仪表盘、数据应用和推荐引擎,并支持即时数据探索的功能。
然而,我们可能会问,为何需要服务层?难道不能仅通过事件流处理平台和流处理器直接向下游提供数据吗?
理解事件价值随时间变化的本质,有助于我们领会服务层所满足的核心需求。如图2-13所示,单个事件的商业价值会随着时间的流逝而逐渐减少。
以一个数字化事件为例,假设有用户在外卖应用中搜索了“比萨”这一关键词。那么,对于这个事件的全部信息,了解它的价值究竟有多大呢?
图2-13:随着时间推移,单个数据点的价值逐渐减少
当这一事件首次发生时,它蕴含着很高的价值:意味着某个地方的某位用户正在积极寻找比萨。如果我们能够实时捕捉到这一行为,就有机会向该用户提供附近比萨店的优惠信息。
但是,这些信息的价值会迅速衰减。了解昨天甚至几个小时前有人想要购买比萨,可能已经没有多大用处。等你意识到这一点时,用户很可能已经从别的竞争者那里购买了比萨并享用完毕。
相比之下,随着时间的推移,汇总后的事件信息的价值却会逐渐增加,正如图2-14所展示的那样。
设想我们不将焦点放在单个个体寻找附近比萨的行为上,而是对一段时间内在特定区域内所有搜索比萨的个体感兴趣。通过分析累积的数据,我们能够洞察到新的趋势。例如,我们可以追踪这一趋势并据此预测未来的需求,这对于库存管理尤为重要。
聚合数据的价值走向与单次事件数据截然不同:对于任何独立事件,其价值或许并不显著,但随着时间的积累,其价值会显著攀升,因为它能提供更准确的预测。
图2-14:随着时间推移,数据点总体的价值不断增加
正是在实时分析的技术栈中,服务层(如图2-15所示)为理解聚合事件的重要性提供了附加价值。
图2-15:服务层
服务层向内外部用户敞开大门,既服务于人类用户,也满足软件实体的需求,它们共同追求的是迅速且精准的大规模分析能力。因此,服务层必须确保以下几点:
摄取延迟
数据摄取过程需要达到极速。任何数据的更新与变化都应瞬间映射至服务层。
查询延迟
一旦数据被拉取,我们需要保证其能在网络响应时间内完成查询——这里所说的时间,是以毫秒计而非秒。
并发性
服务层需要具备同时处理众多查询任务的能力。每秒处理数十万次查询并非罕见。能够对新数据执行大规模查询,意味着为数据开辟了新的使用场景。这些场景可能会增强用户互动,甚至可能为我们已搜集的数据解锁更多商业潜力。
在服务层的选择上,我们面对众多选项。对于键-值存储的NoSQL数据库,MongoDB、Elasticsearch和Redis是流行的技术。而针对实时OLAP数据库,我们可以选择Apache Pinot、Apache Druid、Rockset以及ClickHouse等方案。
决策使用哪一个服务层组件时,首要考虑因素是对服务层可能执行的查询类型的分析。若主要操作是基于键的检索(例如,通过ID获取最新数据),那么支持键-值存储的服务层将是不错的选择。反之,若需要在多个维度对数据进行复杂的交叉分析,实时OLAP数据库则可能更符合需求。在本节接下来的内容中,我们将假定使用的是实时OLAP数据库。
下一步,我们需要评估数据摄取的便捷性:
·是通过API还是标准SQL来完成?
·支持哪些流处理平台作为数据来源?是否与我们所选的流处理平台兼容?
·从事件在流处理平台上发生到能够被查询到,这之间的时间延迟是多少?
·数据库能否应对数据生成的体量和速率?
数据摄取一旦完成,我们的注意力便需要转向数据的存储和查询效率。需要了解的是,对于常规查询,响应速度是否达标,若未达标,是否可以通过增加索引或实施预聚合策略来提升性能。
虽然供应商常会提供基准测试以展示他们的技术在数据摄取及查询方面的性能,但为了确保所选技术能够满足我们具体的性能要求,建议进行独立的性能测试验证。
若服务层面向内部用户,或许我们可以直接赋予他们查询数据的权限。然而,对于外部用户而言,无疑需要提供一个交互式的前端界面。
构建前端有多种方法:
自定义开发
若追求对前端界面和用户体验的绝对控制,自主编码将是必由之路。市面上有众多工具可以轻松打造数据密集型的单页应用(S PA),并且新的工具层出不穷。
在我们看来,React.js是构建SPA的优选工具,当然还有其他优秀的框架,如Angular.js、Ember.js、Backbone.js、Meteor.js、Polymer.js以及Vue.js等。
低代码平台
低代码平台显著减少了打造交互式Web应用所需的编码工作量。这类平台或是让用户通过图形界面搭建应用,或是允许开发者无须掌握任何前端技术便能编写用户界面代码。
我们特别推崇的两个低代码平台是Streamlit和Plotly Dash,它们都支持利用Python来构建交互式的前端应用。Streamlit是一个开源的Python库,能够轻松创建并分享外观精美、专门针对机器学习与数据科学的自定义Web应用。Dash则提供了与Streamlit相似的功能,其基础架构建立在Plotly、React和Flask之上。
数据可视化
数据可视化工具为创建仪表盘提供了直观的拖放功能。这些工具能够毫不费力地制作多种图表,且无须编写任何代码。尽管它们的功能强大性不如低代码平台,但使用起来却更为便捷。
我们特别偏爱的数据可视化工具包括Superset和Redash,同时,Grafana、Retool和Metabase等其他选项也同样值得推荐。
在选择可视化工具时,我们应该考虑以下标准:
前端开发经验
团队中是否有熟悉相应技术栈的软件工程师,能利用该工具打造出交互式的用户界面?
时间因素
准备前端需要多少时间?如果时间紧迫,那么选择一个已经为你完成大部分繁重工作的工具可能更为适宜。
用户群体
前端的用户是公司内部人员还是外部客户?如果是内部用户,选择数据可视化工具或低代码平台可能更加恰当。