xiaohack's Blog - Flink
type: channel
link: https://blog.xiaohack.org/tag/flink/
items: 瑞幸咖啡 x 阿里云合作共创：AI 推荐让瑞幸咖啡“更懂你
items: Flink ClickHouse Sink：生产级高可用写入方案｜得物技术
items: 从零开始学Flink：状态管理与容错机制
items: Fluss在阿里双11万亿规模场景下的落地实践
items: Apache Paimon多模态数据湖实践：从结构化到非结构化的技术演进
items: Linux 环境下，Apache DolphinScheduler 如何驱动 Flink 消费 Kafka 数据？
items: Apache Gravitino 概要介绍
items: 双 11 大促峰值不翻车：淘天集团 Paimon + StarRocks 大规模 OLAP 查询实战与优化
items: 从Kafka到AutoMQ：爱奇艺实时流数据架构演进

瑞幸咖啡 x 阿里云合作共创：AI 推荐让瑞幸咖啡“更懂你
type: item
date: 2026-02-10T15:32:36+08:00
description: 在新零售不断演进的今天，用户走进瑞幸，要的不只是咖啡，更是一种“被真正理解”的体验——口味、习惯、场景，甚至那一刻的心情。作为国内领先的连锁咖啡品牌，瑞幸咖啡正从数字化迈入智能化新阶段，以人工智能技术驱动“人、货、场”核心业务平台的智能化重构，构建面向未来的智慧商业决策体系。为此，瑞幸与阿里云深度共创，基于阿里云人工智能平台PAI，共同打造了一套真正“以用户为中心”的端到端智能推荐系统。它不再依赖静态规则，而是通过理解用户的偏好和需求，为用户提供贴心的咖啡选择建议——无论是清晨提神的美式，还是周末慵懒的生椰拿铁，当你唤醒AI Lucky，“为你而选”的新品、优惠与搭配，就会送到你眼前，让每一次选择都更轻松、更安心。过去依赖人工规则的推荐方式，难以动态响应用户变化；如今，借助双方联合打磨的数据链路、算法模型与运营机制，瑞幸不仅实现了推荐精准度的跃升，也让用户获得更流畅、更贴心的服务体验。这次合作，是瑞幸AI能力体系进化的重要一步，更是与阿里云“一起设计、一起验证、一起交付、一起沉淀”的技术共创典范——不是单方面交付产品，而是共同构建面向未来的智能零售能力。从规则驱动到 AI 驱动：赋能增长新范式截至2025年第三季度，瑞幸咖啡已建立起覆盖全国超2.9万家门店的庞大网络。随着用户规模持续扩大，瑞幸咖啡也在不断探索新技术增加对于客户的理解，为客户提供更加灵活的服务，促进增长的发展。为探索AI赋能增长新范式，瑞幸致力于构建一套具备高精度、可迭代、可扩展能力的AI推荐系统。经过多轮技术评估与方案论证，瑞幸最终与阿里云大数据AI平台合作共创，采用MaxCompute+DataWorks+Flink+Hologres+PAI技术架构，以PAI-Rec作为其新一代推荐引擎，依托其强大的大数据、算法能力与全链路服务支持，开启提升用户推荐体验的智能化升级。与客户共创，助力客户能力沉淀此次合作不仅是技术产品的落地，更是一次深度的“技术共创”实践。阿里云技术团队与瑞幸技术团队紧密协作，全程参与需求分析、POC验证、系统上线与效果优化。在项目推进过程中，阿里云技术团队与瑞幸团队高效协同，高质量完成多组对比实验，并组织多次技术交流，协助瑞幸系统性地沉淀了数据处理规范、特征工程方法、模型调优策略及测试体系，为其后续自主迭代与业务扩展打下坚实基础。展望未来：AI 驱动“更懂你的咖啡”本次合作不仅为瑞幸带来了显著的业务升级，也为阿里云人工智能平台PAI在零售行业树立了标杆案例。“本次与阿里云合作的AI智能推荐场景，提供的不仅是一个工具、一个解决方案，更是一次双方共创合作经验的落地。”瑞幸技术负责人表示，“从POC到全量上线，阿里云团队展现了极强的技术实力与服务意识。我们相信，AI将成为瑞幸持续领跑行业的重要引擎。”一杯咖啡的背后，是海量数据的流转与AI模型的精准计算。随着推荐系统的持续优化，瑞幸咖啡的运营模式实现“更智能、更个性、更高效”。未来，双方还将探索大模型在用户意图理解、生成式推荐、跨场景联动等方向的创新应用，进一步释放AI在消费场景中的潜力。瑞幸咖啡 x 阿里云大数据AI平台的合作，不仅是一次技术升级，更是AI赋能实体经济的生动实践。在智能化浪潮中，AI将成为您的专属咖啡助手——从海量风味中，AI推荐为您探索意想不到的惊喜之选，让咖啡更懂你。阿里云 AI 推荐方案：打造端到端智能推荐引擎下面将重点介绍阿里云AI推荐方案在该场景中的技术亮点与应用优势。阿里云AI推荐方案是面向企业级场景的全托管推荐算法服务平台，深度融合阿里巴巴在电商、本地生活等高并发、高实时性场景下的推荐实践经验，提供从数据处理、特征工程、模型训练、测试验证到在线服务的一站式解决方案。在本次合作中，阿里云为瑞幸咖啡量身打造了覆盖“数据 → 模型 → 服务 → 迭代”的完整推荐链路：端到端系统搭建：基于全托管架构的阿里云大数据AI平台，搭建实时推荐全链路，快速构建从数据采集、实时特征计算、深度学习模型训练到在线推理的全流程系统，实现毫秒级响应的AI推荐服务。精准转化率提升：通过引入深度CTR/CVR预估模型、多目标优化（MMOE）及序列建模（如DIEN），显著提升推荐内容的相关性与转化效率。经测试验证，最终转化率较原有规则系统提升明显。全托管运维，释放技术负担：依托人工智能平台PAI的自动化运维与弹性伸缩能力，瑞幸团队得以从繁重的系统维护中解放，聚焦核心业务创新，大幅降低AI落地门槛。阿里云智能推荐系统解决方案阿里云为企业开发者提供全链路深度定制的推荐系统解决方案。方案涵盖了离线处理、在线服务、实时数据流和工程架构等多个维度，包括召回、排序、过滤和重排等功能模块，提供多种数据诊断分析、推荐结果调试和引擎发布管理等工具，通过A/B testing服务和实验报表平台提升推荐系统的迭代效率。搭…

Flink ClickHouse Sink：生产级高可用写入方案｜得物技术
type: item
date: 2026-02-10T11:29:05+08:00
description: 一、背景与痛点业务场景在实时大数据处理场景中，Flink + ClickHouse 的组合被广泛应用于：日志处理： 海量应用日志实时写入分析库。监控分析： 业务指标、APM 数据的实时聚合。这些场景的共同特点：数据量大：百万级 TPS，峰值可达千万级。写入延迟敏感： 需要秒级可见。数据准确性要求高：不允许数据丢失。多表写入： 不同数据根据分表策略写入不同的表。开源 Flink ClickHouse Sink 的痛点Flink 官方提供的 ClickHouse Sink（flink-connector-jdbc）在生产环境中存在以下严重问题：痛点一：缺乏基于数据量的攒批机制问题表现：// Flink 官方 JDBC Sink 的实现 public class JdbcSink<T> extends RichSinkFunction<T> { private final int batchSize; // 固定批次大小 @Override public void invoke(T value, Context context) { bufferedValues.add(value); if (bufferedValues.size() >= batchSize) { // 只能基于记录数攒批，无法基于数据量 flush(); } }带来的问题：内存占用不可控： 100 条 1KB 的日志和 100 条 10MB 的日志占用内存差距 100 倍。OOM 风险高： 大日志记录（如堆栈转储）会迅速撑爆内存。写入性能差： 无法根据记录大小动态调整批次，导致小记录批次过大浪费网络开销。痛点二：无法支持动态表结构问题表现：// Flink 官方 Sink 只能写入固定表 public class JdbcSink { private final String sql; // 固定的 INSERT SQL public JdbcSink(String jdbcUrl, String sql, ...) { this.sql = sql; // 硬编码的表结构 } }带来的问题：多应用无法隔离： 所有应用的数据写入同一张表，通过特定分表策略区分。扩展性差： 新增应用需要手动建表，无法动态路由。性能瓶颈： 单表数据量过大（百亿级），查询和写入性能急剧下降。痛点三：分布式表写入性能问题问题表现：// 大多数生产实现直接写入分布式表 INSERT INTO distributed_table_all VALUES (...)ClickHouse 分布式表的工作原理：带来的问题：网络开销大： 数据需要经过分布式表层转发，延迟增加。写入性能差： 分布式表增加了路由和转发逻辑，吞吐量降低。热点问题： 所有数据先到分布式表节点，再转发，造成单点瓶颈。生产级方案的核心改进针对以上痛点，本方案提供了以下核心改进：改进一：基于数据量的攒批机制public class ClickHouseSinkCounter { private Long metaSize; // 累计数据量（字节） public void add(LogModel value) { this.values.add(value); this.metaSize += value.getMetaSize(); // 累加数据量 } } // 触发条件 private boolean flushCondition(String application) { return checkMetaSize(application) // metaSize >= 10000 字节 || checkTime(application); // 或超时 30 秒 }优势：内存可控： 根据数据量而非记录数攒批。精确控制： 1KB 的记录攒 10000 条 = 10MB，1MB 的记录攒 10 条 = 10MB。避免OOM： 大日志记录不会撑爆内存。改进二：动态表结构与分片策略public abstract class ClickHouseShardStrategy<T> { public abstract String getTableName(T data); } //日志侧实现为应用级分表 public class LogClickHouseShardStrategy extends ClickHouseShardStrategy<String> { @Override public String getTableName(String application) { // 动态路由：order-service → tb_logs_order_service return String.format("tb_logs_%…

从零开始学Flink：状态管理与容错机制
type: item
date: 2026-02-04T16:08:31+08:00
description: 流式计算任务通常需要 7x24 小时长期运行，面对网络抖动、机器故障或代码 Bug，如何保证任务不挂？或者挂了之后能自动恢复且数据不丢、不重？这正是 Flink 引以为傲的资本：强大的状态管理与基于 Checkpoint 的容错机制。本文将带你深入理解 Flink 是如何“记忆”数据的，以及它是如何在故障发生时“时光倒流”恢复现场的。一、什么是状态（State）在流计算中，数据是一条条流过的。如果处理一条数据时，需要依赖之前的数据（例如：计算过去一小时的总和、去重、模式匹配），那么这些“之前的数据”或“中间计算结果”就是状态。1. 状态的分类Flink 的状态分为两大类：Managed State（托管状态） 和 Raw State（原生状态）。我们日常开发 99% 使用的是托管状态，由 Flink 运行时自动管理内存、序列化和故障恢复。Managed State 又细分为：Keyed State（键控状态）只能在 KeyedStream（即 keyBy 之后）上使用。状态是跟 Key 绑定的。Flink 为每个 Key 维护一份独立的状态实例。常用类型：ValueState、ListState、MapState、ReducingState、AggregatingState。Operator State（算子状态）绑定到算子并行实例（SubTask），与 Key 无关。常用于 Source Connector（记录读取的 Offset）或 Sink Connector（事务控制）。常用接口：ListState、UnionListState、BroadcastState。二、状态后端（State Backends）状态存在哪里？是内存还是磁盘？这由 State Backend 决定。在 Flink 1.13 之后，配置方式简化为以下两种主要模式：1. HashMapStateBackend (基于内存)存储位置：Java 堆内存（Heap）。特点：读写速度极快（对象直接访问，无序列化开销）。适用场景：状态较小（例如仅仅是简单的 Count 或去重），对延迟极其敏感的场景。缺点：受限于 JVM 堆大小，容易 GC；状态过大时可能 OOM。2. EmbeddedRocksDBStateBackend (基于磁盘)存储位置：TaskManager 本地磁盘（基于 RocksDB 数据库），内存中只作为缓存（Off-heap）。特点：支持超大状态（TB 级别），不受 JVM 堆限制。适用场景：超大窗口、超长周期的聚合、海量 Key 的去重。缺点：需要序列化/反序列化，读写性能略低于内存版；需要调优 RocksDB 参数。3. 配置示例StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置状态后端为 RocksDB env.setStateBackend(new EmbeddedRocksDBStateBackend()); // 配合 Checkpoint 存储路径（存储在本地文件系统） env.getCheckpointConfig().setCheckpointStorage("file:///tmp/flink/checkpoints");三、容错核心：CheckpointCheckpoint（检查点）是 Flink 容错机制的灵魂。它是一个全局一致性快照，定期将所有算子的状态持久化到远程存储（如 HDFS）。1. 核心原理：Barrier 对齐Flink 使用 Chandy-Lamport 算法 的变体。Barrier 注入：JobManager 向 Source 发送 Checkpoint Barrier。Barrier 流动：Barrier 像普通数据一样在流中传输。对齐（Alignment）：当算子有多个输入流时，必须等待所有流的 Barrier 到齐，才能进行 Snapshot。这保证了状态的一致性（即 Exactly-Once）。异步快照：算子将状态写入远程存储（异步过程），不阻塞数据处理。确认完成：所有算子都完成快照后，JobManager 确认 Checkpoint 成功。2. Checkpoint 配置实战默认情况下 Checkpoint 是关闭的，生产环境必须开启。// 1. 开启 Checkpoint，每 5000ms 触发一次 env.enableCheckpointing(5000); // 2. 设置 Checkpoint 模式（默认 EXACTLY_ONCE，也可以设为 AT_LEAST_ONCE） env.getCheckpointConfig().setCheckpoi…

Fluss在阿里双11万亿规模场景下的落地实践
type: item
date: 2026-01-30T18:18:39+08:00
description: 摘要：本文整理自阿里采集分析平台工程技术负责人 吴宝国 老师，在 Flink Forward Asia 2025 城市巡回深圳站中的分享。Tips：关注「公众号」回复 FFA 2025 查看会后资料～大家好，我是来自阿里集团平台技术部数据技术与产品部的吴宝国。今天非常荣幸能在这里跟大家分享我们在阿里内部大规模落地 Fluss 的一些实践经验。首先简单介绍一下我们团队。我们团队主要负责集团内部统一的用户行为采集与分析平台，也就是大家常说的 A+ 平台。我们的核心职责是为手淘、钉钉、高德、饿了么等众多集团内应用提供端到端的用户行为数据采集、处理、分析及服务能力。在底层，我们构建了覆盖 Web、小程序、APP（包括 Android、iOS、PC、IOT、鸿蒙、VR 等）以及服务端的全场景采集 SDK 矩阵。在此之上，我们不仅采集用户的行为日志（比如点击、曝光、滑动等），还会融合业务数据（如用户标签、商品信息、订单数据等），构建服务于整个集团的流量域数据公共层。最终，我们通过分析产品帮助业务团队洞察用户行为，驱动运营和产品决策，例如提升广告效果、优化用户体验等。为了支撑这一庞大体系的实时性需求，我们引入了开源流存储系统 Fluss 作为核心的日志数据实时采集通道。接下来，我将从为什么选择 Fluss、如何保障大规模落地稳定性、具体业务实践案例以及未来规划四个方面展开分享。一、为什么选择 Fluss？——解决两大核心痛点在引入 Fluss 之前，我们的实时数据架构长期面临两个根本性挑战。（1）成本高昂：行式消息队列导致资源浪费严重我们过去主要依赖阿里内部的行式消息队列 TT（TimeTunnel）。以手淘的实时流量公共层为例，这张表包含了首页、闪购、搜索等多个业务的数据。每个下游业务（比如推荐系统）都需要一个独立的 Flink 作业来消费这张全量表，然后在作业内进行过滤，只保留自己关心的部分。这种模式带来了三重成本问题：存储与流量成本倍增：计费通常基于读写流量。即使每个业务只关心 1% 的数据，也需要为 100% 的全量数据付费。如果有 N 个业务，就要支付 N 倍的费用。Flink CU 资源浪费：Flink 作业需要消耗大量计算单元（CU）来读取、反序列化并丢弃无用的数据。很多时候，作业空跑不做任何逻辑处理，但依然产生高昂开销。字段冗余读取：一张表可能包含数百个字段，但单个业务往往只需要其中几个。行式存储迫使消费者读取整行数据，造成巨大的 IO 和网络带宽浪费。Fluss 通过其三大核心能力完美解决了上述问题：多级分区（Multi-level Partitioning）：支持按业务、按场景等维度对数据进行精细划分。过滤下推（Filter Pushdown）：消费者可以在订阅时声明过滤条件，数据在源头即可被精确过滤，避免全量拉取。列式存储（Columnar Storage）：允许消费者只读取所需的字段，极大降低数据消费量和 Flink CU 消耗。（2）湖流割裂：Lambda 架构的运维与一致性困境业界经典的 Lambda 架构虽然能同时提供实时和离线视图，但维护两套独立的批处理和流处理链路，带来了开发、运维成本高企以及数据统计口径不一致等问题。随着数据湖技术（如 Paimon、Hudi）的发展，湖仓一体架构成为主流，但它通常只能提供分钟级的数据新鲜度。对于搜索、推荐等要求秒级延迟的核心场景，我们仍需引入 Kafka 这类流式中间件，这实际上又回到了 Lambda 架构的老路，导致“湖”与“流”的割裂。Fluss 的出现为我们提供了一个统一的解决方案：它既能作为高性能的流存储提供秒级数据新鲜度，又能通过其内置的分层存储（Tiering）能力无缝对接数据湖（如阿里内部的 Alake），真正实现了“湖流一体”，消除了双架构的痛点。二、首次双11落地情况：大规模生产验证2025 年的双 11 是 Fluss 在阿里集团的首次大促实战。目前，Fluss 已稳定服务于淘天（含通天塔、阿里妈妈等）、集团数据公共层、饿了么、淘宝闪购、高德、阿里影业等多个核心业务，核心场景主要集中在搜索、推荐、流量等。在本次双十一期间，Fluss 展现了强大的承载能力：数据量：4 PB/天TPS峰值：1 亿BPS峰值：100 GiB/s这些数据充分证明了 Fluss 在大规模、高并发场景下的稳定性和可靠性。三、集群部署架构阿里集团内部的业务特点与云上有所不同，因此我们的部署架构也进行了针对性设计。我们采用了“大集群 + 区域化部署”的模式。不同地域（如张北、上海）拥有独立的 Fluss 集群，而同一地域内的不同业务（如高德、钉钉、淘天）则通过数据库（DB）级别进行逻辑隔离。数据持久化在阿里自研的分布式文件系统 盘古 上，并通过 Tiering Service 同步至…

Apache Paimon多模态数据湖实践：从结构化到非结构化的技术演进
type: item
date: 2026-01-29T16:43:06+08:00
description: 在近期的 Streaming Lakehouse Meetup · Online EP.2｜Paimon × StarRocks 共话实时湖仓 直播中，Apache Paimon PMC 成员/阿里云数据湖资深工程师叶俊豪带来了关于 Paimon 多模态数据湖的深度技术分享。随着大模型训练对数据规模与多样性的要求不断提升，传统以批处理为中心的数据湖架构已难以满足 AI 工作负载对实时性、灵活性和成本效率的综合需求。特别是在推荐系统、AIGC 等典型场景中，工程师既要高频迭代结构化特征，又要高效管理图像、音频、视频等非结构化数据。面对这一挑战，Paimon 作为新一代流式数据湖存储引擎，正通过一系列底层创新，构建面向 AI 原生时代的统一数据基础设施。一、结构化场景下的“列变更”困境在推荐、广告等 AI 应用中，特征工程是一个持续演进的过程。例如，电商团队可能今天新增“用户近7日点击品类分布”，明天又加入“跨端行为一致性评分”。这种动态列变更导致“列爆炸”问题：表结构频繁扩展，而历史数据需与新特征对齐。然而，已知的解决方案在此场景下仍然存在一些问题：主键表 partial-update：虽支持按主键更新部分列，但其基于 LSM 树的实现会在写入频繁时产生大量小文件，查询性能急剧下降；Compaction 虽可合并文件，却带来数倍的临时存储开销。odps 存新特征值 + Join 拼接方案：将新特征写入独立表，查询时通过主键 Join 合并。看似避免了重写，但 Join 操作本身在 PB 级数据上开销巨大，且难以优化。Append 表 + MERGE INTO：SQL 语法简洁，但底层仍需重写整个数据文件。对于每天增量达 PB 级的训练集，全量重写不仅成本高昂，还显著拖慢特征上线周期。这些方案本质上都未能解耦“列”的物理存储，导致灵活性与效率不可兼得。二、Paimon 的列分离架构：以全局 Row ID 为核心Paimon 提出了 列分离存储架构，其核心是引入 全局唯一且连续的 Row ID。每行数据在首次写入时被分配一个在整个表生命周期内不变的 ID，且每个数据文件内的 Row ID 是连续的，元数据会记录该文件的起始 Row ID。这一设计带来两个关键能力：精准定位任意行：通过 Row ID 可直接定位到具体文件及偏移；跨文件自动关联：当查询涉及多个列时，系统能根据 Row ID 范围自动将分散在不同文件中的列数据在存储层合并。例如，当新增“用户兴趣标签”列时，Paimon 仅需写入一个包含该列与对应 Row ID 的新文件，无需修改原始特征文件。查询时，引擎透明地将两组文件按 Row ID 对齐合并，无需 SQL 层 Join，也无需重写历史数据。这种机制将列变更的存储成本从 O(N) 降至 O(ΔN)，极大提升了特征迭代效率，同时节省了数十倍的存储空间。三、迈向多模态：Blob 数据类型的三大突破AI 训练不再局限于结构化特征。AIGC、多模态大模型等场景要求数据湖能高效处理图像、短视频、长音频等非结构化数据。这类数据具有两大特点：体积差异大（几 MB 到数十 GB）、访问稀疏（训练时通常只读取片段）。传统列式格式（如 Parquet）将多模态数据与结构化字段混存，导致即使只查用户 ID，也需加载整个含视频的大文件，I/O 效率极低。Paimon 引入 Blob 数据类型，实现三大突破：物理分离存储：Blob 列独立成文件，与结构化数据完全解耦。查询结构化字段时，Blob 文件完全不参与 I/O，避免资源浪费。多引擎统一抽象：无论使用 Spark、Flink、Java SDK 还是 Python 客户端，均可通过标准的 BYTES 或 BINARY 或 BLOB 类型定义 Blob 字段，接口一致，降低接入成本。blob-as-descriptor 机制：针对超大非结构化数据（如十几GB的视频/日志文件），传统计算引擎（如Flink/Spark）无法将其全量加载到内存中处理。为此，系统引入了 blob-as-descriptor 机制——它是一种协议，通过记录数据在外部存储（如OSS）中的位置、文件路径、起始偏移和长度等元信息，将实际数据读取任务交给下游系统按需流式加载。这样避免了内存溢出，实现了大文件高效入湖。四、生产验证与未来演进当前，Paimon Blob 已在淘宝、天猫等核心业务中实现大规模落地，每天有近 10PB 的多模态数据（如视频、音频、图像）通过 Blob Descriptor 协议高效写入 Paimon 湖，避免了 Flink 或 Spark 将大文件全量加载到内存的问题。然而，在实际使用中仍面临三大关键挑战：数据重复与删除问题，用户常因多次上传相同内容导致大量冗余（预估约 1PB/天的重复数据），亟需高…

Apache Paimon多模态数据湖实践：从结构化到非结构化的技术演进
type: item
date: 2026-01-29T16:42:19+08:00
description: 在近期的 Streaming Lakehouse Meetup · Online EP.2｜Paimon × StarRocks 共话实时湖仓 直播中，Apache Paimon PMC 成员/阿里云数据湖资深工程师叶俊豪带来了关于 Paimon 多模态数据湖的深度技术分享。随着大模型训练对数据规模与多样性的要求不断提升，传统以批处理为中心的数据湖架构已难以满足 AI 工作负载对实时性、灵活性和成本效率的综合需求。特别是在推荐系统、AIGC 等典型场景中，工程师既要高频迭代结构化特征，又要高效管理图像、音频、视频等非结构化数据。面对这一挑战，Paimon 作为新一代流式数据湖存储引擎，正通过一系列底层创新，构建面向 AI 原生时代的统一数据基础设施。一、结构化场景下的“列变更”困境在推荐、广告等 AI 应用中，特征工程是一个持续演进的过程。例如，电商团队可能今天新增“用户近7日点击品类分布”，明天又加入“跨端行为一致性评分”。这种动态列变更导致“列爆炸”问题：表结构频繁扩展，而历史数据需与新特征对齐。然而，已知的解决方案在此场景下仍然存在一些问题：主键表 partial-update：虽支持按主键更新部分列，但其基于 LSM 树的实现会在写入频繁时产生大量小文件，查询性能急剧下降；Compaction 虽可合并文件，却带来数倍的临时存储开销。odps 存新特征值 + Join 拼接方案：将新特征写入独立表，查询时通过主键 Join 合并。看似避免了重写，但 Join 操作本身在 PB 级数据上开销巨大，且难以优化。Append 表 + MERGE INTO：SQL 语法简洁，但底层仍需重写整个数据文件。对于每天增量达 PB 级的训练集，全量重写不仅成本高昂，还显著拖慢特征上线周期。这些方案本质上都未能解耦“列”的物理存储，导致灵活性与效率不可兼得。二、Paimon 的列分离架构：以全局 Row ID 为核心Paimon 提出了 列分离存储架构，其核心是引入 全局唯一且连续的 Row ID。每行数据在首次写入时被分配一个在整个表生命周期内不变的 ID，且每个数据文件内的 Row ID 是连续的，元数据会记录该文件的起始 Row ID。这一设计带来两个关键能力：精准定位任意行：通过 Row ID 可直接定位到具体文件及偏移；跨文件自动关联：当查询涉及多个列时，系统能根据 Row ID 范围自动将分散在不同文件中的列数据在存储层合并。例如，当新增“用户兴趣标签”列时，Paimon 仅需写入一个包含该列与对应 Row ID 的新文件，无需修改原始特征文件。查询时，引擎透明地将两组文件按 Row ID 对齐合并，无需 SQL 层 Join，也无需重写历史数据。这种机制将列变更的存储成本从 O(N) 降至 O(ΔN)，极大提升了特征迭代效率，同时节省了数十倍的存储空间。三、迈向多模态：Blob 数据类型的三大突破AI 训练不再局限于结构化特征。AIGC、多模态大模型等场景要求数据湖能高效处理图像、短视频、长音频等非结构化数据。这类数据具有两大特点：体积差异大（几 MB 到数十 GB）、访问稀疏（训练时通常只读取片段）。传统列式格式（如 Parquet）将多模态数据与结构化字段混存，导致即使只查用户 ID，也需加载整个含视频的大文件，I/O 效率极低。Paimon 引入 Blob 数据类型，实现三大突破：物理分离存储：Blob 列独立成文件，与结构化数据完全解耦。查询结构化字段时，Blob 文件完全不参与 I/O，避免资源浪费。多引擎统一抽象：无论使用 Spark、Flink、Java SDK 还是 Python 客户端，均可通过标准的 BYTES 或 BINARY 或 BLOB 类型定义 Blob 字段，接口一致，降低接入成本。blob-as-descriptor 机制：针对超大非结构化数据（如十几GB的视频/日志文件），传统计算引擎（如Flink/Spark）无法将其全量加载到内存中处理。为此，系统引入了 blob-as-descriptor 机制——它是一种协议，通过记录数据在外部存储（如OSS）中的位置、文件路径、起始偏移和长度等元信息，将实际数据读取任务交给下游系统按需流式加载。这样避免了内存溢出，实现了大文件高效入湖。四、生产验证与未来演进当前，Paimon Blob 已在淘宝、天猫等核心业务中实现大规模落地，每天有近 10PB 的多模态数据（如视频、音频、图像）通过 Blob Descriptor 协议高效写入 Paimon 湖，避免了 Flink 或 Spark 将大文件全量加载到内存的问题。然而，在实际使用中仍面临三大关键挑战：数据重复与删除问题，用户常因多次上传相同内容导致大量冗余（预估约 1PB/天的重复数据），亟需高…

Linux 环境下，Apache DolphinScheduler 如何驱动 Flink 消费 Kafka 数据？
type: item
date: 2026-01-28T11:14:40+08:00
description: 已经在虚拟机部署好Apache DolphinScheduler了，想尝试下在Flink新建一个Flink节点，然后用Flink消费Kafka数据。Apache DolphinScheduler用的是单机部署，具体操作可以参考官方文档：DolphinScheduler | 文档中心(https://dolphinscheduler.apache.org/zh-cn/docs/3.3.2/guide/in...).前置条件：已经安装Java 11、DolphinScheduler 3.3.2、Flink 1.18.1、Kafka 3.6.0，Zookeeper用Kafka内置的。建议这些安装都下载二进制的安装包到虚拟机安装，用命令安装的不可控，我下载的二进制包如下：配置好Flink的环境变量1、编辑环境变量：sudo vim ~/.bashrc增加Flink的路径2、使环境变量生效：#使环境变量生效 source ~/.bashrc #查看环境变量 echo $Flink_HOME修改Kafka、Flink以及DolphinScheduler的配置文件因为用的是虚拟机，为了让外面的主机能够访问到虚拟机的网络，需要修改下配置文件修改Kafka配置：找到Kafka安装包下的config文件夹，修改config下的server.properties文件，修改listeners是为了外面的主机能够访问到虚拟机的Kafka，还有把advertised.listeners改成虚拟机地址，写样例的时候能连上虚拟机的Kafka地址，不然默认连localhostbroker.id=0 listeners=PLAINTEXT://0.0.0.0:9092 #192.168.146.132修改成虚拟机ip advertised.listeners=PLAINTEXT://192.168.146.132:9092修改Flink配置：找到Flink安装包下的conf文件夹，修改conf下的Flink-conf.yaml文件，把里面所有的localhost地址全部改成0.0.0.0，以便主机能访问到虚拟机的Flink。还有增加jobmanager和taskmanager的内存jobmanager.rpc.address: 0.0.0.0 jobmanager.bind-host: 0.0.0.0 jobmanager.cpu.cores: 1 jobmanager.memory.process.size: 1600m taskmanager.bind-host: 0.0.0.0 taskmanager.host: 0.0.0.0 taskmanager.memory.process.size: 2048m taskmanager.cpu.cores: 1修改Apache DolphinScheduler的配置文件，从Apache DolphinScheduler的启动脚本文件dolphinscheduler-daemon.sh可以看出，配置环境变量用的是bin/env文件夹下的dolphinscheduler_env.sh。查看dolphinscheduler-daemon.sh文件：修改dolphinscheduler_env.sh文件，新增JAVA、Flink路径：#修改成自己的JAVA、Flink路径 export JAVA_HOME=/data/jdk-11.0.29 export Flink_HOME=/data/Flink-1.18.1关闭防火墙，启动应用启动应用，包括Zookeeper、Kafka、Flink以及Apache DolphinScheduler。#关闭防火墙 sudo systemctl stop firewalld # 在 Flink 根目录下，执行以下命令启动 Flink 集群 bin/start-cluster.sh # 启动 ZooKeeper bin/zookeeper-server-start.sh config/zookeeper.properties & # 启动 Kafka 服务器 bin/Kafka-server-start.sh config/server.properties & #创建 Kafka 主题 bin/Kafka-topics.sh --create --topic test --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1 #使用命令行生产者发送消息 bin/Kafka-console-producer.sh --topic test --bootstrap-server localhost:909…

Apache Gravitino 概要介绍
type: item
date: 2026-01-28T08:03:41+08:00
description: Apache Gravitino 概要介绍作者: shaofeng shi最后更新: [2025-12-29]背景在大数据时代，企业往往需要管理来自多云多域、异构数据源的元数据，如 Apache Hive、MySQL、PostgreSQL、Iceberg、Lance、S3、GCS 等； 此外，随着 AI 模型训练和推理的大量应用，海量的多模态数据、模型元数据等也需要一种方案进行管理。传统的做法是为每个数据源单独管理元数据，这不仅增加了运维复杂度，还容易造成数据孤岛。Apache Gravitino 作为一个高性能、支持地理分布式的联邦元数据湖，为我们提供了统一管理多源元数据的解决方案。Gravitino 最初是由 Datastrato 公司发起并创立，在2023年开源，2024年捐赠给 Apache 孵化器，在2025年5月从 Apache 孵化器毕业，成为 Apache Top Level Project。目前已经在小米、腾讯、知乎、Uber、Pinterest 等企业落地生产环境。什么是 Apache Gravitino？Apache Gravitino 是一个高性能、地理分布式、联邦化的元数据湖管理系统，为用户提供统一的数据和AI资产管理平台，它能够：统一元数据管理：为不同类型的数据源提供统一的元数据模型和API直接元数据管理：直接管理底层系统，变更会实时反映到源系统多引擎支持：支持Trino、Spark、Flink等多种查询引擎地理分布式部署：支持跨区域、跨云的部署架构AI资产管理：不仅管理数据资产，还支持AI/ML模型的元数据管理核心概念包括：Metalake：元数据的容器/租户，通常一个组织对应一个metalakeCatalog：来自特定元数据源的元数据集合Schema：第二级命名空间，对应数据库中的schema概念Table：最底层的对象，表示具体的数据表Apache Gravitino 核心特性概述统一元数据管理Gravitino 提供了一个统一的元数据管理层，支持多种数据源的集成：支持的数据源类型：关系型数据库：MySQL、PostgreSQL、OceanBase、Apache Doris、StarRocks 等大数据存储：Apache Hive、Apache Iceberg、Apache Hudi、Apache Paimon、Delta Lake（开发中）消息队列：Apache Kafka文件系统：HDFS、S3、GCS、Azure Blob Storage、阿里云 OSSAI/ML 数据格式：Lance（专为AI/ML工作负载设计的列式数据格式）REST API 服务Gravitino 提供了丰富的 REST API 服务，支持不同数据格式的标准化访问：Gravitino 核心 REST API完整的元数据管理 RESTful API 接口支持 Metalake、Catalog、Schema、Table 等所有元数据对象的 CRUD 操作支持用户、组、角色和权限管理的完整 API提供标签、策略、模型等高级功能的 API 接口支持多种认证方式（Simple、OAuth2、Kerberos）Iceberg REST 服务遵循 Apache Iceberg REST API 规范支持多种后端存储（Hive、JDBC、自定义后端）提供完整的表管理和查询能力支持多种存储系统（S3、HDFS、GCS、Azure等）Lance REST 服务实现 Lance REST API 规范专为 AI/ML 工作负载优化支持高效的向量数据存储和检索提供命名空间和表管理功能元数据实时获取和修改Gravitino 采用直接元数据管理模式，确保数据的实时性和一致性：实时同步：对元数据的变更会立即反映到底层数据源双向同步：支持从 Gravitino 到数据源，以及从数据源到 Gravitino 的元数据同步事务支持：保证元数据操作的原子性和一致性版本管理：支持元数据的版本控制和历史追踪统一访问控制Gravitino 实现了跨多数据源的统一权限管理：核心特性：基于角色的访问控制（RBAC）：支持用户、组、角色的灵活权限管理所有权模型：每个元数据对象都有明确的所有者权限继承：支持层次化的权限继承机制细粒度控制：从 Metalake 到具体表的多层级权限控制支持的权限类型：用户和组管理权限目录和模式创建权限表、topic、fileset的读写权限模型注册和版本管理权限标签和策略应用权限统一数据血缘基于 OpenLineage 标准，Gravitino 提供了完整的数据血缘追踪能力：自动血缘收集：通过 Spark 插件自动收集数据血缘信息统一标识符：将不同数据源的标识符转换为 Gravitino 统一标识符多数据源支持：支持 Hive、Iceb…

双 11 大促峰值不翻车：淘天集团 Paimon + StarRocks 大规模 OLAP 查询实战与优化
type: item
date: 2026-01-27T16:56:12+08:00
description: 作者：朱奥 /淘天集团高级数据工程师导读：双 11 等大促场景会在短时间内集中爆发：运营与业务 BI 在开卖后的窗口期密集访问数据产品，瞬时请求量陡增，对查询引擎的稳定性、成本与治理体系提出极高要求。与此同时，业务对近实时数据产品的诉求持续增强，传统“多存储、多链路、依赖回刷”的模式在研发效率、回刷成本与响应速度上逐步暴露瓶颈。本文围绕 Paimon 与 StarRocks 的组合实践，梳理淘天在大规模 OLAP 查询场景下的架构演进与双 11 保障体系：通过实时与离线统一入湖，消除数据同步链路与多份存储成本；基于稳定中间层叠加在线现算与维表实时关联，将高消耗回刷转化为秒级查询，核心场景回刷效率提升约 80%，年化节省成本接近 1000 万；同时结合 StarRocks + RoaringBitmap 低成本解决跨天交叉实时 UV 计算难题，满足大促近实时决策需求。1 淘天集团营销活动 OLAP 查询的探索背景与核心策略1.1 当前数据架构首先，简要介绍当前的数据架构与数据流转方式。从 DWD 层开始，我们的数据分为实时与离线两条主链路：实时数据主要存储在 TT中，在业界可类比为 Kafka 一类的消息队列；离线数据主要存储在 ODPS 中。在数据加工与写入层面，我们会启动 Flink 流批一体任务：实时侧持续消费 TT 中的数据；离线侧消费 ODPS 中的数据；在计算过程中，任务会关联多类 ODPS 维表，例如类目维表、商家分层等维度信息。计算完成后，结果统一写入 ADS 层的Holo 表中，并在数据服务层对外透出。在纯离线场景下，我们会通过 ODPS 任务读取 ODPS 数据，同时写入 ADS 层对应的 ODPS 表。这里既包含历史天级数据，也包含历史小时级数据。当存在查询加速需求时，我们还会将 ODPS 数据进一步导入到 Holo 中。在数据服务层，我们主要通过 Holo 或 MC 对外提供数据服务。我们会根据查询时延要求选择不同的服务路径：当业务对响应速度要求更高、需要达到毫秒级时，通常通过 Holo 提供查询服务；当时延要求相对宽松，例如百毫秒级或秒级，则更多通过 MC 来承载查询请求。1.2 业务诉求与核心痛点随着业务发展，我们当前面临的诉求主要来自两个方向：一是业务侧希望获得更多实时数据产品；二是业务 BI 的实时分析需求持续增长。这对数据研发提出了新的挑战：进一步提升研发效率。回到现有架构，其核心痛点主要体现在两方面：流批存储不统一：实时数据存储在 TT 中，离线数据存储在 ODPS 中；当存在查询加速需求时，部分数据还需要进一步落到 Holo 表中。整体开发架构较为复杂，数据需要在多个存储介质之间流转，导致端到端链路拉长。在查询特性上，Holo 在点查场景具备更突出的性能优势，且整体稳定性较强，在淘天历年大促期间的表现也相对稳定。但在更常见的 Shuffle 场景下，整体查询性能相对一般。尤其当 OLAP 查询负载更重、需要进行更复杂的计算，或需要关联规模较大的维表时，Shuffle 相关的执行效率会成为瓶颈，导致查询耗时明显拉长。数据更新与维护上也存在较高成本。以 ODPS 中的维表为例（如类目维表、商家分层维表等），当维表发生业务变更时，往往需要触发 ADS 层任务的回刷，从而带来额外的回刷开销。业务对“近实时”的诉求在部分场景下出现了被动降级。例如在跨天实时 UV 等场景中，由于 state 规模较大、成本较高等原因，方案不得不从实时级别降级到小时级别。从业务视角看，近实时能力仍然是明确存在的需求。1.3 核心策略1）架构简化提效架构上实现 存储介质的统一：将实时与离线数据统一沉淀到 Paimon 的湖存储中。在此基础上， StarRocks 可以直接面向湖存储进行高性能分析查询，从而能够消除数据同步链路以及多份存储带来的成本。降低使用门槛，让数据更容易被上层分析与 BI 使用。以实时链路为例，原本实时数据存储在 TT 中，而 TT 的数据形态具有明显特征：每行数据是一个字符串、缺少 schema。在这种形态下，数据虽然可以被消费，但如果要面向 BI 分析使用，往往还需要额外进行反序列化与解析，这会带来不可忽视的工程与使用成本。在统一存储之后，Paimon 将实时与离线数据沉淀在同一张表中，并提供明确的 schema。这意味着，上层使用方可以直接面向结构化数据开展分析：即使分析师的数据开发能力不强，也可以基于 Paimon 的近实时中间层，通过 StarRocks 自助完成对近实时数据的分析。在这种模式下，过去一些相对简单的取数与分析需求，可以由 BI 或分析师通过自助方式直接完成，不再必须提交给数据研发排期处理，从而在一定程度上减少数据开发侧的需求量与交付压力。2） 业务难点攻坚通过稳定的中间层 Pa…

从Kafka到AutoMQ：爱奇艺实时流数据架构演进
type: item
date: 2026-01-26T16:02:24+08:00
description: 从Kafka到AutoMQ：爱奇艺实时流数据架构演进概述本文详细介绍了爱奇艺在处理大规模实时流数据时，从传统Kafka架构向AutoMQ演进的技术历程。为了解决私有云环境下集群扩缩容难、资源利用率低以及运维成本高等挑战，爱奇艺开发了Stream平台与Stream-SDK，实现了业务与底层存储的彻底解耦。随后，公司引入公有云服务并最终切换至基于存算分离架构的AutoMQ，利用其单副本存储和秒级弹性的特性，显著提升了系统的灵活性。这一系列的架构升级不仅优化了数据治理体系，还成功将运营成本降低了70%以上。目前，爱奇艺正持续扩大AutoMQ的应用规模，以进一步实现降本增效的长期目标。背景Kafka因其高吞吐、低延时、可扩展的特性，在出现之后迅速成为流数据存储的标准组件，广泛应用于实时大数据场景。爱奇艺的流数据服务也主要基于Kafka构建，随着实时大数据应用越来越广泛，Kafka集群数量、规模越来越大，面临扩缩容繁琐、成本高、难治理等诸多问题与挑战。为解决这些问题，我们进行了Kafka服务化、上云、迁移AutoMQ等一系列探索。本文将介绍爱奇艺Kafka从私有云迈向公有云、从Kafka到AutoMQ的探索与实践。流数据在爱奇艺的应用在爱奇艺，流数据的存储组件使用的是Kafka，计算组件主要使用的是Flink，流数据相关的典型数据通路如图1所示，主要包括如下环节：数据集成：Pingback(端上投递日志)、后端日志、数据库binlog、指标等持续产生的流数据，实时写入数据总线Kafka。数据仓库：由Flink程序将数据引入到实时（流式）、离线（批式）数仓。在实时数仓中，数据仍然以流数据形态存储在Kafka中，并通过Flink构建实时数仓各层数据。在离线数仓中，流数据将会聚集成批数据存储在Iceberg中，再由 Flink增量消费Iceberg构建离线数仓各层数据。实时数仓具备秒级延时，离线数仓具备分钟级以上延时。数据开发：数仓的数据通过数据开发平台应用到各业务场景。在实时计算中Kafka也会作为中间流数据的存储用于任务之间的解耦。数据应用：数据广泛应用到爱奇艺的推荐、搜索、广告、报表等等场景中。数据的价值随着延时增大快速衰减，为了数据价值最大化，近几年主要应用场景都已切换到流数据。Kafka作为流数据的存储承担数据集成到大数据体系的数据总线、实时数仓存储、实时任务之间解耦等角色。流数据存储服务：从管集群到管数据爱奇艺的流数据服务最初以Kafka集群为核心构建，提供集群生命周期管理、Topic管理、消费监控等基础能力。随着业务规模扩大、集群数量和数据量持续增长，逐渐暴露出以下问题：业务与集群强耦合：业务代码直接依赖Kafka地址访问集群，一旦需要迁移或调整集群，必须修改业务代码并重新上线，不灵活。同时也无法从平台侧统一识别和监控各业务的读写行为。缺乏统一的数据与schema管理：平台没有管理数据描述、schema、数据归属等元数据信息，无法提供数据查找功能，不利于跨团队的数据理解、复用与治理。主备数据管理缺失：对重要数据，业务侧通常配置主备链路，但平台侧缺乏对主备关系的统一管理，难以做到一致性保障与故障切换治理。为了解决上述问题，我们将流数据存储服务升级到了如图2所示的架构，由Stream平台、Stream-SDK、存储组件三部分构成。先介绍下Stream平台，Stream-SDK和存储组件后面介绍。Stream平台由“集群管理”和“数据管理”两大模块组成。集群管理负责集群生命周期与底层资源的统一管理，侧重运维侧能力。数据管理是平台的核心，以“数据为中心”构建，面向数据开发人员提供统一的数据视图和管理能力，核心功能如下：逻辑队列：原先“集群+Topic”定位数据的方式，升级为基于“项目+队列（Topic）”的逻辑命名方式，集群仅作为队列的一个属性，消除业务对具体集群的依赖。逻辑队列还支持同时绑定主备两个集群，结合Stream-SDK可实现主备链路的一键切换。Schema管理：支持为队列配置schema，并自动同步至大数据元数据中心，使队列能够在数据开发平台中自动映射为逻辑表，使用SQL直接处理流数据。数据地图：提供队列的多维度查询与检索能力，支持在线申请和授权使用队列，简化跨团队的数据查找和复用流程。数据血缘：基于Stream-SDK自动上报的读写端信息，构建应用级的读写血缘链路，帮助快速定位上下游数据关系及影响范围。Stream-SDK：统一的流数据读写客户端Stream-SDK是平台提供的统一数据访问客户端，封装了底层原生客户端，兼容Kafka协议和RocketMQ。业务仅需配置“项目+队列”，即可完成数据读写，无需关注具体集群地址或认证方式，从而实现业务代码与底层集群的彻底解耦。Stream-SDK的数据读写流程如图3所示，主要包括…