企业在现代技术栈演进时,通常会遇到遗留系统问题。以审计系统为例,如何利用Apache Iceberg、Spark、Trino 和 Doris等关键能力替代过去HBase + Elasticsearch遗留系统?需要结合具体的业务场景进行分析!
重构背景
审计系统通常是企业的诸多关键业务系统之一,主要用于分析所有进入平台的录入数据以及系统内部执行的具体操作。一般来说,主要服务对象有两类:
1、数据科学团队,审计系统上的数据是他们构建未来机器学习模型的基础。
2、客户,需求是希望定期查询数据库,以分析其公司的活动情况。
基于这些用例,技术团队需要一个既能支持分析型工作负载,又能支持近实时查询的平台。
当前架构及其痛点
整体来看,这家企业最初的技术栈相当陈旧,它围绕一个单体 Java 服务构建,该服务接收 HTTP 批量请求,并将数据写入 HBase(作为主要数据源)和 Elasticsearch。其排队机制基于 HDFS 文件系统,每个服务从自己的目录读取消息。
该架构存在以下问题:
成本高昂:HBase、Elasticsearch 和 HDFS 的维护及基础设施成本很高。
运行缓慢:单体架构复杂且笨重,难以高效扩展。
难以变更:任何对业务逻辑的修改或数据库问题都可能影响所有 API(包括写入和搜索)。
与此同时,技术团队还意识到,企业其实并不需要如此沉重且昂贵的架构。审计系统主要用于近实时流程中的分析目的,数据导入延迟 2–3 分钟是完全可接受的。
湖仓一体:为何选择 Apache Iceberg
为了实现平台现代化目标,企业决定采用湖仓一体架构,表格式选用 Apache Iceberg,文件格式选用 Parquet。
与数据湖类似,湖仓一体使用云对象存储(如 Amazon S3、ADLS 或 GCS),并将数据存储为开放文件格式(如 Apache Parquet、Avro 或 ORC)。这种云存储模式赋予了湖仓一体数据湖的所有主要优势:
高可用性与高持久性
成本降低
可扩展性
支持结构化、半结构化和非结构化数据
对 AI/机器学习用例的良好支持
选择 Iceberg 是因为它具备几个关键功能:
ACID 事务:需要强有力的保证,因为多个 Spark 作业可能会写入同一个存储。Iceberg 的 ACID 支持确保了即使并发写入也能保持一致性。
分区演进:起初,查询总是包含 partnerId。后来,业务逻辑发生变化,时间成为了每个查询的关键过滤器。Iceberg 让企业能够在不重写整个表的情况下演进分区方案,且能“实时”完成。
版本控制与回滚:对企业来说,能够回滚到表的旧版本非常重要,以防部署失误或数据损坏。Iceberg 的快照和回滚机制赋予了企业所需要的这种能力。
在文件格式方面,经过性能测试,发现 Parquet 最适合企业的业务逻辑。在具体使用场景中,它也比 Avro 提供了更好的压缩效果。
数据迁移
首先,技术团队需要将数据从 HBase 迁移到云存储。由于时间和资源有限,利用现有的 MapReduce 作业在 Hadoop 上提取了 HBase 的数据。
至于,实现方案中为何选择 Spark?
在数据摄取方面,选择了 Apache Spark 结构化流处理,因为它提供了:
与 Iceberg 的良好兼容性
便捷的 API
强劲的性能
为了节省成本,企业还采用了一种微批处理模式,即从Spark 从 Kafka 读取数据,处理一个微批次,将结果写入 Iceberg,然后停止,而不是连续运行。在编排方面,使用 Airflow,每五分钟触发一次 Spark 作业来读取 Kafka 的数据。
Spark 还为优化 Iceberg 表提供了良好的支持,包括文件压缩和其他维护操作,这对于 Iceberg 的长期使用非常重要。
企业在调优 Spark 和写入文件时遇到了一些挑战:
有一次,技术团队配置了一个非常大的写入批次,导致文件损坏。最后,通过减少批次数量并调整 maxOffsetsPerTrigger 参数解决了这个问题。
企业还需要增加 Kafka 分区数量,以提升 Spark 的并行度并充分利用集群。
在实现过程中,企业使用了 PySpark,这让技术团队能够快速迭代,并轻松与环境中的其他组件集成。
Trino 的局限与选择 Doris 的原因
企业的主要任务之一是找到在云对象存储中查询数据的最 佳解决方案,技术团队的负载并不算特别高,每次查询最多允许两分钟。然而,根据公司政策,必须维护两个独立的查询引擎集群,以确保客户的高可用性。
企业最初的想法是给次级集群分配最少的资源,仅在紧急情况下使用。起初,团队以 Trino 作为主要查询引擎。然而,Trino 未能在特定工作负载下提供预期的实时搜索性能。
这大概与使用它的方式有关,Trino 非常擅长整合多个来源的数据并进行联合分析查询,但当你需要对单个湖仓源进行非常快速、实时的搜索时,它并不总是最 佳选择。
因此,技术团队开始寻找更适合需求的替代查询引擎。之后,企业评估了两个引擎:StarRocks 和 Apache Doris。企业曾尝试实现基于 StarRocks 的解决方案,但由于部署和配置耗时过长,最终选择了 Apache Doris。
在 Doris 部署过程中,特别喜欢它的缓存机制,这让企业的搜索查询性能显著提升——在测试中通常快了 2 到 3 倍。Doris 还提供外部表支持,企业计划在迁移高负载系统时使用。
结论
企业从旧的 HBase 和 Elasticsearch 技术栈迁移到湖仓一体架构,效果非常显著,成功降低了成本和资源使用。大体来看,在考虑从传统烟囱式架构迁移到湖仓一体时,理解系统的最终目的非常重要。
如果你的分析工作负载查询负载处于中低水平,湖仓一体架构通常是最 佳选择。
如果你需要极快且负载极高的搜索,传统的流媒体架构和专门针对实时查询的数据库可能仍然更适合。
同样重要的是,要仔细选择表格式、文件格式和查询引擎:
为了在湖仓数据上进行快速实时搜索,企业首选的解决方案是 Apache Doris(或 StarRocks)。
对于从不同来源汇总数据并运行联合分析查询,Trino 依然是一个极 佳的选择。
实践经验表明,将基于 Iceberg 和 Parquet 构建的湖仓架构与用于导入的 Spark 以及用于查询的 Doris 相结合,可以成为传统 HBase + Elasticsearch 技术栈的强大且经济的替代方案。