使用 neo4j-jdbc 打开连接是瓶颈
Using neo4j-jdbc open-connection is bottleneck
我正在使用 neo4-jdbc 和池库 BasicDataSource。
我遇到了巨大的延迟问题,所以我们分析了应用程序,发现打开连接是原因。我不明白为什么我们使用池打开连接需要这么长时间。这是我们个人资料的屏幕截图:
这是 Neo4jDatasourceRemote 的样子:
package com.comp.wm.common.repo;
import com.comp.wm.common.utils.Constants;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.SQLException;
private final Logger logger = Logger.getLogger(Neo4jDataSourceRemote.class);
private BasicDataSource ds;
@Value("${neo4j.host:localhost}")
private String NEO4J_HOST;
@Value("${neo4j.port:7474}")
private String NEO4J_PORT;
@Value("${neo4j.username:nouser}")
private String NEO4J_USERNAME;
@Value("${neo4j.password:nopass}")
private String NEO4J_PASSWORD;
@Value("${neo4j.pool.size:200}")
private int NEO4J_POOL_SIZE;
private String GetUrl() {
return String.format(Constants.NEO4J_JDBC_CONNECTIVITY_STRING, NEO4J_HOST, NEO4J_PORT);
}
@PostConstruct
public void init(){
ds = new BasicDataSource();
ds.setInitialSize(300);
ds.setDriverClassName("org.neo4j.jdbc.Driver");
ds.setUrl(GetUrl());
ds.setUsername(NEO4J_USERNAME);
ds.setPassword(NEO4J_PASSWORD);
}
@Override
public Connection openConnection() throws SQLException {
return this.ds.getConnection();
}
@Override
public void closeConnection(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (SQLException ex) {
logger.info("error closing connection", ex);
}
}
}
这是我如何针对图表执行查询的示例:
public List<NearbyItem> executeQuery(..) {
conn = neo4jDataSource.openConnection();
String getUsersStatement = "some query..";
try (PreparedStatement ps = conn.prepareStatement(getUsersStatement)) {
..
ResultSet rs = ps.executeQuery();
while (rs.next()) {
...
}
} catch (Exception e) {
throw new RuntimeException("Error returning userId=" + userIdInput, e);
} finally {
neo4jDataSource.closeConnection(conn);
}
return distItemDatas;
}
有什么想法吗?
根据以上评论,我将添加此作为回复。
默认情况下,Neo4j 以 10 个线程为核心运行在 http 接口中。您可以在 neo4j-server.properties
中调整线程总数
org.neo4j.server.webserver.maxthreads=200
然而,线程越多,上下文切换和锁争用的问题就越多。如果您增加线程数,我预计吞吐量不会大幅增加,您只需转移必须等待的点。从初始化(openCONnection)到处理查询。
我正在使用 neo4-jdbc 和池库 BasicDataSource。
我遇到了巨大的延迟问题,所以我们分析了应用程序,发现打开连接是原因。我不明白为什么我们使用池打开连接需要这么长时间。这是我们个人资料的屏幕截图:
这是 Neo4jDatasourceRemote 的样子:
package com.comp.wm.common.repo;
import com.comp.wm.common.utils.Constants;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.SQLException;
private final Logger logger = Logger.getLogger(Neo4jDataSourceRemote.class);
private BasicDataSource ds;
@Value("${neo4j.host:localhost}")
private String NEO4J_HOST;
@Value("${neo4j.port:7474}")
private String NEO4J_PORT;
@Value("${neo4j.username:nouser}")
private String NEO4J_USERNAME;
@Value("${neo4j.password:nopass}")
private String NEO4J_PASSWORD;
@Value("${neo4j.pool.size:200}")
private int NEO4J_POOL_SIZE;
private String GetUrl() {
return String.format(Constants.NEO4J_JDBC_CONNECTIVITY_STRING, NEO4J_HOST, NEO4J_PORT);
}
@PostConstruct
public void init(){
ds = new BasicDataSource();
ds.setInitialSize(300);
ds.setDriverClassName("org.neo4j.jdbc.Driver");
ds.setUrl(GetUrl());
ds.setUsername(NEO4J_USERNAME);
ds.setPassword(NEO4J_PASSWORD);
}
@Override
public Connection openConnection() throws SQLException {
return this.ds.getConnection();
}
@Override
public void closeConnection(Connection conn) {
try {
if (conn != null)
conn.close();
} catch (SQLException ex) {
logger.info("error closing connection", ex);
}
}
}
这是我如何针对图表执行查询的示例:
public List<NearbyItem> executeQuery(..) {
conn = neo4jDataSource.openConnection();
String getUsersStatement = "some query..";
try (PreparedStatement ps = conn.prepareStatement(getUsersStatement)) {
..
ResultSet rs = ps.executeQuery();
while (rs.next()) {
...
}
} catch (Exception e) {
throw new RuntimeException("Error returning userId=" + userIdInput, e);
} finally {
neo4jDataSource.closeConnection(conn);
}
return distItemDatas;
}
有什么想法吗?
根据以上评论,我将添加此作为回复。
默认情况下,Neo4j 以 10 个线程为核心运行在 http 接口中。您可以在 neo4j-server.properties
org.neo4j.server.webserver.maxthreads=200
然而,线程越多,上下文切换和锁争用的问题就越多。如果您增加线程数,我预计吞吐量不会大幅增加,您只需转移必须等待的点。从初始化(openCONnection)到处理查询。