携程基于Flink与哈希算法原理解析,如何利用哈希函数预测博彩走势Paimon的近实时湖仓建设实践

2025-12-11

  哈希算法,SHA256,哈希函数,加密哈希,哈希预测/哈希算法是博彩游戏公平性的核心,本文详细解析 SHA256 哈希函数的运作原理,并提供如何通过哈希技术进行博彩预测的方法!随着携程业务的快速全球化扩张,携程传统 T+1 数据时效的离线数仓已无法满足日益增长的准实时分析决策需求。为解决 Lambda 架构下开发运维成本高昂、链路割裂、时效性不足等核心痛点,我们设计并实践了一套以 Flink CDC 与 Apache Paimon 为核心的近实时湖仓一体化解决方案。

  本文首先阐述了该方案的整体架构设计,重点介绍了为满足生产环境约束而构建的两阶段 CDC 数据入湖机制,并详细阐述了如何通过性能优化、动态更新和引擎改造等一系列实践,攻克了生产环境中的关键挑战。最终,通过在国际化营销、广告归因等场景的应用,方案实现了端到端分钟级延迟,验证了其在降本增效和驱动业务敏捷决策上的显著价值。

  携程原有数据体系已构建了成熟的离线批处理链路,能够支撑大部分 T+1(天级)或 T+1H(小时级)的数据分析场景。然而,随着业务的持续增长与精细化运营的需求,数据新鲜度与计算成本之间的矛盾日益凸显。

  纯实时计算:虽能实现秒级延迟,但在处理大规模数据时,面临状态管理成本高昂、消息中间件存储开销巨大等问题,导致总成本显著增加。

  Lambda 架构:因实时与离线链路物理割裂,在面对融合分析需求时,往往需要双团队协同开发,涉及大量数据口径对齐工作,造成高昂的人力协调成本,阻碍了业务敏捷响应。

  为应对上述挑战,业务亟需一个低门槛、低成本、端到端具备分钟级延迟(目标 5-30 分钟)的流批一体数据解决方案。该方案旨在统一数据处理链路,显著提升端到端时效性,同时降低开发、运维负担与总体运行成本。为此,我们选择了 Flink + Paimon 的技术栈,并设计了一套创新的数据入湖架构来解决数据同步与数据应用,旨在从根源上解决这些挑战。

  为实现上述目标,我们构建了如图 1 所示的近实时数据处理架构。该架构以 Flink作为核心计算引擎, Paimon 作为湖仓存储底座。数据通过 Flink CDC 从 MySQL 等业务数据库捕获变更数据流,实时写入 ODS 层的 Paimon 表中。下游应用可根据需求,选择多种消费与分析路径:

  实时/准实时 ETL:通过 Flink 作业持续消费上游 Paimon 表的增量数据,进行实时流式处理。

  高速 OLAP 查询:将计算结果物化或直接接入 StarRocks,满足高性能、交互式的分析查询需求。

  灵活的 Ad-hoc 查询与离线分析:借助 Trino 或 Apache Spark 引擎,对湖内数据进行灵活的即席查询与大规模批处理分析。

  通过该架构,我们为不同业务方提供了统一、多样的近实时数据服务,实现了计算与存储的高效协同。

  在技术选型上,我们选择 Paimon 作为核心存储底座,主要基于其与 Flink 生态的深度原生集成、灵活的 Merge Engine 机制(如 partial-update、aggregation)以及 LSM 树结构的存储模型。相比 Hudi 或 Iceberg,Paimon 在我们的 Upsert 密集型场景中展现了更优的写入性能和更低的维护成本,有力支撑了近实时湖仓的构建。

  携程大量业务数据存储于 MySQL 中,其线上部署遵循 master-slave-slavedr 模式。为了保障线上数据库的稳定性,我们对同步任务有一些限制策略:

  Binlog 读取限制:每个 MySQL 物理实例(Instance)仅允许一个线程读取其 binlog,以避免并发读取对 binlog 归档产生干扰。

  上述单实例单线程读取 binlog 的约束,是催生我们设计“共享 Source,独立 Sink”两阶段 CDC 架构的根本原因。若为每个用户的同步任务单独启动一个完整的 CDC 作业,将占用实例的唯一 binlog 读取进程。因此,我们设计的 CDC 同步流程(如图 2 所示)分为两个独立的阶段:

  第一阶段(source 任务):由平台统一管理的共享 Flink 作业。该任务负责从指定 MySQL 实例读取 binlog,并将增量数据分发至 Kafka。此任务对普通用户透明且不可操作,确保了对核心 DB 资源的合规、高效复用。

  第二阶段(sink 任务):由用户自行管理的 Flink 作业。该任务从 Kafka 消费数据,并写入目标 Paimon 表。用户可对此任务进行启停、配置等操作。

  该架构支持单库单表、单库分表、分库分表等多种同步模式,并通过平台化的管理,实现了对复杂 DB 环境的有效适配。Sink 任务支持多种运行模式:

  全量+增量一体化模式:首次启动时,作业自动执行全量数据快照同步,完成后无缝切换至 Kafka 的指定位点,开始消费增量数据。

  挑战:我们的一阶段任务是将 binlog 的增量数据同步至 Kafka,在最初上线的时候我们发现同步的速率较慢, 延迟较高,无法满足分钟级别的需求。

  单线程反序列化:从 MySQL 拉取数据后的反序列化操作在 Flink CDC Source 算子内部是单线程执行的。

  如下图 3 所示,即使你设置了并行度为 16, 实际的工作线。 这个环节存在较大的性能瓶颈。

  解法: 为了优化这个问题, 我们在反序列化环节增加了埋点。通过数据分析,发现耗时更高的实际上是单线程写 Kafka 这一块,因此后面我们通过 db.table.primary_key 作为 Kafka key 来进行数据分发,这样只需要做到主键之间的数据有序即可。这样可以将解析 binlog 和写 Kafka 进行解耦, 如下图 1 所示。通过这种方式,数据处理吞吐量提升了近 10 倍。

  挑战:数据可能因为作业异常而丢失, 如果每次出错都需要全量回刷成本较高,必须具备可靠的数据回补(补数)机制。

  分析:数据回补机制是保障数据质量的关键环节。我们探讨了两种方案,如图 4 所示:

  方案一:基于归档的 binlog 文件回放,优点在于可以完整还原增删改操作,不依赖业务表结构;但这种方式依赖公司数据库管理员(DBA)的支持。另外,由于公司不同的数据库可能部署在同一台物理机上,可能存在越权访问非目标 DB 的问题。

  方案二:基于时间戳字段回溯,依赖业务表中的 DataLastChange_time 等更新时间字段,通过筛选时间范围来拉取数据。优点是实现简单、依赖少。缺点是无法还原物理删除操作,且强依赖表结构和时间字段的可靠性。

  鉴于携程数据库 MySQL binlog 中涉及到了大量的线上数据,基于安全考虑无法重放,因此我们主要采用的是第二种方案。用户可在平台上配置起始时间,一键启动 Sink 任务。此模式下,作业会先拉取指定时间范围的历史数据,完成后自动切换到增量消费模式。

  解法:我们开发了带有时间戳过滤的全增量一体的补数方案, 如图 5 所示。用户可以通过配置,可以进行一键补数。其核心是带有时间戳过滤的全增量一体同步。但是这个方案存在一个局限:就是会导致 MySQL 一些被删除的数据无法同步到 Paimon 中删除。即在异常期间,源端数据库已删除的数据,其删除操作未能同步到 Paimon,导致这些数据在 Paimon 中仍然存在。

  另外,由于有一些作业存在特殊的逻辑,因此我们也开发了一些接口给用户进行特殊补数。特殊补数可以通过用户指定 sql 条件来进行补数。例如,线上有些逻辑删除是通过将表中的 时间戳指定到一个特殊的年份来表示删除,对于这些逻辑删除的数据,如果用户在补数时不希望同步它们,可以指定如下过滤条件:--data_backfill_condition mysql_db.mysql_table=not createtime=2000-01-01。支持补数的前提是因为我们的 Paimon 都是主键表,同步数据的操作是幂等操作。所以不会有数据的丢失。无论是基于时间戳的补数,还是带有条件的特殊补数,cdc 二阶段的作业都会在补数完成之后自动切换到增量消费的模式。

  新的挑战:补数模式随之引入新麻烦,作业切完增量重启后无法从 Checkpoint 恢复。补数参数会影响 Hybrid Source 中 Source 的数量。一旦补数完成、作业切换到增量消费模式后,若此时重启作业,就会因为 Source 结构不一致导致无法从 checkpoint 正常恢复(即 Source State 无法恢复)。

  新的解法:为了解决这一问题,我们在 flink 引擎侧新增了一个配置项,允许 Flink 在恢复时直接从 Hybrid Source 中的最后一个 Kafka Source 启动。这样一来,无论是补数模式还是增量模式,作业都能平滑切换,彻底解决了两种模式下的 checkpoint 兼容问题。

  挑战:当链路稳定运行之后,为实现平台化,我们面临一个问题:每当有新用户需要同步新表时,都必须重启共享的 Source 任务,这会引发下游所有消费任务的抖动。最初,我们尝试同步一个 database 下的所有表,但很快发现这会向 Kafka 写入大量非必要数据,且非目标表的批量操作(业务如凌晨刷数、归档等)会导致 binlog 暴增。

  解法:为解决此问题,我们开发了 table-name 参数的热更新功能, 如图 6 所示。Source 任务仅同步用户明确指定的表。当有新的同步链路加入时,数据平台通过向 JobManager 发送请求,将新表名动态传递给运行中的 Source 算子。算子接收到新参数后,无需重启作业即可开始监听新表。该功能极大地减少了写入 Kafka 的数据量,并避免了因任务重启给下游带来的抖动。

  新挑战:对于数据量巨大或存在批量操作的源表,所有数据汇入单一 Kafka Topic,下游多个作业同时消费同一个 Topic,会导致 Topic 流量过载(峰值可达数十 GB/s),可能耗尽特定 Broker 节点的网络带宽,影响整个 Kafka 集群的稳定性。

  最终解法:我们实现了 Topic 分流功能。用户可通过配置路由表,将不同表的数据自动路由到不同的 Topic 中,下游 Sink 任务再根据路由信息消费对应 Topic,有效分散了流量压力。

  在实际生产实践中,根据不同的问题对引擎侧做了一些优化。比如,我们发现在某些场景下,Paimon 对于 float 小数转化存在错误。以及业务方需要基于 bit 类型转化为 boolean(此功能后面在社区已经支持)。

  另外在分库分表同步中,作业启动的时候,每一个 flink subtask 对于每一张表都需要对 Paimon 中进行 schema 验证。如图 7 所示,process 算子实际上是做 schema 变更的。在启动初始化时收到了 1024 条数据。这一步通过 HDFS 来获取 schema 文件速度较慢,会降低 flink 作业从 checkpoint 恢复速度,甚至会导致 checkpoint 失败。因此我们开发了基于时间的 schema 缓存机制,在启动时获取一次 Paimon 的 schema 之后会缓存一分钟。这大大缩短了作业启动耗时。

  另外我们支持了 only-snapshot 模式。这是因为,在某些分库分表的场景下,我们遇到过 Hybrid source 中存在 180 个 source(批模式),这些 source 之间的切换是依赖一个 checkpoint 完成的。因此有时候可能补数本身运行时间是比较短的,大部分时间在等待 checkpoint 完成。此模式可以不必等待 checkpoint 完成,大大提高了补数的效率。

  Paimon 主键表的 bucket 数是一个比较重要的配置 ,Paimon 社区对于 bucket 数推荐是 每个 bucket 大约 200MB - 1GB 数据量。生产中我们发现 dynamic bucket 对于大量的数据而言,写入性能不如 fixed bucket。某些场景下,我们支持了固定步长的 bucket 模式。支持业务方可以通过配置,比如根据数据大小,每增长 100 万条数据增加一个 bucket。

  我们建立了覆盖全链路的表级别监控体系。通过内置的批流切换事件通知, 如图 8 所示,用户可以清晰地了解作业当前状态(全量/增量/回补)。从 MySQL 到 Kafka,再到 Paimon,数据流在各环节的出入口均增加了表级别的指标埋点,用户可基于这些指标配置数据断流、延迟等告警,实现了精细化的可观测性(图 9-图 10)。

  数据入湖后,我们提供了多种增量计算方式。除了使用 Flink 持续消费外,还打通了 Spark 和 Trino 对 Paimon 表的增量读取能力,实现了“批流一体”的计算模式。

  目前,除了已有的 Flink 和 Spark 支持增量消费之外,我们已全面支持 Trino 对 Paimon 的读写、增量读取及 Compact 操作。通过这一能力,Trino 可以无缝访问 Paimon 存储中的实时与历史数据,支持高并发、低延迟的分析查询。与此同时,Paimon 的高效数据管理和增量更新机制,也为 Trino 提供了更加轻量、实时的数据源。

  两者的深度融合有效提升了查询性能与数据一致性,实现了计算与存储的高效协同,进一步完善了湖仓一体的生态体系,为用户带来更灵活、更高效的数据分析体验, 如图 11 所示。另外,我们在 trino 中支持了对 hive udf 的复用,这样可以降低用户的迁移成本。在 trino 支持读取 Paimon 的过程中需要注意以下几点:

  在使用固定分桶(Fixed Bucket)模式时,Trino 侧的数据分发策略必须与 Paimon Writer 内部的分发策略保持严格一致。两者若出现不一致,会导致数据写入错误的 Bucket,进而引发数据正确性问题和查询结果异常。因此在实现时需要确保双方使用相同的哈希算法和分桶逻辑。

  数据分发的核心实现是 BucketFunction 类。需要特别注意的是,该类的实例会在多个线程之间共享使用,因此必须保证其线程安全性。在实现时应避免使用可变的实例变量,或通过适当的同步机制来防止并发访问导致的数据竞争问题。

  在原生实现中,Catalog 逻辑存在一个隐患:Coordinator 和 Worker 节点会并发地拉取同一张表的 Schema 信息。当查询执行时间较长且期间发生了 Schema 变更时,各节点获取到的 Schema 可能不一致,导致查询失败或结果错误。我们已将此逻辑优化为:由 Coordinator 统一拉取 Schema 后分发给各 Worker 节点,确保全局 Schema 一致性。但由于涉及 FileSystem 对象的序列化问题目前的实现方案在代码层面不够优雅,后续可考虑引入更优雅的 Schema 传递机制进行重构。

  采用增量计算引擎,在大幅提升数据处理速度(尤其在变更频繁场景)的同时,显著降低全量计算资源消耗,优化整体计算成本。

  当前业务 A 国际业务已覆盖多个区域,其中国际业绩数据是公司众多业务线决策数据之一。在国际数据处理的业绩模块下,某些业务日期是按照统一时区进行统计和更新,主要基于离线业绩模型产生,其流程具有以下几个特点:

  从数据源到结果产出,整体任务层级多、离线任务众多,数据清洗和整合过程复杂,需要大量的计算资源和时间

  对于海外市场,业务日期窗口仍是按照北京时间来做时间窗口划分,统计每天的数据结果,这就导致非 UTC+8 时区所展示的预订业绩数据,部分取自当天的数据,另外一部分取自前天的数据,进而导致数据统计不准确。

  除统计数据外,目前数据的更新时间也是按照北京时间(UTC+8 时区)展示,对于所在时区排名比 UTC+8 靠后的业务数据,就可能会在所在时区仍在今天,但数据更新时间展示为明天的情况,造成商户误解。

  解决方案:解决上述问题的关键就是提升整体业绩流程的更新频率,通过更新加速,实现所有海外业务所在时区可以及时、准确看到业绩统计数据。最终海外业务采用了近实时湖仓的链路,其整体的链路如下所示:

  我们采用 Flink CDC+Paimon+Trino/Spark 作为小时级数仓的技术底座,通过流式入湖和小时级调度,形成了从多源异构数据采集、分钟级入湖、分层存储管理到最终应用服务输出的全链路技术架构。

  实现了数据分钟级延迟的入湖能力:通过 FlinkCDC 接入 MySQL 表的 Binlog,同时 Paimon 表格式支持 Update,并支持流式写入,分钟级数据合并,从而实现如下优点:

  低延迟性:通过 CDC+Kafka,实现 MySQL 变化数据的实时获取和传输,基于 Paimon 的 ods 表延迟在 5 分钟以内(延迟时间可按需设置,最低可以设置 1 分钟)

  存储成本低:得益于湖格式的 Snapshot 管理,加上 LSM 的文件复用,大幅节省存储资源

  增量计算:通过 IncrementalQuery 机制,将全量计算转为增量,大幅减少每次计算的是数据量,减少数据 IO。Paimon 的增量计算能力,可以支持如下两点功能:

  端到端提效:基于上述 3 项优势,最终实现业绩数据从 ODS 到 ADM 层的产出提效,在 1 小时内完成一个调度批次。

  效率提升:提升业绩汇总数据的更新频率和产出时间,保障海外业务和商户可以在工作时间尽早的关注到数据情况。

  准确性保证:保障了海外单店可以按照所在地时区对日期进行筛选,获取符合海外商户认知的 T-1 日及更早数据。

  业务 B 在全球化战略的背景下,一直在努力推进国际化战略部署。目前海外业务已经集中在英国、亚洲和欧洲各国。

  离线看板与营销侧对数据时效性有更高要求,如:供应商异常处理批量退款,以及海外营销策略的调整,当前的数据新鲜度无法满足业务需求。

  国际业务的员工分散世界各地,时差问题导致 T+1 天数据不符合海外员工的使用习惯。过往国际 T+1 小时票量统计,是通过与后端合作,由后端处理好部分逻辑,数仓再通过 DataX 进行小时级同步,进行逻辑的二次处理。每小时的批量重复同步造成了计算资源的浪费,两边团队耦合的开发也降低了开发效率。

  新架构支持销售监控、客流统计、收入汇总等多维度实时分析场景。同时也支持增量查询机制,大幅提升查询性能。确保数据质量和系统稳定性。解决了因时差问题导致 T+1 数据不符合海外员工使用习惯的问题。延迟由天级降到了分钟级。同时也优化了之前加工链路较为复杂,难以维护的问题,使得运维效率得到了大幅提升。

  业务 C 聚焦于为企业客户提供一站式差旅服务,涵盖机票、酒店、用车、火车等多种场景。客户可通过该系统完成预订、审批、报销等完整流程,随着服务链条延伸、数据流转环节增多,数据量与复杂度持续增长。伴随业务成长及产品形态丰富,对数据时效性的要求也日益提高。过去的 “T+1” 离线数仓架构已无法满足对“准实时”数据分析的需求,而采用传统基于流式平台的实时数仓虽能处理部分实时计算场景,但其适用性受限,且其计算中间层难以直接用于分析。

  在广告投放场景方面,涉及广告的曝光、点击与下单行为的准实时上报。下单行为需与用户近 3 日内的点击日志进行归因匹配,只有在下单前 3 日内存在有效点击行为的订单,方会上报给广告主。该订单上报流程对响应速度有一定要求,业务方希望实现从触发到上报端到端的分钟级时效。

  上报所需字段和逻辑在业务系统中涉及 7 张 MySQL 表,实时多流 Join 实现难度和成本较大、稳定性挑战较大。

  点击日志每日增量多,数据表膨胀速度较快,需有效控制表存储,保障查询和 Join 性能。

  如何高效整合多表数据、管理膨胀的点击日志表,并满足分钟级别的上报时效,是该场景下的核心业务痛点。

  价值:改造后,从最上游的 MySQL 数据到最终的结果归因,端到端时延在 8 分钟以内(还可通过调整 checkpoint 间隔进一步降低),下游业务方表示当前延迟在可接受范围内。和之前的整个离线计算逻辑相比,数据延迟降低了 8 倍,达到准实时的效果。

  携程近实时湖仓生产实践深度总结:面对数字化转型浪潮和业务对实时数据分析需求的急剧增长,携程从传统数据仓库的小时级延迟痛点出发,历经技术选型、架构设计、生产落地等关键阶段,成功构建了一套完整的近实时湖仓一体化解决方案。该方案以 Flink 作为流处理计算引擎,Paimon 作为湖仓存储底座,形成了从多源异构数据采集、实时 ETL 处理、分层存储管理到业务服务输出的全链路技术架构。

  数据新鲜度达到分钟级:采用全增量一体化处理模式,显著降低因传统离线全量与实时增量双链路并行带来的复杂性与维护成本。

  端到端时效跃升: 端到端数据处理时效从天级提升至 5-30 分钟级,满足准实时分析需求。

  主键更新赋能实时场景: 湖仓提供原生主键(Upsert)更新能力,有效支撑实时订单状态、用户画像更新、实时维表变更等需要行级更新的核心业务场景。

  增量计算降本增效: 采用增量计算引擎,在大幅提升数据处理速度(尤其在变更频繁场景)的同时,显著降低全量计算资源消耗,优化整体计算成本。

  构建分钟级 SLA 保障体系: 建立覆盖全链路的、具备分钟级时效性保障能力的 SLA 机制,并配套完善的多级监控与告警体系,确保数据生产的高可靠性与可观测性。

  强化 Paimon 表治理能力: 深化 Paimon 表核心管理功能,元数据治理(如血缘、Schema 变更跟踪)及自动化生命周期管理(如自动 Compaction、数据过期清理),提升表管理效率与数据质量,支撑高频更新等复杂场景。

  推动准实时链路规模化落地: 持续扩大准实时湖仓架构在核心数仓场景的应用范围,沉淀并推广优秀实践,实现技术价值向业务价值的高效转化与闭环。

地址:广东省广州市天河区88号 客服热线:400-123-4567 传真:+86-123-4567 QQ:1234567890

Copyright © 2012-2025 哈希游戏推荐 版权所有 非商用版本