一 为什么要使用流数据架构
流处理最初是一种“特定群体”技术。但随着 SaaS、物联网和机器学习的快速发展,各行各业的组织现在都在试行或全面实施流分析。很难找到一家没有应用程序、在线广告、电子商务网站或物联网产品的现代公司。这些数字资产中的每一个都会创建实时事件数据流。人们越来越渴望整合流式数据基础架构,从而使复杂、强大和实时的分析成为可能。传统的批处理架构可以满足较小规模的需求。但流媒体资源——传感器、服务器和安全日志、实时广告、来自应用程序和网站的点击流数据等等——每秒可以生成多达 1 Gb 的事件。流式数据架构在生成数据时使用这些数据,并准备好进行分析。考虑到数据流的独特特征,后者尤其重要——通常是非结构化或半结构化数据,在进行任何认真的分析之前必须对其进行处理、解析和结构化。流式架构提供了批处理管道无法提供的多项优势:
- 以原生形式处理永无止境的事件流,避免批处理事件的开销和延迟。
- 实时或近实时处理最新的数据分析和洞察力——例如,显示机器性能的仪表板,或微目标广告或即时服务,或检测欺诈或网络安全漏洞。
- 检测时间序列数据中的模式, 例如突出显示网站流量数据的趋势。这很难用传统的批处理来完成,因为连续的时间相邻事件可以跨多个批次中断。
构建流媒体架构是一项复杂的挑战,最好根据用例使用额外的软件组件来解决——因此需要“构建”一个通用解决方案,以处理大多数(如果不是全部)设想的用例。
二 流式架构的组件
流数据架构是一个软件组件框架,用于从多个来源摄取和处理大量原始数据流。
从广义上讲,它由四个部分组成:
- 流处理器或消息代理,用于收集数据并重新分发它
- 数据转换工具(ETL、ELT 等),为查询准备好数据
- 查询引擎,提取商业价值
- 大量流数据的经济高效存储——文件存储和对象存储
下面我们回顾一下每种组件类型在流式架构中的位置和方式。
流处理器/消息代理
流处理器从其来源收集数据,将其转换为标准消息格式,然后连续流式传输以供其他组件使用。(此类组件可以是存储组件,例如数据湖、ETL 工具或其他类型的组件。)流处理器具有高容量(>1 Gb/秒),但不执行其他数据转换或任务调度。
作为数据管道的流处理器(来源:Wikimedia Commons)
例子:
- Apache Kafka
- Amazon Kinesis Data Streams
- Azure Event Hub
- Google Cloud PubSub
流处理工具
在消息代理存储数据后,您必须聚合、转换和构建数据以使其可以查询。您可以通过 ETL 执行此操作,在其中您在暂存区域或流工具中准备数据,然后再将其移动到查询位置,或者通过 ELT,在同一位置转换和查询数据。此类转换包括规范化;将相关字段映射到列;加入来自多个来源的数据;文件压缩;分区;基于时间的聚合;等等。
例子:
- Apache Spark Streaming (SQL querying possible, mostly via complex Java or Scala)
- Amazon Web Services – Kinesis
- Google Cloud – Dataflow
- Microsoft Azure – Stream Analytics
- Apache Flink
- Upsolver
请注意,根据您的需求和您创建的架构,数据转换可能会直接发生在数据流入和存储在数据湖或其他存储库之前,或者在数据被摄取和存储之后。
查询引擎
数据现在已准备好进行分析。工具和技术差异很大,具体取决于用例。
示例(并非详尽无遗):
- 查询引擎——Athena、Presto、Hive、Redshift Spectrum
- 文本搜索引擎——Elasticsearch、OpenSearch、Solr、Kusto
- 云数据仓库——AWS Redshift、Snowflake、Google BigQuery、Synapse Analytics (Azure)
- NOSQL 存储 – Cassandra、Amazon DynamoDB、CosmosDB、Google BigTable
- 图形分析——Neo4j、Amazon Neptune
- 关系数据库——RDS、SingleStore、CockroachDB
- 实时数据库——Imply、Clickhouse
- TSDB——InfluxDB,AWS TimeSeries
流式数据存储
由于事件流的庞大数量和多结构性质,组织通常将其流事件数据存储在云对象存储中以用作数据湖。它们提供了一种经济高效且持久的方法来存储大量事件数据。它们是一个灵活的集成点,因此流媒体生态系统之外的工具可以访问流媒体数据。
例子:
- 亚马逊 S3
- 微软 Azure 存储
- 谷歌云存储
三 流式架构最佳实践
在构建流架构时,请牢记这些技术:
- 部署读取模式模型
- 分离实时和历史数据
- 维护所有传入事件的不可变日志
- 分层数据湖
- 保持架构开放
- 优化查询性能
部署读取模式模型
应该了解正在摄取的数据——每个数据源的架构、稀疏填充的字段、数据基数等。在读取时获得这种可见性而不是在写入时尝试推断它可以省去很多麻烦,因为随着架构变化的发生(意外的新的、删除的和更改的字段),可以基于最准确和可用的数据构建 ETL 管道。
将用于实时分析的数据与历史数据分开
优化用于实时或近实时分析的数据以确保快速读取。以原始形式保留历史数据以供临时查询使用,用于:
- “回放”过去的事态
- 错误恢复
- 追踪数据沿袭
- 探索性分析
维护所有传入事件的不可变日志
在这里,实质上是在存储整个事件转换链,而不仅仅是转换的最终(或最近)结果。通过这种方式,可以将任何事件恢复到某个时间点的状态。这种“事件溯源”方法有很多好处:
- 使数据团队能够追溯验证他们的假设
- 使运营团队能够跟踪已处理数据的问题并快速修复它们
- 在发生故障或数据损坏的情况下提高容错能力;可以通过将整个事件序列应用于损坏的实体来恢复数据的当前状态。
为了降低成本,将日志存储在对象存储中。当收到分析师或研究人员的请求时,创建一个 ETL 作业以将数据从不可变日志流式传输到分析平台,并从那里回放。
根据用户的技能对数据湖进行分层
在数据湖中存储多个数据副本,以服务于范围广泛的消费者。理想的数据管道让这些消费者中的每一个都能使用他们已知的工具访问他们想要的数据——例如,完整(或接近完整)的数据科学家或机器学习算法的原始数据,或者聚合的、更薄的和结构化的版本BI 分析师可以使用它来快速创建报告。可以自动化提取原始数据的 ETL 管道,并根据用例执行相关转换。然后,可以避免依赖数据提供者(DevOps、数据工程)手动工作的瓶颈,例如为每个新请求编写 Apache Spark 等 ETL 框架。
针对不同用户组配置的云数据湖
保持架构开放
鉴于分析行业的快速变化,保持对“面向未来”的架构的开放性至关重要。避免供应商锁定或过度依赖单一工具或数据库。当可以通过广泛的服务使用各种工具提供无处不在的数据访问时,将获得最大的价值。
要创建一个开放式架构:
- 以开放的列式文件格式(例如 Avro 和 Parquet)存储数据,这些格式是标准的、众所周知的并得到广泛支持(与为特定数据库构建的专有文件格式(例如Databricks Delta Lake )相反),这也提高了查询性能。
- 将原始历史数据保留在廉价的对象存储中,例如 Amazon S3。无论使用什么平台来管理数据湖和运行 ETL,保障数据始终可用。
- 使用支持良好的中央元数据存储库,例如 AWS Glue 或 Hive 元存储。可以在一个位置集中管理所有元数据,在此过程中降低基础架构、IT 资源和工程时间方面的运营成本。
优化查询性能
以下最佳实践可提高大多数业务案例的查询性能:
- 适当地分区数据以供您使用
- 转换为高效的列式文件格式
- 经常压缩(合并)小文件
分区数据
如何对数据进行分区对查询成本和速度有重大影响。查询运行更高效、成本更低,因为适当的分区限制了Amazon Athena 等查询引擎为回答特定分析问题而必须扫描的数据量。
数据通常按时间戳进行分区。但是,根据查询,数据可能会被其他字段分区,例如地理或与记录时间戳不同的基于时间的字段。如果可能,根据可能运行的查询类型和分析系统的建议来配置分区的大小。例如,如果大部分查询都需要过去 12 小时的数据,考虑按小时而不是按天进行分区,以减少要扫描的数据量。
转换为高效的列式文件格式
另一种减少扫描数据量的方法。将计划用于分析的数据存储在列式文件格式中,例如 Apache Parquet 或 ORC。使用列式格式,可以仅查询所需的列,从而减少所需的计算量,从而加快查询速度并降低成本。
经常压缩以解决“小文件问题”
数据流每天定期产生数百万个小事件文件。小文件提供更新鲜的数据,但如果直接查询这些小文件,随着时间的推移会降低性能。将小文件合并为大小合适的文件的过程称为压缩。
权衡数据流通的价值与高性能的价值,并根据需要尽可能频繁地压缩文件,以使数据保持最佳文件大小。
三 工具比较:流处理/事件流工具
到目前为止,最常见的事件流工具是 Amazon Kinesis 和 Apache Kafka。
亚马逊Kinesis
Amazon Kinesis 是一种发布-订阅 (pub-sub) 消息传递解决方案。它是 AWS 云中的一项托管服务;配置有限,无法在本地运行 Kinesis。
- 设置/配置:AWS 代表管理流式传输数据所需的基础设施、存储、网络和配置。AWS 还处理硬件、软件和其他数据流服务的配置、部署和持续维护。
- 成本:没有前期设置成本。收费取决于:
- 所需吞吐量所需的分片(分区)数量 每个分片本质上是一个包含数据子集的单独流;Kinesis 每个流有多个分片)。
- 生产者传输到数据流的数据量,因此对于大量数据,成本可能很高。
- 用于:鉴于 Amazon 的高可用性承诺,如果没有用于 24/7 监控、警报和 DevOps 团队从故障中恢复的资源,Kinesis 可能是一个不错的选择。
阿帕奇Kafka
Apache Kafka 是一个开源的 pub-sub 系统,已经发展成为一个成熟的水平可扩展和容错系统,用于高吞吐量数据重放和流。
- 设置/配置:优化 Apache Kafka 的吞吐量和延迟需要同时调整生产者和消费者。服务器端配置——例如,复制因子和分区数——对于通过并行性实现最佳性能也至关重要。为了获得高可用性,必须将 Kafka 配置为尽快从故障中恢复。
- 在 Kafka 中构建 ETL 管道存在挑战;除了数据转换的基本任务外,还必须考虑事件流数据的独特特征。
- 成本:Kafka 需要自己的集群。设置 Kafka 集群需要学习和分布式系统工程实践以及集群管理、供应、自动缩放、负载平衡、配置管理和重要的 DevOps 参与的能力。还需要大量节点(代理)、复制和分区以实现系统的容错和高可用性。
- 用于:实时数据处理;应用程序活动跟踪;日志记录和/或监控系统。
托管Kafka服务
Confluent KSQL和Amazon MSK(Kafka 托管流)都提供部署在云中的离散托管 Kafka 服务。 他们的目标是利用 Kafka 的灵活性和近乎无处不在的特性,同时管理其内在的大部分复杂性。
Confluent Cloud是 Kafka 的完全托管云服务,可加速事件驱动服务和实时应用程序的开发,而无需您管理 Kafka 集群。
- 设置/配置:需要 Java 运行时环境和访问 Kafka 集群以实时读取和写入数据。集群可以在本地或云端。需要为 ksqlDB 服务器和查询设置配置参数,以及底层 Kafka 流和 Kafka 客户端(生产者和消费者)。
- 成本:多种定价模型:每 Gb(数据输入、数据输出、数据存储);每小时计算;每小时分区。
- 用于:用于在云中托管 Kafka。也可用作消息代理,促进企业级系统之间的通信,并将每个系统生成的数据集成到中央位置,例如 Amazon S3。
Amazon MSK是一项完全托管的服务,可简化使用 Apache Kafka 管理消息队列和处理流数据的生产应用程序的构建和运行。
- 设置/配置:MSK 简化了设置和维护。设置和配置基于 Apache Kafka 的部署最佳实践。自动配置并运行您的 Apache Kafka 集群。
- 成本:基于使用情况。需要为代理实例的运行时间、每月使用的存储空间以及集群内外数据的标准数据传输费用付费。
- 用于:维护和扩展 Kafka 集群,启用由完全托管服务支持的端到端摄取管道。还用作不同微服务之间的实时消息代理。