从RDBMS到Snowflake的迁移实践
Source: InfoQ - Big Data
问题陈述:
在仅有8GB内存的一台Databricks Worker上,将一张超过1亿条记录的Oracle表迁移到Snowflake,需要一种高度优化、具备内存感知的方案,以避免失败并确保在严格的2小时时限内稳定执行。传统方法存在发生内存不足错误和资源利用低效的风险,因此需要一种策略,在无需额外增加集群资源的前提下,优先实现受控的数据流式处理、尽可能小的内存占用以及高效的写入操作。(使用Databricks、PyArrow和Native Spark)
❌ 常见错误:
使用单线程的 Pandas to_sql() = 必然触及内存上限并失败。未调优的直接JDBC读取 = 缓慢且不稳定。
✅ 优化策略:
1.来源:Oracle并行读取
调优 JDBC 的fetchsize 与 defaultRowPrefetch.计算并限制分区数以获得最佳并行度。使用谓词下推以高效进行数据切分。
2.暂存:DBFS上的Snappy Parquet
重新分区以避免小文件。写入Snappy Parquet以发挥列式效率。
* 避免小文件—合理使用coalesce() 或repartition()
* Parquet块大小128MB
创建稳定的分布式检查点。
3.处理:用PyArrow分块,而非Pandas
按*row groups**迭代,而不是一次处理整个数据集。
使用pyarrow.parquet.ParquetFile() 打开文件通过.read_row_group() or .read_raw_group()读取每个分组
*至关重要的是跳过Pandas 转换**,以避免driver 端OOM.
*直接转换为Spark DataFrame,以进行分布式处理。
4.加载:使用Native Spark Writer 至Snowflake
使用spark-snowflake连接器进行并行、高吞吐写入。利用 Snowflake的Apache Arrow集成以提升速度。
5.稳定性:显式内存清理
在每个分块处理后删除DataFrame引用。
*删除DataFrame对象
*显式丢弃所有列以释放内存
手动触发垃圾回收 (gc.collect()).防止长时作业中的内存泄漏。结果:在单个8GB worker节点上对1亿+记录实现稳定执行,并在可预测的2小时窗口内完成(Approx)。
声明:本演示中所表达的观点和意见仅代表作者个人,并不必然反映Novartis或其任何附属机构或管理人员的官方政策或立场。
原文地址: