01 背景
1.1 什么是数据一致性校验
在数据迁移、数据同步以及多数据中心部署等场景中,数据的一致性要求极为严格。然而冗长的同步计算链路产生的误写或丢失、主从复制延迟产生的脏读,业务双写、人为误操作产生的脏数据等众多因素,都可能导致数据不一致。
通过建设数据一致性校验能力,能够及时、准确的发现并解决数据不一致问题,有效降低对业务的影响。
1.2 数据一致性校验应具备的能力
在小红书内部,数据传输服务每天服务着众多的业务,保障着众多的数据同步任务,在数据同步过程中,源端和目标端的数据一致性需要严格保证,否则将会产生业务损伤。同时,在面对不同的业务场景下,数据一致性校验工具能够进行无损且快速的数据校验。因此,针对数据一致性校验工具我们需要面对以下难点:
- 数据量和内容不断地变化:在数据校验过程中,源端和目标端数据的总量和内容可能都在变化,是一个动态的过程,数据校验能力需要应对不断变化的数据,防止产生误报;
- 无锁且不停服的数据校验:数据一致性校验不能影响现有的业务,需要在业务不停服的情况下进行,且应该在无锁状态进行,避免影响业务读写操作;
- 对数据库的性能影响要可控:校验工具一般都会高并发读取数据库的数据,然而,数据库同时承担着线上的业务应用。如何有效平衡数据校验速度以及数据库稳定性是校验工具应该解决的重要命题。
- 适配不同数据源:由于校验数据源具有多样性,数据校验需要考虑到不同数据源之间的差异,能够在不同数据源之间实现数据校验工作;
- 数据分布不均匀:在源端和目标端数据分布不均匀的场景下(如源端和目标端分表数量不一致),数据校验程序能够将源端数据正确映射到目标端,并进行数据校验工作。
- 快速定位不一致内容:数据校验的目的是为了验证数据一致性,并针对不一致数据进行快速补救。所以,能够定位并提供具体不一致的内容也是数据校验工具的重要特质。
- 快速订正数据的能力:当数据校验定位到不一致内容后,是否能够提供数据订正脚本帮助用户快速修复不一致数据也是校验工具必不可少的基础能力。
02 现状分析
随着小红书公司业务的不断发展,原先的MySQL集群容量已经无法满足业务的发展,因此需要对原先的MySQL集群进行扩容等操作,以满足业务不断增长的需求。数据迁移一般需要将全部数据从源端迁移到目标数据源上,迁移通常是一次性的,迁移之后链路即停止。常见的场景有:
- 集群扩缩容,当预期流量增长或者资源达到瓶颈,对整个数据库集群分片扩容,以减轻各个分片的压力,同理预期流量下降或者资源利用率偏低时,要对集群缩容,避免资源浪费。
- 库表迁移,由于容量或者业务逻辑变动,将数据库集群上的部分库或表迁出,到新的集群中,或者分表规则变更(分表键,分表数,分表规则变更)都需要将原有数据同步一份至新表中。
- 异构数据源迁移,比如技术升级或者存储介质变更,需要将历史数据同步至新的数据源。
在数据迁移过程中,我们利用自研的数据传输服务将数据从源集群同步到新集群。然而,网络抖动、脏写污染等问题可能导致源端与目标端数据出现不一致。然而,现在的一些业界解决方案可能无法满足现在小红书内部的复杂业务场景,我们需要一款适配上述各种场景的数据一致性校验工具,来确保在数据传输过程中的数据质量,保障数据的一致性。因此,我们决定为小红书打造一套全新的数据校验系统,以应对内部业务的多样化和现有基础架构的挑战,它融合了业界成熟的校验技术。其主要具有以下特性:
- 允许源端和目标端数据分布不一致:数据一致性校验工具能够适应数据分布不一致的情况,针对单表、分库分表等场景都能够很好的进行校验工作。
- 自动选择最佳校验方式:根据源端和目标端的表结构以及数据分布等信息,数据一致性校验工具会自动选择最合适的校验方法,从而快速进行数据校验。
- 适应动态数据变化:数据一致性校验工具支持在数据量和内容不断变化的情况下进行校验。
- 无中断&无锁校验:数据一致性校验工具能在不中断服务且无需锁定的状态下进行数据校验,确保业务和同步链路的顺畅运行。
- 校验参数动态可配置:数据一致性校验工具提供了一系列可配置参数,允许用户根据需要动态调整校验速度和批次大小。
- 快速定位不一致内容:数据一致性校验工具在发现数据不一致时,能够快速发现具体不一致的内容。
- 自定义列校验和规则转化:数据一致性校验工具支持自定义列校验,即使源端和目标端列名不同,也能通过配置列映射实现校验。同时支持用户自定义列转化规则。
03 数据一致性校验在小红书内部得实现
3.1 校验类型
按照数据校验的方式,可以划分为全量数据校验和增量数据校验:
- 全量校验:这种方法涉及对数据库中所有数据的一次性检查,确保高准确度。然而,它反映的仅是校验时刻的数据状态。全量数据校验又被分为同构全量数据校验和异构全量数据校验,通常情况下,全量数据校验建议多次周期性运行,以确保数据一致性。
- 增量校验:此方法基于数据变更事件,仅校验新变更的数据,减少了校验量并提高了实时性。但它无法覆盖历史数据的一致性校验。
在实际应用中,我们会根据具体情况灵活结合这两种校验方式,以更有效地确保数据的准确性和时效性。
在实际实践中,我们将全量数据校验根据源端和目标端校验表结构的差异又细分为同构校验和异构校验,它们的主要区别如下:
在实际进行全量数据校验时,数据一致性校验工具会自动根据源端和和目标端的数据源类型、校验表的数据分布以及数据校验任务配置等多种因素为校验任务选择合适的校验方式,此过程中用户不感知。
3.2 方案实现
基于实时数据流传输服务的特点,我们抽象了读取端(Reader)、写入端(Writer)和处理端(Processor)组件,实现了业务逻辑解耦。
- 读取端(Reader):主要负责从源端获取数据,分为Selector和Replicator。Selector主要负责在全量数据校验时对全量数据的抽取,而Replicator主要负责在增量数据校验时对Binlog的解析。
- 处理端(Processor):主要负责数据的处理、过程和加工。在数据校验时,如果用户自定义了列映射或者数据转化规则,此时通过Processror可以对数据进行一次二次转化,然后和目标端数据进行对比。
- 写入端(Writer):主要负责将数据写入下游,主要包括数据校验实时位点更新、校验摘要更新以及校验不一致数据的持久化等。
3.3 全量数据校验
全量数据校验是指对数据库中的全量数据进行一次对比,它是一次性任务。在实际实践中,全量数据校验一般会被多次运行,从而确保数据的完整性和准确性。全量数据校验需要在数据传输服务全量同步任务运行完成后,且增量同步任务追平延迟后开启,否则会因为数据同步延迟导致大量数据不一致误判。
全量数据校验分为同构校验和异构校验,两者均采用分块抽样校验法。数据一致性校验工具在执行全量校验时,会分批次从源端和目标端提取数据块,然后对比这些数据块以验证一致性。分块策略允许用户配置数据块的大小,每次从数据库中提取固定数量的数据进行校验。一旦完成一个数据块的校验,程序就会继续下一个数据块。当提取的数据量小于设定的数据块大小时,校验结束。若在某个数据块中发现不一致,将进行复检,仅当多次校验均不一致时,才会记录为数据不一致。采用分块校验的原因包括:
- 提高校验效率:避免一次性处理大量数据,减少对比时间,加快整体校验速度。
- 减少业务影响:分块校验减轻了对业务数据库的读取压力,避免对业务操作造成显著影响。
同构全量数据校验通过校验和(checksum)实现,因为上下游数据分布是均匀的,我们可以通过主键对数据进行分块的checksum校验。在此过程中,待校验表的数据被划分为多个固定大小的校验块(chunk)。在特定时刻,源端和目标端的对应数据块将进行整体Hash校验和(如CRC32),以判断数据是否一致,同构校验过程中,校验块的大小可以动态调整,设置过大可能会增大数据库压力,同时可能会因为区间过大导致区间数据不一致概率大;设置过小,可能会降低校验速度。在实际应用中,业务可以根据上下游数据库的指标以及数据变化情况进行动态调整数据块的大小。
当校验过程中,发现某个 chunk 的上下游的 checksum 不一致,通过二分法将原来的 chunk 划分成大小接近的两个子 chunk,对子 chunk 进行 checksum 对比,进一步缩小不一致行的可能范围。通过 checksum 对比不断的缩小不一致行的可能范围,可以减少需要进行逐行对比的数据行,加快对比速度,减少内存损耗,并且由于每次计算 checksum 都相当于遍历一次二分后的子 chunk,理论上不考虑多次额外消耗,二分检验的开销相当于只对原 chunk 多做两次 checksum,当chunk大小变成1时,即可找到对应的不一致记录。但是,在一个校验块内,如果我们发现源端的数据比目标端数据要少,我们会通过逐行对比的方式去寻找出不一致的数据。
异构全量数据校验采用逐行对比的方法。在执行校验时,系统会分批次从源端提取数据,并通过一系列预设规则进行处理,以便与目标端的数据进行比较。一旦发现数据不一致,系统将自动进行复检,且复检的间隔时间会逐渐延长,呈指数级增长。这种机制旨在减少对系统的不必要负担,同时确保数据的准确性。
3.4 增量数据校验
增量数据校验专注于验证数据迁移、同步或更新过程中新增或修改的数据,确保数据的完整性和准确性,对保持数据一致性和可靠性至关重要。数据一致性校验工具的增量校验功能实时监控源端数据变更,并与目标端数据进行比对。它与全量数据校验独立运行,用户可按需选择是否启用增量校验。
增量校验以源端数据库为基准,利用其binlog来驱动校验过程。通过主键或唯一键,系统会检索目标数据库中相应的行数据,进行一致性对比。考虑到数据同步或校验任务可能存在延迟以及数据频繁变更等问题,实际的源端与目标端数据库数据可能比已消费的binlog位点更新。为应对这种情况,我们设计了延迟点查以及复查机制来对两边数据库的当前数据执行一致性比对,确保数据的准确性。
04 总结与展望
4.1 阶段性总结
小红书MySQL数据一致性校验工具自上线以来,已经在数据库迁移、单元化等重要场景得到了很好的应用,为小红书内部业务提供了数据一致性保障。
4.2 展望
后续关于数据一致性校验将在以下方面继续深入建设。
- 增强产品成熟度:持续深化现有功能,简化操作流程,提升用户体验。后续会丰富数据源,支持更多的端到端异构数据校验。
- 扩展产品应用范围:进一步扩展至数据入湖入仓、数据变更订阅、缓存更新等场景,以全面提升数据传输的服务质量,同时支持用户定制业务逻辑,支持对账等复杂场景。
- 提升数据修复效率:完善数据修复功能,减少手动操作,降低成本,提供一键生成修复SQL能力,快速进行回归验证。
- 完善数据质量大盘:提供归因分析能力,对产生的不一致数据进行原因推测,建立质量大盘。
05作者简介
初原(张勇)
小红书关系型数据库部研发工程师,数据库中间件小组成员,毕业于西北工业大学,现主要负责小红书数据传输服务的日常维护与迭代。
元甲(郑云龙)
小红书关系型数据库部研发工程师,数据库中间件小组成员,毕业于浙江大学,曾就职于美团基础架构中间件中心,目前是小红书数据传输服务负责人。
克邪(沈力锴)
小红书关系型数据库部研发工程师,数据库中间件小组负责人,毕业于中国科学技术大学,现主要负责小红书数据传输服务、数据库代理和数据库SDK等数据库中间件产品的整体架构和技术演进。