Etl.Net 2.2.0 项目深度分析

Etl.Net 2.2.0 项目深度分析

说明:分析项目源码版本,https://github.com/paillave/Etl.Net/releases/tag/v2.2.0

1. 项目定位

ETL.NET 是一个用纯 .NET 实现的大规模数据处理引擎,提供类似 LINQ 的流式 API,具备 SSISSQL Server Integration Services)的全部功能甚至更多。核心特点是响应式 (Reactive) 架构,支持多流并行、高性能、低内存占用,即使处理百万行数据也不在话下。

<Project>
  <PropertyGroup>
    <LangVersion>latest</LangVersion>
    <Nullable>enable</Nullable>
    <Version>2.4.0-beta.1</Version>
    <PackageIcon>NugetIcon.png</PackageIcon>
    <PackageReadmeFile>README.md</PackageReadmeFile>
    <Authors>Stéphane Royer</Authors>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    <PackageLicenseExpression>MIT</PackageLicenseExpression>
    <PackageProjectUrl>https://paillave.github.io/Etl.Net/</PackageProjectUrl>
  </PropertyGroup>
  <ItemGroup>
    <None Include="../../README.md" Pack="true" PackagePath=""/>
    <None Include="../NugetIcon.png" Pack="true" Visible="false" PackagePath="" />
  </ItemGroup>
</Project>
  • Github 项目地址,https://github.com/paillave/Etl.Net
  • 官方文档,https://paillave.github.io/Etl.Net/

2. Nuget 包

ETL.NET 完全用 .NET 编写,适用于多平台使用,并且可以直接集成到任何应用中。

3. 整体架构

项目采用核心 + 插件式连接器的模块化架构,解决方案包含 27 个项目

层级项目职责
核心引擎Paillave.Etl流式处理引擎、响应式内核、所有操作符
数据格式TextFile, ExcelFile, JsonFile, XmlFile, Pdf文件解析/序列化
存储连接器SqlServer, EntityFrameworkCore数据库读写
文件系统FileSystem, Zip, S3, AzureStorageAccount, Dropbox文件源/目标
传输协议Ftp, Sftp, Http, Mail网络传输
安全Pgp加密/解密
外部集成GraphApi, Bloomberg第三方 API
辅助ExecutionToolkit, FromConfigurationConnectors, Paillave.EntityFrameworkCoreExtension工具/扩展
测试Tests, XmlFileTests单元/集成测试
教程SimpleTutorial, BlogTutorial, Samples示例代码

4. 核心引擎架构(Paillave.Etl

核心引擎分为两大部分:响应式内核 (Reactive Core)ETL 流层 (Stream Layer)

4.1 响应式内核 — 自研的 Push-based Reactive 框架

项目没有使用 System.Reactive (Rx.NET),而是实现了一套自己的响应式原语:

  • IPushObservable — 核心可观察序列接口,支持 Subscribe(onPush, onComplete, onException)
  • IPushSubject — 同时是 Observable + Observer + Disposable
  • PushSubject — 核心 Subject 实现( 218 行),管理订阅列表、值推送、完成和异常传播,支持 CancellationToken

59 个响应式操作符 位于 Reactive/Operators/ 下:

  • MapSubject, FilterSubject, FlatMapSubject — 基础变换
  • AggregateSubject, AggregateGroupedSubject — 聚合
  • DistinctSubject, GroupSubject, SortedGroupSubject — 去重/分组
  • LeftJoinSubject, CombineWithLatestSubject — 流连接
  • ChunkSubject, SkipSubject, TakeSubject — 分块/截取
  • ConcatenateSubject, MergeSubject — 流合并
  • SubstractSubject — 流差集

关键工厂类 PushObservable 提供 FromEnumerable, FromSingle, Merge, CombineWithLatest, Empty, Range 等静态方法。

4.2 ETL 流层

四种流类型:

接口实现含义
IStream<T>Stream普通无序流
ISingleStream<T>SingleStream<T>只包含一个元素的流(如配置/上下文)
ISortedStream<T,TKey>SortedStream<T,TKey>按 Key 排序的流
IKeyedStream<T,TKey>KeyedStream<T,TKey>按键分组的流

节点基类 StreamNodeBase<TOut, TOutStream, TArgs>(225 行):

  • 每个操作都是一个节点,包含名称、执行上下文、输入/输出流
  • 自动追踪节点间的依赖关系(GetInputStreams 通过反射读取 Args 中的 IStream 属性)
  • 自动管理 IDisposable 资源(WrapSelectForDisposal 系列方法)
  • 创建输出流时自动注入追踪逻辑(计数、异常捕获)
4.3 执行引擎

StreamProcessRunner 是入口点:

config → PushSubject → SingleStream<TConfig> → 用户定义的 Job Pipeline
                                                   ↓
                                            TraceStream → 追踪/日志/统计

执行流程:

  1. 创建 JobExecutionContext(管理节点、任务、追踪)和 TraceExecutionContext
  2. 构建 DI 容器(ServiceCollection + Logging + MemoryCache
  3. 注册取消令牌回调
  4. 调用用户定义的 _jobDefinition(startupStream) 构建流图
  5. 推送 config 值启动流水线
  6. 等待所有 Observable 完成(Task.WhenAll
  7. 返回 ExecutionStatus(成功/失败 + 统计 + 错误信息)

JobExecutionContext 管理:

  • 所有节点的任务(_tasksToWait
  • 资源释放(CollectionDisposableManager
  • 追踪事件推送(_traceSubject
  • 错误时自动取消(_internalCancellationTokenSource.Cancel

5. 39 个流操作符扩展方法

位于 Extensions/ 目录,采用流式 DSL 风格,每个操作符的第一个参数是字符串名称(用于追踪和调试):

类别操作符
变换Select (567行!), SelectResolution (431行), SelectSection
过滤Where, Distinct, OfType, Top, Skip, First, Last
聚合Aggregate, GroupBy, Pivot, Chunk
关联CorrelateToSingle, CorrelateToMany, LeftJoin, Lookup
组合Union, UnionAll, Substract, CombineAllSingles
应用CrossApply, Do, SubProcess
排序Sort, EnsureSorted, EnsureKeyed, ReKey
追踪GetStreamStatistics, KeepLastTracesPerNode, Fix
控制WaitWhenDone, SetForCorrelation, UnsetForCorrelation

6. 关联机制 (Correlation)

CorrelatedETL.NET 的独有特性:

  • 通过 SetForCorrelation 为每行数据分配关联键(HashSet<Guid>
  • 通过 CorrelateToSingle / CorrelateToMany 实现跨流关联(类似数据库 JOIN
  • 典型场景:从扁平文件读取数据,分发到多张表(作者、分类、文章),通过关联键维护外键关系

7. 文件抽象层

IFileValue 统一了所有文件源的抽象:

  • IFileValueProvider — 提供文件(FileSystem, S3, Dropbox, Azure…)
  • IFileValueProcessor — 处理文件(Zip 解压、PDF 解析…)
  • FileValueConnectors — 连接提供者与处理器

8. 数据库持久化

SqlServer 直连SqlServerSaveStreamNode

  • 自动生成 MERGE SQLIF EXISTS → UPDATE ELSE INSERT
  • 支持 SeekOn(匹配键)、DoNotSave(忽略列)
  • 支持 ODBC/OLE DB 适配

EF CoreEfCoreSaveStreamNode

  • 批量处理(Chunk(batchSize)ProcessChunk
  • 双模式:SaveMode.EntityFrameworkCore(标准)和 SaveMode.SqlServerBulk(Bulk Insert)
  • 支持 SeekOn + AlternativelySeekOn(多键匹配)
  • 自动 Detach 实体避免 ChangeTracker 内存泄漏

9. 文本文件解析

FlatFileDefinition 提供了强类型的平面文件映射:

  • 表达式树定义列映射:i.ToColumn("email"), i.ToDateColumn("date", "yyyy-MM-dd"), i.ToNumberColumn<int?>("amount", ".")
  • 支持分隔符文件(IsColumnSeparated(',')) 和固定宽度文件(HasFixedColumnWidth
  • 支持编码、CultureInfo、行预处理、值预处理

10. 设计亮点

  1. 完全响应式: 自研 Push-based Reactive 框架,数据按需推送,天然支持并行多流
  2. Fluent API: 所有操作链式调用,每个节点有名称用于追踪
  3. 内存高效: 流式处理不缓存全量数据,StreamWithResource 确保流资源正确释放
  4. 可观测性: 内置追踪系统(TraceEvent → TraceStream),支持自定义追踪处理
  5. 可扩展: 新增连接器只需实现 Provider/Processor 接口,5 分钟即可完成
  6. Correlation: 独有的跨流关联机制,优雅解决数据规范化问题
  7. 内存泄漏修复: 代码中有大量注释标注了内存泄漏修复点(CancellationToken 注册释放、Entity DetachSubscription 清理等)

11. 不足

  1. 文档不完整: README.md 中明确提到文档严重不足
  2. 测试覆盖低: 测试项目主要是文档示例测试,缺乏核心引擎的单元测试
  3. 部分代码有 TODO: 如 IStream.GetMatchingStream 返回 object 的类型安全问题
  4. 自研 Reactive: 没有使用成熟的 Rx.NET,可能在边界场景有未覆盖的 bug
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChaITSimpleLove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值