开源一个超好用的数据核对/对账框架

项目地址:github.com/starslink/d...

🚀 高性能、多策略的数据对账框架,支持内存、流式、并行、Redis、数据库等多种处理方式

✨ 特性

  • 🎯 多种对账策略 - 内存、流式、并行、Redis、数据库、增量处理
  • 🔧 灵活配置 - 支持注解和适配器两种数据定义方式
  • 📊 性能优化 - 根据数据量自动选择最优处理策略
  • 🌐 分布式支持 - Redis分布式缓存,支持集群部署
  • 💾 内存友好 - 流式处理避免大数据量内存溢出
  • 高并发 - 多线程并行处理,充分利用CPU资源

🚀 快速开始

1. 添加依赖

xml 复制代码
<dependency>
  <groupId>com.starslink</groupId>
  <artifactId>data-check</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

2. 基础使用

java 复制代码
// 创建对账配置
CheckConfig config = CheckConfig.builder()
        .id("order-check")
        .name("订单对账")
        .srcLoader(date -> loadSourceData(date))      // 源数据加载器
        .targetLoader(date -> loadTargetData(date))   // 目标数据加载器
        .allowableErrorRange(BigDecimal.valueOf(0.01)) // 允许误差
        .checkAfter(context -> {
          // 处理对账结果
          System.out.println("发现差异: " + context.getCheckResult().getDiffDetails().size());
        })
        .build();

// 执行对账
CheckExecutor executor = CheckExecutor.buildExecutor(config);
CheckContext result = executor.process("2023-12-01");

3. 数据实体定义

方式一:使用注解

java 复制代码
public class Order {

  @CheckIdentity
  private String orderId;

  @CheckField(order = 1)
  private BigDecimal amount;

  @CheckField(order = 2)
  private String status;
}

方式二:实现适配器

java 复制代码
public class OrderAdapter implements CheckAdapter {

  @Override
  public String getKey() {
    return orderId;
  }

  @Override
  public Map<String, Object> getCheckData() {
    return MapUtil.of("amount", amount, "status", status);
  }
}

📊 处理器选择

处理器类型 适用数据量 主要特点 使用场景
Memory < 10万 全内存,速度最快 小数据量,实时对账
Stream 10万-100万 分批处理,内存友好 大数据量,防止OOM
Parallel 任意 多线程并行 CPU密集型,追求速度
Redis 任意 分布式缓存 集群环境,数据共享
Database > 100万 SQL优化 超大数据量
Incremental 任意 增量处理 定期对账,减少计算

🔧 高级配置

流式处理(推荐大数据量)

java 复制代码
CheckConfig config = CheckConfig.builder()
    .id("stream-check")
    .batchSize(5000)  // 批次大小
    .checkProcessor(new StreamCheckProcessor())
    .build();

并行处理(推荐多核CPU)

java 复制代码
CheckConfig config = CheckConfig.builder()
    .id("parallel-check")
    .isAsync(true)
    .checkProcessor(new ParallelCheckProcessor())
    .build();

Redis分布式处理

java 复制代码
CheckConfig config = CheckConfig.builder()
    .id("redis-check")
    .checkCacheEnum(CheckCacheEnum.REDIS)
    .redisConfig(redisConfig)
    .build();

数据库处理(超大数据量)

java 复制代码
CheckConfig config = CheckConfig.builder()
    .id("database-check")
    .checkProcessor(new DatabaseCheckProcessor(dataSource))
    .build();

增量处理

java 复制代码
IncrementalDataProvider provider = new MyIncrementalDataProvider();
CheckConfig config = CheckConfig.builder()
    .id("incremental-check")
    .checkProcessor(new IncrementalCheckProcessor(provider))
    .build();

🎯 智能选择策略

java 复制代码
public CheckProcessor selectOptimalProcessor(int dataSize) {
  if (dataSize < 10_000) {
    return new MemoryCheckProcessor();           // 小数据量
  } else if (dataSize < 100_000) {
    return new ParallelCheckProcessor();         // 中等数据量
  } else if (dataSize < 1_000_000) {
    return new StreamCheckProcessor();           // 大数据量
  } else {
    return new DatabaseCheckProcessor(dataSource); // 超大数据量
  }
}

📈 性能对比

makefile 复制代码
数据量: 100万条记录测试结果

Memory处理器:    ❌ OutOfMemoryError
Stream处理器:    ✅ 45秒, 内存占用: 200MB
Parallel处理器:  ✅ 28秒, 内存占用: 800MB  
Database处理器:  ✅ 35秒, 内存占用: 50MB

🛠️ 完整示例

java 复制代码
@Test
public void testOrderReconciliation() {
  // 模拟数据
  List<Order> sourceOrders = loadOrdersFromSystem1("2023-12-01");
  List<Order> targetOrders = loadOrdersFromSystem2("2023-12-01");

  // 配置对账
  CheckConfig config = CheckConfig.builder()
      .id("daily-order-check")
      .name("每日订单对账")
      .srcLoader(date -> CheckEntry.wrap(sourceOrders))
      .targetLoader(date -> CheckEntry.wrap(targetOrders))
      .allowableErrorRange(BigDecimal.valueOf(0.01))
      .checkProcessor(selectOptimalProcessor(sourceOrders.size()))
      .checkPre(context -> validateData(context))
      .checkAfter(context -> {
        CheckResult result = context.getCheckResult();
        generateReport(result);
        sendNotification(result);
      })
      .build();

  // 执行对账
  CheckExecutor executor = CheckExecutor.buildExecutor(config);
  CheckContext result = executor.process("2023-12-01");

  // 输出结果
  System.out.println("对账完成:");
  System.out.println("- 源数据: " + result.getSource().size());
  System.out.println("- 目标数据: " + result.getTarget().size());
  System.out.println("- 差异记录: " + result.getCheckResult().getDiffDetails().size());
}
相关推荐
gengsa2 小时前
使用 Telepresence 做本地微服务项目开发
后端·微服务
Undoom2 小时前
腾讯云 Lighthouse MCP 的实战全解
后端
0wioiw03 小时前
Nodejs(④GraphQL)
后端·graphql
王同学 学出来3 小时前
跟做springboot尚品甄选项目(二)
java·spring boot·后端
bobz9653 小时前
Calico 项目功能分析:聚焦转发面
后端
bobz9653 小时前
tcp 状态机
后端
阿杆3 小时前
文心快码 3.5S 发布!实测插件开发,Architect 模式令人惊艳
前端·后端·文心快码
文心快码BaiduComate4 小时前
我用Comate搭建「公园找搭子」神器,再也不孤单啦~
前端·后端·微信小程序
计算机毕业设计指导4 小时前
基于Spring Boot + Vue 3的社区养老系统设计与实现
vue.js·spring boot·后端