Pyspark加载海量数据到Oracle数据库的方案选型咨询
Pyspark加载8000万行数据到Oracle方案对比
结论
方案二(API抽取数据直接入内存通过Pyspark写Oracle)综合效率远优于方案一,性能提升幅度可达到100%以上。
两个方案的性能差异分析
方案一:读CSV后导入Oracle
- 仅有的优势是数据落地后可断点重试,无需重新调用REST API拉取全量数据。
- 性能短板非常明显:凭空增加了全量CSV磁盘写入、全量CSV磁盘读取、CSV文本格式解析三个大开销步骤,8000万行数据仅这三步就要额外消耗半小时左右的时间。就算开启Pyspark多并行度读CSV,最高也只能比sql loader快30%左右,达不到质的提升。
方案二:API数据暂存内存直接写Oracle
- 省掉了CSV读写、解析的全部额外开销,API拉取的结构化数据直接转成Spark DataFrame内部二进制格式存储,内存不足时溢出的临时文件也是高压缩的列式存储,比CSV体积小5倍以上,读写速度快10倍以上。
- 支持流水线并行处理:拉取到一批API数据就可以同步写入Oracle,无需等全量数据抽取完成再启动加载流程,进一步压缩总耗时。
Pyspark写Oracle核心优化配置(必做,否则性能提升不明显)
- 开启批量写入:调用
spark.write.jdbc时必须添加两个参数:batchsize=10000(根据单行数据大小可调整到1万10万区间)、`rewriteBatchedStatements=true`,开启后写入速度可提升35倍,避免单行插入的网络开销。 - 并行度匹配:调整Spark分区数为Oracle节点CPU核心数的2~4倍,不要超过Oracle数据库允许的最大连接数,避免压垮数据库。
- 全量导入优化:如果是导入空表,提前禁用表的索引、非空约束,导入完成后再重建,可再节省30%以上的写入时间。
折中方案(兼顾性能和可靠性)
如果担心REST API拉取中途失败需要重复调用,可将拉取到的数据落地为Parquet格式而非CSV,Parquet是压缩列式存储,体积是同数据量CSV的1/5~1/3,读写解析速度是CSV的10倍以上,兼顾断点重试能力和性能。
附CSV数据样例

内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

