Spark JDBC连接复用:多次Impala查询执行的疑问
关于Impala JDBC连接复用与Spark环境下的疑问解答
先帮你梳理下场景:你现在是在Driver端用原生JDBC创建了一个Impala连接,然后打算把con.createStatement()及后续查询逻辑放进循环执行5000次,针对这个场景的疑问,我来逐一解答:
问题1:是否会产生5000次连接开销?连接能否复用?Spark会自动关闭连接吗?
- 连接开销与复用:如果你的
con(连接对象)是在循环外面初始化的,那循环里调用con.createStatement()只会创建新的Statement对象,连接本身是复用的,不会产生5000次连接建立的开销——整个循环只会用最开始创建的那一个Impala连接,这点完全不用担心。 - Spark的连接管理:你现在用的是原生JDBC API,不是Spark官方提供的JDBC DataSource(比如
sqlContext.read.format("jdbc")那种),所以Spark不会帮你自动管理这个连接的生命周期。也就是说,如果你不手动调用con.close()、stmt.close()、rs.close(),这些资源不会被自动释放,时间长了容易造成连接泄漏,占满Impala的连接配额,导致后续无法建立新连接。所以一定要在循环结束后(或者每次查询完成后)手动关闭相关资源。 - 对比map与mapPartitions的开销:顺便提一句,如果是在Spark的
map算子里创建连接,那每条数据都会触发一次连接创建,开销极大;而mapPartitions是每个Partition创建一次连接,能大幅降低开销。不过你现在的场景是在Driver端循环执行,不是在Executor的算子里,所以核心还是要保证连接在循环外初始化,循环内复用。
问题2:使用Hive Context是否无需每次重新建立连接?Parquet/ORC表是否支持高效复用?
- Hive Context的连接管理:如果你改用Hive Context(Spark 2.x及以上推荐用SparkSession)来操作Impala,比如直接执行
spark.sql("SELECT * FROM impala.default.your_table"),Spark会自动在底层处理连接的建立、复用和销毁,不需要你手动写JDBC连接代码。Spark会根据配置的连接池参数来复用连接,比原生JDBC的手动管理高效且安全得多。 - Parquet/ORC的高效方式:如果你的业务场景允许,把Impala的数据预写成Parquet或ORC格式的表(这两种都是高效的列式存储格式),然后让Spark直接读取HDFS上的这些文件,那根本不需要通过JDBC连接Impala了——Spark直接读文件的性能远高于JDBC查询,而且完全不存在连接复用的问题。如果需要写数据到Impala,写完Parquet/ORC后执行
REFRESH TABLE刷新Impala元数据即可,这种方式比反复JDBC查询要高效得多。
内容的提问来源于stack exchange,提问作者Ged




