我们使用Apache Spark每2小时执行一次ETL。
有时Spark在执行读/写操作时会给数据库带来很大压力。
对于Spark Streaming,我可以在kafka上看到backpressure
配置。
有没有办法在批处理中处理这个问题?
背压实际上只是一个用来设置最大接收速率的花哨词。所以实际上它并不像你想象的那样起作用。
这里应该做的实际上是在阅读端。
现在,在经典JDBC使用中,JDBC连接器具有PreparedStatement
s的fetchSize
属性。因此,基本上,您可以考虑根据以下答案中的内容来配置fetchSize:
-
Spark JDBC fetchsize选项
-
Statement.setFetchSize(nSize(方法在SQLServer JDBC驱动程序中真正做了什么?
很遗憾,这可能无法解决RDBMS
的所有性能问题。
您必须知道的是,与在单个工作线程上运行的基本jdbc读取器相比,当使用整数列或使用谓词序列对数据进行分区时,以分布式模式加载数据会带来一些问题。在您的情况下,大量的并发读取可以很容易地限制数据库。
为了解决这个问题,我建议如下:
- 如果可用,请考虑通过JDBC使用专门的数据源连接
- 考虑使用专门或通用的批量导入/导出工具,如Postgres COPY或Apache Sqoop
- 一定要了解不同JDBC数据源的性能影响变体,尤其是在使用生产数据库时
- 考虑为Spark作业使用单独的复制副本
如果您想了解更多关于使用JDBC源读取数据的信息,我建议您阅读以下内容:
- Spark SQL和数据集API
免责声明: 我是该回购的合著者。