数据工程终极设计模式——数据工程中的架构模式

41 阅读36分钟

引言

在我们已经学习了数据工程基础之后,接下来将进入新的阶段:学习数据如何在各种架构框架中被摄入、处理、存储和服务。我们将更深入地探讨关键数据工程架构的优势、局限性和真实世界应用。

因此,我们将首先考察 Lambda architecture。它是一种 data-processing framework,旨在通过结合 batch 和 stream-processing 方法,在 latency、throughput 和 fault tolerance 之间取得平衡,从而处理海量数据。随后,我们将探索 Kappa architecture。Kappa architecture 通过使用 stream-processing system 同时处理 real-time 和 historical data,简化了数据处理流程,从而消除了对独立 batch processing 的需求。

然后,我们会转向 data mesh 和 data fabric 等现代方法。Data mesh 强调 decentralized data ownership、domain-oriented design 和 self-serve data infrastructure,目标是通过面向领域的去中心化扩展分析数据能力。另一方面,data fabric 关注创建一个集成的数据层,也就是 fabric,用于连接数据和流程,使分布式环境中的数据访问和处理更加无缝。

之后,我们将深入 event-driven 和 microservices-based data architectures,并强调 Apache Kafka 等系统如何支持可扩展的 real-time data pipelines。Event-driven architectures 围绕 events 的生产、检测和响应展开,使系统能够实时响应变化。

理解架构模式固然重要,但选择正确架构还需要评估实际的业务和组织因素。因此,架构决策不应只由技术优雅性驱动,而应由具体上下文驱动。

Cost 是首要考虑因素。Lambda 这类架构会引入双处理层和更高的 infrastructure overhead,从而增加运营和工程成本。因此,如果组织不需要复杂的 batch reprocessing,Kappa 这类更简单的模型可以减少重复,并可能更具成本效益。

Team maturity 会显著影响架构成功。Distributed systems 要求强 DevOps practices、monitoring、incident management 和 operational discipline。如果团队缺乏管理 streaming systems、stateful processing 或 large-scale distributed infrastructure 的经验,更简单的架构可能更可持续、更可靠。

Regulatory and compliance requirements 也会影响设计选择。金融和医疗等行业通常要求 auditability、data lineage,以及重新计算历史结果的能力。因此,在这类环境中,可能需要能够保留 immutable raw data 并支持 controlled reprocessing 的架构。

Operational pain points 经常驱动架构演进。Delayed reporting、data silos、integration challenges 或 scaling issues,可能成为转向 streaming、event-driven 或 decentralized models 的理由。因此,所选架构应直接解决组织最紧迫的约束。

最后,还必须考虑 failure modes。复杂架构会引入更多故障点,包括 synchronization issues、state inconsistencies 或 governance fragmentation。风险容忍度较低的组织,可能会优先选择 simplicity 和 observability,而不是 sophistication。

在实践中,正确架构不是最先进的架构,而是与业务目标、预算、团队能力、监管义务和 operational resilience 对齐的架构。

结构

本章将覆盖以下主题:

  • Lambda Architecture
  • Kappa Architecture
  • Data Mesh and Data Fabric
  • Event-Driven and Microservices-Based Data Architectures
  • Data Lake House Architecture

Lambda Architecture

Lambda Architecture 是一种 data processing framework,旨在高效处理 large-scale、real-time 和 batch data processing。它由三个主要组件组成:

Batch Layer:这一层负责以 batch 方式处理大量数据,并通过重新处理所有可用数据生成准确视图。Apache Hadoop 等技术通常用于这一层。

Speed Layer:也称为 real-time layer,它实时处理 data streams,以提供即时洞察。该层的 views 可能不如 batch layer 的 views 准确或完整,但几乎可以在数据摄入后立即可用。Apache Storm、Apache Spark 和 Apache Flink 等 stream-processing technologies 通常用于这里。

Serving Layer:这一层会索引并暴露 batch layer 和 speed layer 中预计算好的 views。它确保数据被组织好,并可供查询。Apache Druid、Apache Pinot 和 ClickHouse 等技术,都是 serving layer 中常用的系统示例。

Lambda Architecture 有用的原因包括:

Handles High Volume of Data:它同时支持 real-time,也就是 streaming data,以及 batch,也就是 historical data。

Fault Tolerance:它通过在不同层存储数据来确保可靠性。通过同时维护 batch 和 real-time processing paths,系统可以从部分故障中恢复,而不会完全丢失数据。因此,这种 layered redundancy 支持重新计算和错误修正,并提升整体 system resilience 和 availability。

Scalability:它可以 horizontal scale,以处理大型 datasets。

Low Latency and Accuracy:它在提供 real-time insights 的同时,也通过 batch processing 确保 correctness。

Use Case:使用 Lambda Architecture 做 Real-Time Twitter Hashtag Analysis

在这个例子中,我们将构建一个简单的 Lambda architecture pipeline,用于 real-time Twitter hashtag analysis。Tweets 在产生时会被摄入 Kafka。随后,speed layer 会以 near real-time 处理这些 tweets,并更新 Cassandra 中的 sentiment 和 hashtag counts,以支持 low-latency queries。Batch layer 会定期从存储在 file-based data lake 中的 historical data 重新计算 aggregates,以确保 correctness 并处理 late-arriving events。最后,serving layer 使用 Cassandra 存储 speed 和 batch views,并允许 applications 查询最新 real-time insights,同时保持历史准确性。

首先,我们安装以下 dependencies:

pip install kafka-python cassandra-driver pyspark

Speed Layer:从 Kafka 消费并更新 Cassandra

from kafka import KafkaConsumer
from cassandra.cluster import Cluster
import json

# Connect to Cassandra.
cluster = Cluster(['127.0.0.1'])
session = cluster.connect()
session.set_keyspace('twitter_analysis')

# Kafka Consumer:
consumer = KafkaConsumer(
'twitter_stream',
bootstrap_servers=['localhost:9092'],
value_deserializer=lambda x: json.loads(x.decode('utf-8'))
)

# Process real-time tweets.
for message in consumer:
    tweet = message.value
    hashtag = tweet['hashtag']
    sentiment = tweet['sentiment']
    timestamp = tweet['timestamp']

    session.execute("""
    INSERT INTO hashtag_speed_view
    (hashtag, window_start, window_end, tweet_count, last_updated)
    VALUES (%s, %s, %s, %s, %s)
    """, (hashtag, timestamp, timestamp, 1, timestamp))

    print(f"Updated speed layer for hashtag: {hashtag}")

Batch Layer:使用 Spark 重新计算 Historical Aggregates

from pyspark.sql import SparkSession
from pyspark.sql.functions import window, col

spark = SparkSession.builder.appName("BatchLayer").getOrCreate()

# Load historical tweets (stored in data lake).
batch_df = spark.read.format("parquet").load("historical_tweets/")

# Recompute aggregates.
aggregated_df = (
    batch_df
    .groupBy("hashtag")
    .count()
)

aggregated_df.write \
    .format("org.apache.spark.sql.cassandra") \
    .options(table="hashtag_batch_view", keyspace="twitter_analysis") \
    .mode("append") \
    .save()

print("Batch layer recomputation completed.")

在这个设计中,speed layer 提供 low-latency updates,而 batch layer 会定期重新计算 aggregates,以确保 correctness。Cassandra 充当 serving layer,同时为 dashboards 和 APIs 提供 fast reads。最终 application 可以同时查询 batch 和 speed views,以展示准确且实时的 sentiment trends。

Kappa Architecture

Kappa architecture 是一种 data processing framework,它通过移除 batch layer 来简化 Lambda architecture。它不再维护独立的 batch layer 和 speed layer,而是只依赖 stream processing,同时处理 real-time 和 historical data。

Lambda 和 Kappa architecture 的区别如下:

Single Stream Processing Layer:不同于 Lambda 同时拥有 batch 和 speed layer,Kappa architecture 会将所有数据作为 real-time streams 处理。

No Separate Batch Pipeline:在 Kappa Architecture 中,没有专门的 batch layer,也没有独立的 batch processing stack。Historical,也就是 backfill computation,仍然会执行,但它是通过 replay event stream,或者从同一个 immutable log 中读取,并经过同一个用于 real-time processing 的 stream-processing job 完成的。换句话说,Kappa 将 real-time 和 historical processing 统一到一条路径中,这条路径就是 stream processing 和 replay for reprocessing。

Simpler Architecture:它消除了合并 batch 和 real-time views 的复杂性。

Efficient for Streaming Use Cases:它最适合 real-time processing 是优先事项的场景,例如 fraud detection、social media analytics 或 sensor data processing。

将 Twitter Analysis Code 从 Lambda 转换为 Kappa

在 Kappa architecture 中,我们将移除独立 batch pipeline,并使用同一个 streaming job 同时处理 historical 和 real-time data。Historical reprocessing 通过 replay immutable log 实现,通常是 Kafka,或 Kafka 与 object storage 的组合。在这个例子中,tweets 会持续摄入 Kafka;当需要 reprocessing 时,Spark structured streaming 会从 earliest available offset 开始处理它们。处理后的 outputs 会写入 Cassandra,作为 low-latency serving store,因为查询模式通常是“按 hashtag 或 time window 获取最新 trends / sentiment”,而 Cassandra 通过高写入吞吐和快速 key-based reads 可以高效支持这种模式。重要的是,为了达到 production readiness,我们会包含 checkpointing,用于 restart safety;避免 collect(),用于 scalability;并承认 retention cost、compliance、schema evolution 和 late data handling 等问题。代码如下:

# pip install cassandra-driver pyspark

from cassandra.cluster import Cluster
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, from_json, to_timestamp, window
from pyspark.sql.types import StructType, StructField, StringType

# 1) Cassandra Connection (Serving Store):
cluster = Cluster(['127.0.0.1'])
session = cluster.connect()
session.set_keyspace('twitter_analysis')

# NOTE: Cassandra fits here as a serving store for high-write, low-latency queries.
# (for example, "latest sentiment trend for #AI" or "top hashtags in last 10 minutes").
# It should store aggregates/views, not just raw events.

# 2) Spark Session:
spark = SparkSession.builder.appName("TwitterKappaStreamingProcessor").getOrCreate()
spark.sparkContext.setLogLevel("WARN")

# 3) Define schema (helps with schema evolution and safer parsing).
tweet_schema = StructType([
    StructField("tweet_id", StringType(), True),
    StructField("user_id", StringType(), True),
    StructField("text", StringType(), True),
    StructField("hashtag", StringType(), True),
    StructField("sentiment", StringType(), True),
    StructField("timestamp", StringType(), True),  # ISO-8601 preferred
])

# 4) Read from Kafka (historical and real-time).
tweets_df = (
    spark.readStream
    .format("kafka")
    .option("kafka.bootstrap.servers", "localhost:9092")
    .option("subscribe", "twitter_stream")
    .option("startingOffsets", "earliest")   # replay for reprocessing
    .load()
)

# 5) Parse JSON safely.
tweets_parsed = (
    tweets_df.selectExpr("CAST(value AS STRING) AS json_str")
    .select(from_json(col("json_str"), tweet_schema).alias("t"))
    .select("t.*")
    .withColumn("event_time", to_timestamp(col("timestamp")))
)

# 6) Handle late data (watermark) and compute a simple aggregate view.
# Example: Per-hashtag counts in 1-minute windows
agg = (
    tweets_parsed
    .withWatermark("event_time", "10 minutes")  # late data allowed up to 10 mins
    .groupBy(window(col("event_time"), "1 minute"), col("hashtag"))
    .count()
)

# 7) Write to Cassandra using foreachBatch WITHOUT collect() (scalable pattern).
# We do partitioned inserts (still illustrative; production may use Spark Cassandra connector).
def write_aggregates_to_cassandra(batch_df, batch_id):
    rows = batch_df.select(
        col("hashtag").alias("hashtag"),
        col("window.start").cast("timestamp").alias("window_start"),
        col("window.end").cast("timestamp").alias("window_end"),
        col("count").alias("tweet_count"),
    )

    def write_partition(iterator):
        # create Cassandra session per executor partition (simple pattern)
        from cassandra.cluster import Cluster
        cl = Cluster(['127.0.0.1'])
        sess = cl.connect()
        sess.set_keyspace('twitter_analysis')

        for r in iterator:
            sess.execute("""
            INSERT INTO hashtag_trend_view (hashtag, window_start, window_end, tweet_count)
            VALUES (%s, %s, %s, %s)
            """, (r["hashtag"], r["window_start"], r["window_end"], int(r["tweet_count"])))

        cl.shutdown()

    rows.foreachPartition(write_partition)

# 8) Checkpointing ensures exactly-once progress tracking (prevents data loss on restart).
query = (
    agg.writeStream
    .foreachBatch(write_aggregates_to_cassandra)
    .option("checkpointLocation", "/tmp/twitter_kappa_checkpoints/hashtag_trends")
    .outputMode("update")
    .start()
)

query.awaitTermination()

Notes to Readers(Important Best Practices)

Kafka as “historical store” is a trade-off:保留长 retention 可能会很昂贵,并且可能与 compliance 或 data governance requirements 冲突。因此,在许多生产环境中,Kafka 是有界时间内可 replay 的 log,而 durable long-term history 会存储在 object storage,例如 S3、GCS、ADLS 中,并且可以选择性重新发布到 Kafka 用于 backfills。

Checkpointing is mandatory in streaming jobs:没有 checkpointing 时,重启可能导致 reprocessing 或 skipping,这取决于 offsets 和 failures。

Late data handling is important in real pipelines:Watermarking 是一种常见方法,用于限制 state growth,同时仍然纳入 late arrivals。

Schema evolution should be planned:应使用 schema registry,或 versioned schemas,使 producers 和 consumers 能随时间安全演进。

Avoid collect() :使用 distributed writes,例如 foreachPartition 或合适的 Cassandra connector,并围绕 query patterns 设计 Cassandra tables,例如 partition keys 和 clustering keys。

Data Mesh and Data Fabric

Data mesh 和 data fabric 是现代数据架构,用于处理企业数据日益增长的复杂性。下面我们深入探讨每个概念。

Data Mesh

许多组织投资建设 central data lake,并期望它成为 single source of truth,且所有数据需求都能被满足。然而,随着复杂性增加,我们经常会看到 central data team 成为服务各部门需求的瓶颈。该团队无法及时响应 management 和 product owners 提出的所有 analytical questions。这是一个大问题,因为及时的数据驱动决策对保持竞争力非常必要。

Data team 希望按时回答所有这些问题。但实际上,他们做不到,因为他们已经花了太多时间修补由于 operational database modifications 导致损坏的数据管道。因此,在有限时间内,data team 必须去寻找并学习所需的 domain data。他们必须为每一个问题学习 domain knowledge,才能生成相关 insights。这是一项巨大的任务,因为获取所需 domain expertise 非常困难。

另一方面,公司也已经投资了 domain-driven design、independent domain teams,也称为 stream-aligned teams 或 product teams,以及 decentralized microservice architecture。Domain teams 熟悉自己的 domain,包括业务信息需求。他们独立设计、构建并运行自己的 web applications 和 APIs。尽管他们了解 domain 及其周围的信息需求,但 domain teams 仍然需要去找已经不堪重负的 central data team,以获得必要的数据驱动洞察。

因此,随着组织最终扩张,domain teams 和 central data team 的健康状况都会受损。解决方法之一,就是将数据 ownership 从 central data team 下放到 domain teams。这就是 data mesh philosophy 的总体思想,即对 analytical data 实施 domain-oriented decentralization。因此,data mesh architecture 让 domain teams 能够像 microservices architecture 中的 APIs 一样,独立执行 cross-domain data analysis 并连接数据。

Data Mesh 的原则

Zhamak Dehghani 于 2019 年首次使用 data mesh 这一术语,它基于四个构建在成熟概念之上的基本原则:

Data Ownership 原则 意味着 domain teams 是其数据的 owners。因此,分析数据需要基于 domains 组织,而 domains 是根据该原则,将团队边界映射到系统 bounded context 的方式。一旦 domain-driven distributed architecture 建立起来,analytical 和 operational data ownership 就不再集中于 central data team,而是存在于 domain teams 中。

Data as a Product 原则 将 product thinking mindset 引入被分析的数据。该原则意味着除了 domain 之外,还有其他 data consumers。因此,domain team 必须通过交付高质量数据来满足其他 domains 的需求。本质上,domain data 必须像任何其他 public API 一样被对待。

Self-Serve Data Infrastructure Platform 的理念,是将 platform thinking 带入 data infrastructure。有一个 data platform team 提供 domain-agnostic functions、tools 和 systems,用于为所有 domains 构建、执行和管理 interoperable data products。通过这种方式,data platform team 让 domain teams 能更容易地通过平台消费和构建 data products。

Federated Governance 原则 通过 standardization 实现所有 data products 的 interoperability,这种标准化由 governance team 在整个 data mesh 中推广。Federated governance 最显著的目标,是根据组织规则和行业法规创建一个 data ecosystem。

设计 Data Mesh

实施 Data Mesh 需要组织变革、技术赋能和文化转变。下面我们逐步了解如何在组织中实施 data mesh:

Identify and Define Data Domains:分析业务领域,然后将其分组为 logical domains,例如 Customer、Payments、Marketing、Risk 和 Finance。将数据 ownership 分配给生成和使用该数据的 domain teams。

Treat Data as a Product:确保每个 domain 像管理产品一样管理自己的数据,具备清晰 SLAs(Service Level Agreements)、metadata 和用于数据消费的 APIs。提供 data catalog,以便 easy discovery。

Build a Self-Serve Data Infrastructure:为 domain teams 提供 self-service platform,使其具备以下能力:

  • Storage,例如 Amazon S3、Delta Lake 和 Snowflake
  • Processing,例如 Apache Spark、dbt 和 Airflow
  • Serving APIs,例如 GraphQL 和 REST
  • Data Discovery,例如 Amundsen 和 DataHub

Establish Federated Governance:采用标准化 data formats,例如 Parquet、Avro。确保 APIs 和 event-driven architectures,例如 Kafka、Pulsar,支持 domains 之间无缝 data exchange。

Continuous Evolution and Scaling:从少数关键 domains 开始,迭代,并逐步扩展。定期审查 infrastructure、governance 和 performance。

Data mesh 非常适合拥有多个 business units 和去中心化数据需求的大型复杂企业。它不适合数据集中且团队有限的小型组织。

Use Case:银行业 Data Mesh

我们以一家银行公司实施 data mesh 为例。

一家银行公司在不同业务职能之间负责许多重要数据,包括 customers、accounts、loans、risk scoring、fraud detection 和 regulatory compliance。因此,银行业 data mesh 可以在不牺牲 security 和 regulatory compliance,例如 RBI、SEC 等要求的情况下,提供 scalability、responsiveness 和 improved data governance。

Identify and Define Data Domains

银行公司可以基于以下业务职能构建 data domains:

Data DomainData OwnerData Examples
Customer DataCustomer Service、CRMKYC、Personal Details、Transaction History
Accounts and TransactionsCore Banking TeamAccount balances、deposits、withdrawals、payments
Loans and CreditLending and Risk TeamLoan applications、risk scores、credit bureau reports
Fraud DetectionSecurity and Risk TeamSuspicious transactions、AML(Anti-Money Laundering)alerts
PaymentsPayments and OperationsUPI、NEFT、RTGS、Card transactions
Regulatory and ComplianceCompliance and AuditRBI reports、transaction logs、PII data management
Wealth ManagementInvestment and Portfolio TeamMutual funds、stock trading、portfolio analytics

表 3.1:定义 Data Domains

每个 domain team 都负责自己的数据,并确保 data quality、security 和 usability。

Treat Data as a Product

每个 domain 的数据都像产品一样管理,具备:

  • 针对 data freshness 和 reliability 的清晰 SLAs
  • 支持 seamless integration 的 APIs 和 event streams
  • 用于 discoverability 的 data cataloging

例如:

  • Loan team 提供 risk score API,供 underwriting teams 使用。
  • Payments team 为 transaction monitoring 提供 real-time fraud detection API。

Build a Self-Serve Data Infrastructure

Self-service data platform 使 teams 可以通过以下方式独立管理数据:

ComponentTechnology Stack
StorageDelta Lake(on AWS S3)、Snowflake 和 Google BigQuery
ProcessingApache Spark、dbt、Airflow 和 Flink
Streaming and MessagingKafka、Pulsar
Query LayerTrino、Presto 和 GraphQL

表 3.2:Self-Serving Data Infrastructure

因此,每个 domain team 都可以独立 store、process 和 serve data,而无需依赖 central IT team。

Establish Federated Governance

由于银行涉及严格监管合规,例如 RBI、GDPR、PCI DSS 等,governance 是 federated 但 standardized 的。

  • Data contracts 跨 domains 执行 consistency。
  • RBAC(Role-Based Access Control)确保 secure access。
  • 标准化 data formats,例如 Parquet、Avro 和 ORC,用于 interoperability。

例如:

  • Fraud detection team 只与 risk team 共享 anonymized customer data。
  • Regulatory team 确保 PII(Personally Identifiable Information)在被共享时已经 masked。

Continuous Evolution and Scaling

从小处开始,验证,然后逐步扩展。

银行业 Data Mesh 中的潜在失败场景

虽然 data mesh 提供 scalability 和 domain ownership,但它并不会因为设计理念本身就自动成功。在银行环境中,实施不当可能引入 fragmentation、inconsistency 和 regulatory risk。因此,在采用之前理解潜在失败场景至关重要。这些场景包括:

缺乏强大的 Platform Team:Data mesh 需要一个稳健的 centralized platform team,用于构建和维护 shared self-serve infrastructure,包括 storage、CI/CD pipelines、cataloging、security controls、monitoring 和 lineage tracking。如果缺少这个 enabling layer,domain teams 可能会创建不一致 tooling、重复 pipelines 和不兼容 standards。在银行业,这种不一致可能导致 compliance violations 和 operational instability。因此,没有强大 platform backbone 的 data mesh,常常会退化为带有分布式 ownership 的 data silos。

Federated Governance 没有 Enforcement:Federated governance 必须被标准化并执行。如果 domains 对 governance rules 的解释不同,或者绕过 data contracts,组织就可能出现关键指标定义不一致的问题,例如 risk exposure、liquidity ratios 或 fraud indicators。在受监管银行环境中,例如 RBI、SEC、GDPR、PCI DSS,薄弱的 governance enforcement 可能导致 audit failures 和 penalties。因此,data mesh 中的 governance 必须通过 policies、access controls、schema validation 和 monitoring 自动化执行,而不能依赖 voluntary compliance。

跨 Domains 的 Data Definitions 不一致:如果每个 domain 对 customer、account status 或 risk score 的定义不同,cross-domain analytics 就会不可靠。这会导致 dashboards 冲突,并在 executive level 造成决策混乱。因此,需要 shared semantic standards 和清晰定义的 data contracts,以防止 metric drift。

Security 和 Access Mismanagement:Decentralization 会增加 access controls 配置错误的风险。不恰当的 RBAC 或缺少 encryption standards,可能暴露 sensitive financial 或 PII data。因此,需要强 centralized security policies 与 domain-level accountability 结合。

Domain Teams 的 Operational Immaturity:如果 domain teams 缺乏 data engineering maturity,它们可能难以履行 SLA commitments、monitoring 或 quality assurance。这会降低对 domain-owned data products 的信任。因此,data mesh 需要的不只是 structural decentralization,也需要 capability decentralization。

Data Fabric

Data fabric 是一种 architectural approach,由一组 technologies 支撑,支持组织范围内无缝 data access、integration 和 governance,无论数据位于 on-premises、cloud、SaaS applications,还是 hybrid environments 中。它的主要目标是减少 data silos,并改善 business users、analysts 和 application developers 的 self-service data access。

Data fabric 不完全依赖大规模数据整合,而是强调通过 metadata management、data virtualization 和 automated governance 实现 intelligent data integration。在很多情况下,数据会保留在原始 source systems 中,并通过 virtualized query layers 访问。不过,有限 data movement 仍然可能发生,例如 metadata synchronization、query result caching、materialized views 或 performance-optimized replicas。其目标并不是完全消除 data movement,而是尽量减少不必要 duplication,同时在分布式数据环境中支持 unified access、governance 和 consistency。

因此,data virtualization 是任何 data fabric 的核心,因为它是将 sources 与 consumption 分离的 middle layer。它是 consolidation、governance 和 data providing 的层。现在,我们来探索 data virtualization 的具体含义。

Data Virtualization

Data virtualization 是 Data Fabric 中的核心技术,它可以在不物理移动或复制数据的情况下,实现对 distributed data 的 real-time access。它创建一个 virtualized layer,连接多个 data sources,例如 on-prem、cloud、SaaS、APIs,并允许 users 无缝查询和集成数据。

它可以:

  • 在多个 databases、data lakes 和 SaaS applications 之间创建 unified view of data。
  • 支持 real-time queries,而不需要将数据物理存储到一个地方。
  • 支持跨 structured 和 unstructured data sources 的 federated queries。
  • 动态应用 security 和 governance policies,以执行 compliance。

Data virtualization 按以下方式工作:

Connecting to Multiple Distributed Data Sources

Data virtualization engine,例如 Presto、Trino、Denodo、IBM Data Fabric、Starburst 等,会连接多个 heterogeneous data sources,包括:

  • SQL Databases:PostgreSQL、MySQL、SQL Server 和 Oracle
  • NoSQL Databases:MongoDB、Cassandra
  • Data Lakes:AWS S3、Google BigQuery、Delta Lake 和 Snowflake
  • Streaming Platforms:Kafka、Pulsar
  • SaaS Applications and APIs:Salesforce、SAP、Workday 和 Stripe

Data connectors,例如 JDBC、ODBC、REST API 和 Kafka adapters,会建立到这些 sources 的连接。此外,data virtualization layer 不复制数据,而是注册有关 data source structure 的 metadata。

示例:一家银行公司拥有:

  • PostgreSQL 中的 Customer Data
  • AWS S3 中的 Loan Data,格式为 Parquet
  • 来自 External API 的 Risk Scores

Virtualization engine 会实时连接所有这些 sources,而不创建 ETL pipelines。

创建 Virtualized Semantic Layer(Metadata Mapping)

Data virtualization engine 会扫描每个 source,然后创建一个 metadata layer,理解以下内容:

  • Data Schema:Tables、Columns、Data Types
  • Indexes 和 Primary Keys
  • Tables 之间的 Relationships
  • Security 和 Access Control Policies

Engine 会构建不同 sources 之间如何关联的 internal mapping,同时支持 federated queries,而不复制数据。

示例:

  • PostgreSQL Table:customer_info (id, name, account_number)
  • AWS S3 File:loan_data.parquet (loan_id, account_number, risk_score)
  • API Response:{ "account_number": "12345", "credit_score": 750 }

Data virtualization layer 会创建 unified logical schema,其中:

  • account_number 是跨 sources 的 common key。
  • 数据被虚拟连接,但仍保留在 source 中。

Query Federation and Optimization:Queries 如何实时执行

当用户运行 query 时,virtualization engine 会:

  1. 将 query 拆分为每个 data source 的 sub-queries。
  2. 将 computation 下推到 source,即 Predicate Pushdown。
  3. 优化 query execution,例如 index selection、query pruning。
  4. 即时 join 跨 sources 的数据。

对于 non-SQL sources,例如 APIs、NoSQL 和 streams,virtualization layer 会将 SQL queries 转换为适当的 API 或 NoSQL commands。

示例 Query:Risk analyst 针对 virtualized data layer 运行以下 SQL query:

SELECT c.name, l.loan_id, l.risk_score, r.credit_score
FROM customer_info c
JOIN loan_data l ON c.account_number = l.account_number
JOIN credit_api r ON l.account_number = r.account_number
WHERE l.risk_score > 700;

Backend 中会发生以下过程:

Step 1:Query engine 会拆分 query:

  • 从 PostgreSQL 获取 name
  • loan_data.parquet 获取 loan_idrisk_score
  • 为每个 account_number 调用 credit score API

Step 2:每个 query 在对应 source 上运行:

  • PostgreSQL 执行:SELECT name, account_number FROM customer_info
  • AWS S3 执行:SELECT loan_id, risk_score FROM loan_data WHERE risk_score > 700
  • API Calls 返回:{ "account_number": "12345", "credit_score": 750 }

Step 3:Data virtualization layer 在内存中执行最终 join,并返回结果。

数据不会被移动,只有 results 会被合并。

Security and Governance Enforcement:Real-Time Data Masking and Access Control

Dynamic Data Masking:确保基于 user roles 保护 sensitive data。

Row-Level and Column-Level Access Control:动态控制谁可以看到哪些数据。

Data Lineage and Auditing:记录谁在何时访问了什么数据,以支持 compliance。

示例:

  • Loan officer 可以看到 risk scores,但看不到 credit scores。
  • Compliance auditor 可以访问 anonymized PII data。
  • Fraud analyst 只能查看 suspicious transactions。

所有这些都会在 virtualization layer 中动态执行,而不会修改 source data。

Delivering Data to Consumers:BI、AI/ML、APIs

Data 通过多种格式暴露,包括:

  • SQL Querying:Presto、Trino、Denodo
  • BI Dashboards:Power BI、Looker、Tableau
  • GraphQL 和 REST APIs:用于 Real-Time Applications
  • ML Pipelines:用于 AI-Driven Risk Models

示例:Fraud detection AI model 通过以下接口请求 real-time transaction data:

GET /api/fraud_transactions?account_number=12345

Data virtualization engine 会动态地只从 Kafka(real-time)、S3(historical)和 SQL(customer profile)中获取最新 transactions。

Data Mesh vs. Data Fabric

Data mesh 和 data fabric 都是现代数据架构,旨在解决 scalability、data silos、governance 和 real-time access 等挑战。但它们的方法存在根本差异:

  • Data mesh 聚焦 decentralized ownership、domain-driven design,并将 data as a product。
  • Data fabric 强调 centralized integration、AI-driven metadata management 和 automated governance,同时支持对 distributed data sources 的 federated access。
FeatureData MeshData Fabric
ArchitectureDecentralizedCentralized integration
Data OwnershipOwned by domain teams(business units)Managed centrally,accessible across the enterprise
Data AccessAPIs、event-driven data sharingVirtualized、federated access without duplication
GovernanceFederated governance by domain teamsAI-driven metadata and policy automation
Data MovementData remains within the domain boundariesNo data movement;virtualized access across sources
Data IntegrationRelies on APIs、event streaming 和 data contractsUses metadata-driven data virtualization
Use CaseBest for scaling distributed、domain-driven data architectureBest for integrating and managing data across hybrid and multi-cloud environments
Security and ComplianceEnforced per domainCentralized、AI-driven compliance enforcement
FlexibilityHigh(teams control their own data products)Medium(predefined governance and metadata-driven access)
Self-Service AnalyticsAvailable within each domainAvailable across the enterprise via a unified platform
Best ForLarge、complex enterprises with multiple data-producing teamsOrganizations needing real-time、unified data access across platforms

表 3.3:Data Mesh 和 Data Fabric 对比

接下来,我们将进入 event-driven 和 microservices-based data architectures。

Event-Driven and Microservices-Based Data Architectures

传统数据架构长期依赖 batch ETL processes 和 scheduled data pipelines。虽然 batch processing 对 large-scale analytical workloads 仍然非常有效,但它可能无法满足需要 low-latency responsiveness、continuous updates 或 real-time decision-making 的 use cases。因此,随着数字系统向 instant payments、fraud detection、IoT monitoring 和 personalized customer experiences 演进,组织越来越需要能够在 events 发生时作出响应的架构。

Event-driven 和 microservices-based data architectures 正是为满足这一需求而出现的,它们允许 systems 以 near real-time 的方式 publish、detect 和 respond to events。因此,系统不再只依赖 periodic data extraction,而是在有意义的变化发生时发出 events,例如 transaction 被处理、loan application 被提交,或 fraud rule 被触发。Apache Kafka、Pulsar 和其他 streaming platforms 等技术允许这些 events 被多个 downstream services 消费,从而创建 scalable、loosely coupled data ecosystems。

重要的是,event-driven architectures 并不会完全取代 batch systems。相反,它们是互补关系。Batch processing 仍然服务 analytical、historical 和 reconciliation workloads,而 event-driven systems 则驱动 operational intelligence 和 real-time responsiveness。二者共同构成一种 hybrid data architecture,可以支持现代企业中的 accuracy 和 agility。

解决方案是采用 event-driven data architecture,这是一项重大转变,可以实现 event-driven data 的 real-time ingest 和 processing,并减轻 databases 的压力。

因此,许多组织依赖 scheduled batch ETL pipelines,它们按固定间隔从 databases 和 file systems 中抽取数据。虽然这一直是传统方法,但它带来两个主要问题:

Increased Load on the Source System

ETL pipelines 会频繁查询 application databases,以获取 updated data。

即使使用 delta approach,也就是只获取 new records,这些 queries 也经常会扫描整张 tables,导致高 compute costs,并可能降低 live applications 的性能。

示例:一个使用 MySQL database 的 e-commerce site 每晚运行 batch job 提取 order data。这个 job 会扫描数百万 records,尽管只有几千个 orders 是新的。

Data is always stale

Batch ETLs 按固定 schedule 运行,例如 hourly、daily。

Job 开始之后发生的任何 changes,都要等到下一次执行才会被捕获。

Fraud detection、user analytics 和 personalized recommendations 等 real-time use cases 会因此无法实现。

示例:一个 fraud detection system 如果每 12 小时才更新一次数据,就无法在 fraudulent transactions 发生时捕捉到它们。

Event-Driven Data Architecture

Event-driven architectures 不轮询 databases,而是在数据生成的瞬间捕获数据,并实时 push 给 consumers。它们的工作方式如下:

  1. An Event Occurs:用户下单、文件上传或 transaction 被处理。
  2. Event is Published:系统生成一个包含相关数据的 event。
  3. Event is Pushed to a Queue or Stream:Kafka、RabbitMQ 或 AWS Kinesis 等 message brokers 分发该 event。
  4. Events are Processed in Real-Time:Downstream consumers,例如 data warehouse 或 analytics engine,立即接收并处理数据。

实现 event-based data architecture 的方法如下:

Use Change Data Capture(CDC)for Databases:不是轮询 databases,而是使用 Change Data Capture(CDC)在 changes 发生时提取它们。

  • 它监控 database logs,以检测 inserts、updates 和 deletes。
  • 它将 changes 推送到 Kafka、Kinesis 或其他 event streams。
  • 它确保 low latency,并减少 database query load。

Leverage Message Queues and Event Streaming:不要先将数据直接写入 database,而是推送到 message queue 或 event stream 中进行 real-time processing。

Process Data Before It Hits the Database:不要在 event 发生后再从 database 拉取数据,而是必须在写入 database 前捕获 events。你还应记住:

  • 修改 backend APIs,使其在写入 database 前将 event 发送到 queue。
  • Consumers 从 queue 中读取,然后实时将数据写入 warehouse 或 analytics system。

Optimize File-based Event Ingestion:许多企业依赖来自 IoT devices、logs 或 external partners 的 file-based data ingestion。

  • Use Event Triggers:不要轮询新 files,而是使用 event notifications,例如 AWS S3 event notifications 或 Google Cloud Pub/Sub。
  • Stream Processing:在 files 到达时增量处理,而不是等待 batch jobs。
  • Auto-Scaling Functions:AWS Lambda 和 Google Cloud Functions 等 serverless tools 可以动态处理 file events。

Event-driven architectures 相比传统 batch ETLs 更优,因为它们提供 real-time data processing,同时减少 database strain,并提升 scalability。

Use Case:E-Commerce Platform 中的 Real-Time Order Processing

一个 e-commerce platform 每天处理数千个 orders。目前,order data 存储在 MySQL database 中,ETL job 每 12 小时运行一次,将 order data 转移到 data warehouse,例如 Redshift 或 Snowflake,用于 analytics 和 reporting。

Challenges with Batch ETL:

Database Load:Batch job 查询整张 orders table,导致 CPU 使用率高,并拖慢 live transactions。

Stale Data:由于 ETL job 每天只运行两次,warehouse 中的数据总是延迟数小时。

Inflexibility:Marketing team 希望获得 real-time order insights,但当前 setup 不支持。

因此,与其运行 batch job,不如在每次 order placed 时捕获 real-time events,并立即 stream 数据到 warehouse。这将通过以下方式实现:

  1. Order Service(Microservice) 将 order data 写入 MySQL database,并发布 event。
  2. Message Broker(Kafka 或 RabbitMQ) 捕获 event,并发送给感兴趣的 consumers。
  3. Event Consumer(ETL Service) 处理 event,并实时更新 warehouse。
  4. 最终,analytics dashboard 会立即获得 fresh order data。

Step-by-Step Implementation

下面逐步实现 event-driven data architecture。

Step 1:Capture Order Events

修改 Order Service,使其在 order 创建时发布 event。

Example:Order Event(JSON Format)

{
"order_id": "12345",
"user_id": "56789",
"amount": 250.75,
"payment_status": "Paid",
"order_status": "Processing",
"timestamp": "2025-03-12T10:30:00Z"
}

我们不只将该数据存储在 MySQL 中,还会将其推送到 Kafka 中进行处理。

Step 2:Set up Apache Kafka for Event Streaming

Kafka 作为 event broker,会 queue incoming events,然后将它们分发给 consumers。

Kafka Topic Setup:

创建名为 order_events 的 Kafka topic:

kafka-topics.sh --create --topic order_events --bootstrap-server localhost:9092 --partitions 3 --replication-factor 2

现在,每当 order 被下单时,一个 event 就会被发送到 order_events

Step 3:Consume Events and Load Data to the Warehouse

一个 Python consumer service 会持续监听 Kafka events,然后将数据写入 Snowflake / Redshift。

Python Consumer Service

from kafka import KafkaConsumer
import json
import psycopg2  # Assuming PostgreSQL-based Data Warehouse

# Connect to Kafka.
consumer = KafkaConsumer(
'order_events',
bootstrap_servers='localhost:9092',
value_deserializer=lambda x: json.loads(x.decode('utf-8'))
)

# Connect to Data Warehouse (Redshift/Snowflake).
conn = psycopg2.connect(
dbname="data_warehouse",
user="admin",
password="password",
host="warehouse-host",
port="5439"
)
cursor = conn.cursor()

# Process the Incoming Order Events.
for message in consumer:
    order = message.value

    query = """
    INSERT INTO orders (order_id, user_id, amount, payment_status, order_status, timestamp)
    VALUES (%s, %s, %s, %s, %s, %s)
    """

    cursor.execute(query, (
        order["order_id"],
        order["user_id"],
        order["amount"],
        order["payment_status"],
        order["order_status"],
        order["timestamp"]
    ))

    conn.commit()

print("Order events processed successfully!")

Step 4:Set up the Real-Time Analytics Dashboard

由于数据现在已经实时 streaming,我们可以使用 Apache Superset、Metabase 或 Power BI 构建 interactive dashboard。

示例:

  • 显示每分钟 live order count。
  • 按 region 展示 average order value。
  • 实时识别 failed payments。

从 batch-based ETL 切换到 event-driven data pipeline,可以显著提升性能、降低 latency,并增强 scalability。因此,通过利用 Kafka、Change Data Capture(CDC)和 real-time ingestion,组织可以构建 resilient 和 real-time data architectures。

Microservices-Based Data Architecture

Microservices data architecture 是从 monolithic architecture 出发的一次根本转变,提供 scalability、flexibility 和 modularity。在 data microservices architecture 中,有许多小型、自治 services,用于管理不同系统之间数据的 flow、transformation 和 enrichment。因此,它们是 loosely coupled 的,并且协同运行,以提供高效 resource usage、fault tolerance 和 flexibility。

不同于 monolithic architectures 中某个组件 workload 增加会影响整个系统,microservices 确保每个 service 可以根据实际 demand 独立扩展。

下面我们逐步了解如何构建 microservice-based data architecture。

Step 1:Define Business Requirements and Identify Services

从识别核心业务功能及其之间的数据交互开始。

示例:E-Commerce Platform 需要的 services 包括:

  • User Service:管理 user authentication 和 profiles
  • Orders Service:处理 order placements
  • Payments Service:处理 transactions
  • Inventory Service:跟踪 stock levels
  • Shipping Service:处理 order fulfillment
  • Analytics Service:提供 business intelligence

这些 services 中的每一个都将独立管理自己的数据。

Step 2:Choose the Right Data Storage for Each Microservice

由于每个 microservice 都拥有自己的数据,因此必须选择最适合的 database。

MicroserviceRecommended DatabaseReason
User ServicePostgreSQL / MySQLRelational data with ACID transactions
Orders ServicePostgreSQLEnsures transactional consistency
Payments ServiceMongoDBFlexible schema for transactions
Inventory ServiceRedisFast key-value store for real-time stock updates
Shipping ServiceDynamoDBScalable NoSQL for shipping data
Analytics ServiceElasticsearch / SnowflakeHigh-speed analytics and BI

表 3.4:每个 Microservice 的 Data Storage

Step 3:Implement Event-Driven Communication

Microservices 应避免 direct API calls,而应使用 event-driven messaging。

How It Works:

  • User places an order → Orders Service 发布 order_placed event。
  • Payments Service 监听 order_placed 并处理 payment。
  • Inventory Service 监听 payment_successful 并更新 stock。
  • Shipping Service 监听 order_shipped 并启动 delivery。

Recommended Tools:

  • Kafka:High-throughput event streaming
  • RabbitMQ:Lightweight messaging
  • AWS SQS:Managed queue service

Step 4:Implement the API Gateway for Secure Service Communication

不要直接暴露单个 microservices,而是通过 API Gateway 路由所有 requests,原因如下:

  • Centralized Authentication and Authorization
  • Load Balancing and Rate Limiting
  • Request Aggregation

Step 5:Implement Data Observability and Monitoring

Microservices architectures 需要 end-to-end observability,用来监控:

  • Services 之间的 Data Flow
  • Schema Changes and Anomalies
  • Latency and Failure Rates

Use Case:Ride-Sharing Platform 的 Microservices-Based Data Architecture

我们将 microservices 概念应用到类似 Uber 或 Lyft 的公司。

Step 1:Define Business Requirements and Identify Services

像 Uber 或 Lyft 这样的 ride-sharing platform 需要多个独立 microservices 来处理不同业务功能。每个 service 独立运行,并通过 event-driven messaging 与其他 services 交互。

Core Microservices:

  • User Service:管理 user authentication、profiles 和 preferences
  • Ride Service:处理 ride requests、ride matching 和 ride history
  • Payment Service:处理 ride payments、refunds 和 invoices
  • Driver Service:管理 driver onboarding、availability 和 ratings
  • Location Service:跟踪 drivers 和 users 的 real-time locations
  • Notification Service:发送 SMS、emails 和 push notifications

Step 2:Choose the Right Data Storage for Each Microservice

由于每个 microservice 有不同数据需求,我们为每个选择最适合的 database。

MicroserviceRecommended DatabaseReason
User ServicePostgreSQL / MySQLEnsures ACID compliance for user data
Ride ServicePostgreSQLMaintains ride transactions and history with consistency
Payment ServiceMongoDBFlexible schema for transactions、payment records 和 invoices
Driver ServiceDynamoDBNoSQL ensures fast retrieval of driver availability and history
Location ServiceRedisFast key-value storage for real-time driver tracking
Notification ServiceAWS SQS / FirebaseSupports async messaging and push notifications
Analytics ServiceSnowflake / ElasticsearchHigh-speed BI analytics and reporting

表 3.5:Uber 或 Lyft Use Case 的 Data Storage

Step 3:Implement Event-driven Communication

Microservices 不使用 direct API calls,而是使用 event-driven messaging,以获得 scalability 和 resilience。

Workflow of a Ride Booking:

  • User Requests a Ride:ride_requested event 被发布到 Kafka。
  • Ride Service Matches a Driver:driver_assigned event 被发布。
  • Driver Arrives at the Pickup Point:driver_arrived event 被发布。
  • Ride Starts and Completes:ride_completed event 被发布。
  • Payment Service 监听 ride_completed:处理 payment。
  • Notification Service 监听 ride_completed:向 user 发送 receipt。
  • Analytics Service 监听 ride_completed:更新 ride metrics。

Step 4:Implement API Gateway for Secure Service Communication

不要暴露单个 microservices,所有 requests 都通过 API Gateway。

Step 5:Implement Data Observability and Monitoring

由于多个 microservices 处理关键 real-time operations,data observability 确保系统性能平稳,并能检测故障。

Observability Features:

  • Monitor Data Flow:确保 ride requests 被正确处理。

  • Track Schema Changes:检测 event formats 中的意外修改。

  • Identify Latency Issues:标记 ride-matching 缓慢或 payment failures。

  • Alerting and Anomaly Detection:在以下情况发送 alerts:

    • Driver 在 2 分钟内没有被分配 ride。
    • Ride 没有在预期时间内完成。
    • Payments 失败率超过某个 threshold。

Final Architecture Overview

  • User Requests a Ride:ride_requested event 被发送到 Kafka。

  • Ride Service Assigns Driver:driver_assigned event 被发布。

  • Driver Arrives and Starts the Ride:ride_started event 被发送。

  • Ride Completes:ride_completed event 会触发以下 actions:

    • Payment Service 处理 fare。
    • Notification Service 发送 receipt。
    • Analytics Service 记录 ride data。

因此,这种 loosely coupled、event-driven architecture 能确保 high availability、scalability 和 fault isolation。

在 ride-sharing platform 中,数据分布在多个 services 中,这意味着整个系统范围内的 strong consistency 并不总是现实的。大多数 microservices-based systems 采用 eventual consistency,其中每个 service 拥有自己的数据,并在 state changes 发生时发布 events。例如,Ride Service 中创建的 ride request,可能会稍晚通过 events 反映到 Notification Service 和 Driver Service 中。因此,为了保证可靠性,services 必须支持 idempotent event handling、清晰 event contracts 和 retry mechanisms,使 repeated 或 delayed events 不会产生 duplicate actions。

Distributed transactions 是另一个关键问题。单次 ride journey 会触及多个 services,例如 ride creation、driver assignment、pricing、payment authorization 和 receipt generation,但通常会避免跨这些 services 使用单一 ACID transaction,因为这会造成 tight coupling 和 fragility。相反,系统通常使用 saga pattern,其中每个 step 发布 event,下一个 service 对其作出响应,如果发生 failure,则提供 compensating actions。例如,如果 driver 已被分配后 payment authorization 失败,系统可以触发 compensation,例如释放 driver,并将 ride 标记为 cancelled。这种方法提升 scalability 和 resilience,但要求仔细设计 failure handling 和 compensation logic。

因此,observability 在 distributed microservices 中是必需的,但它也带来不可忽视的成本。由于 requests 会异步流经多个 services,如果没有适当 telemetry,troubleshooting 会非常困难。因此,组织通常会实现 centralized logging、distributed tracing 和 metrics collection,以跟踪端到端 ride lifecycle performance 和 failures。不过,high-volume systems 会生成大量 observability data,例如 logs、traces、metrics,从而增加 storage 和 monitoring costs。因此,务实方法是 intelligent trace sampling、选择性保留 error paths 的详细 logs,并定义 SLO-driven monitoring,而不是不加区分地收集一切。

Data Lakehouse Architecture

Data warehouses 提供高性能 structured data,但成本较高;而 data lakes 为 unstructured 和 semi-structured data 提供灵活性,但经常存在 governance 和 query performance 问题。因此,为了弥合这一差距,data lakehouse architecture 被提出,用于将 data lakes 和 data warehouses 的优势结合到一个平台中。

Data Lakehouse Architecture

Data lakehouse 建立在多个 layers 之上,这些 layers 确保无缝 data ingestion、processing、governance 和 analytics。主要 layers 包括:

Storage Layer(Foundation of the Data Lakehouse) :在低成本 cloud storage 中存储 raw、structured、semi-structured 和 unstructured data。

Staging Layer(Metadata and Indexing) :维护描述已存储数据的 metadata catalogs,例如 schema、lineage、access control。

Processing Layer(Data Transformation and Management) :执行 ETL(Extract、Transform、Load)和 ELT(Extract、Load、Transform)operations,为 analytical use 准备数据。

Semantic Layer(Data Query and Analysis) :充当 data storage 与 analytics tools 之间的 interface,例如 SQL access 和 AI / ML integration。

Consumption Layer(Data Access and Utilization) :连接 BI dashboards、data visualization tools 和 reporting systems,例如 Tableau、Power BI。

Data Warehouse、Data Lake 和 Data Lakehouse 对比

Data warehouses、data lakes 和 data lakehouses 是三种不同的数据存储架构,各自具有独特特征和 use cases。下面是比较概览:

AspectData WarehouseData LakeData Lakehouse
Data TypesStructured dataStructured、semi-structured 和 unstructured dataStructured、semi-structured 和 unstructured data
SchemaSchema-on-write(predefined schemas)Schema-on-read(flexible schemas)结合 schema-on-write 和 schema-on-read
Storage Cost由于 optimized storage,成本较高使用 cost-effective storage,成本较低在 cost 和 performance 之间平衡
Performance复杂 queries 的 high performancePerformance 不稳定,可能需要额外 processingHigh performance,并支持 diverse workloads
Use CasesBusiness intelligence 和 reportingBig data analytics、machine learningUnified analytics 和 machine learning
Governance强 governance 和 data quality controls需要额外 governance frameworks内置 governance 和 data management features
ScalabilityScalability 有限,可能复杂且昂贵高度 scalable,storage 和 compute 解耦高度 scalable,storage 和 compute 解耦
ACID Support完全支持 ACID transactions通常缺少 ACID transaction support支持 ACID transactions,以保证 data reliability

表 3.6:Data Warehouse、Data Lake 和 Data Lakehouse Architectures 对比

适合选择 Data Lakehouse 的场景

Unified Data Processing:在单一架构中高效处理 structured data,例如 transactions、customer data,以及 unstructured data,例如 logs、images、videos。

Real-Time and Batch Analytics:无缝支持 streaming use cases,例如 fraud detection,以及 batch processing,例如 financial reporting。

Scalability and Cost Efficiency:解耦 compute 和 storage,从而为持续增长的数据量提供灵活且成本高效的 scaling。

High-Performance Queries:通过 ACID transactions、indexing 和 caching 增强 data lakes,同时支持快速可靠的 SQL analytics。

不应使用 Data Lakehouse 的场景

  • 如果你只处理 small、structured data,使用传统 data warehouse 可能更简单。
  • 如果你不需要 real-time analytics,基础 data lake 可能已经足够。
  • 如果你有 fixed schema,且没有 semi-structured data,data warehouse 可能更合适。

Table Formats and Trade-Offs:Iceberg vs. Delta vs. Hudi

现代 lakehouse architectures 依赖 open table formats,在 object storage 之上提供 ACID transactions、schema evolution、time travel 和 scalable metadata management。最广泛采用的格式包括 Apache Iceberg、Delta Lake 和 Apache Hudi。不过,虽然它们解决的问题类似,但设计理念和 trade-offs 不同。

Delta Lake 与 Spark ecosystem 紧密集成,并在 Databricks environments 中被广泛采用。它提供强 ACID guarantees、简单 configuration 和成熟 tooling。不过,严重依赖 Delta 的组织可能会与特定 compute engines 或 vendor ecosystems 产生更紧耦合,这取决于 deployment choices。

Apache Iceberg 强调 engine neutrality 和 metadata handling 的可扩展性。它在 large-scale、multi-engine environments 中表现良好,例如 Spark、Flink、Trino、Presto,并支持 hidden partitioning,这简化了 partition management。在 multi-cloud 或 heterogeneous compute environments 中,如果 openness 和 interoperability 是战略优先事项,Iceberg 通常更受偏好。

Apache Hudi 强烈关注 incremental processing 和 upsert-heavy workloads。它非常适合 change data capture(CDC)、streaming ingestion 和 near real-time lakehouse pipelines。不过,根据 clustering、compaction 和 indexing configurations,其 operational complexity 可能更高。

因此,选择其中一种取决于 workload characteristics、ecosystem alignment、team familiarity 和 operational requirements,而不是单纯比较 features。

Cost Considerations and Failure Stories

虽然 lakehouse architectures 相比传统 warehouses 承诺更低 storage costs,但它们并不天然便宜。Object storage 相对便宜,但重复 transformations、compactions、small file management 和 query acceleration 的 compute costs 可能快速上升。此外,糟糕 partitioning strategies、过度 file fragmentation 或不受控 table growth,可能导致高 query latency 和更高 compute spend。

一种常见失败场景是,组织将数据从 warehouses 迁移到 lakehouse,却没有重新设计 governance、metadata management 和 lifecycle policies。因此,如果缺少适当 data retention rules、quality checks 和 ownership models,lakehouse 可能累积文档不完善的数据集、重复 tables 和不一致 schemas。随着时间推移,这会退化为通常所说的 “data swamp”,也就是数据存在,但难以信任、发现或高效查询。

另一种失败模式是,多个独立团队在没有 shared governance standards 的情况下创建孤立 lakehouse environments。最终组织得到的不是一个 governed lakehouse,而是 fragmented mini-lakes,它们在 storage layer 重新制造 silos。因此,这违背了 unified analytics 和 shared infrastructure efficiency 的初衷。

When a Lakehouse Becomes a Data Swamp

当出现以下情况时,lakehouse 风险会演变为 data swamp:

  • 没有 enforced data catalog 或 metadata governance。
  • Schema evolution 不受控制。
  • Datasets ownership 不清晰。
  • 缺少 quality validation pipelines。
  • File compaction 和 lifecycle management 被忽视。
  • Access control 定义松散。

因此,在这些场景中,query performance 会下降,data trust 会降低,团队会重新开始构建 separate marts 或 shadow warehouses。

因此,我们可以推断,一个成功的 lakehouse 不仅需要现代 table formats,还需要强 governance、自动化 quality validation、lifecycle management 和清晰 domain ownership。没有这些,统一 lake 和 warehouse 能力的架构承诺,可能很快在 operational entropy 下崩塌。

结论

本章探索了关键现代数据架构,包括 Lambda 和 Kappa architectures、data mesh 和 data fabric,以及 event-driven、microservices-based data architectures 和 data lakehouse architecture。在每一种架构中,我们都学习了它们为什么被使用、适合什么场景,以及解决什么问题。因此,data engineer 必须了解这些架构,因为它们为理解后续概念奠定基础。

进入下一章后,我们将学习 data ingestion patterns。我们会探索数据如何以 batch process、real time streaming、change data capture、API-based data consumption,以及 IoT 或 Sensor data captures 的形式被消费。因此,在已经掌握 data architecture 知识之后,继续学习数据如何被消费和利用,将是一段有趣旅程。