Java 正确的方法是什么;池;Phoenix查询服务器连接

Java 正确的方法是什么;池;Phoenix查询服务器连接,java,azure,phoenix,Java,Azure,Phoenix,我们正在使用Azure和Phoenix写入HBase集群。有两个驱动程序:一个大驱动程序和一个瘦客户端。瘦客户机使用HTTP上的Json与数据库交互 当我们每次保存创建一个新连接时,每次保存大约150毫秒 this.conn = DriverManager.getConnection("jdbc:phoenix:thin:url=http://1.1.1.1"); 当我们重新使用连接时,每次保存只需70毫秒:这是一个显著的加速。文档有点含糊不清,在胖客户机和think客户机之间转换 那么,汇集

我们正在使用Azure和Phoenix写入HBase集群。有两个驱动程序:一个大驱动程序和一个瘦客户端。瘦客户机使用HTTP上的Json与数据库交互

当我们每次保存创建一个新连接时,每次保存大约150毫秒

this.conn = DriverManager.getConnection("jdbc:phoenix:thin:url=http://1.1.1.1");
当我们重新使用连接时,每次保存只需70毫秒:这是一个显著的加速。文档有点含糊不清,在胖客户机和think客户机之间转换

那么,汇集瘦客户机连接的最佳实践是什么

重要的变化

我们的连接开始出现一些问题,所以我想回到我们的代码并做一些更改。我设置了一些计时器,发现上面的代码在0毫秒内工作。我不确定上面我做错了什么

因此,正确的方法池凤凰是不池凤凰。有几个帖子从开发团队那里证实了这一点

拥有庞大的SQL Oracle/DB2/SqlServer背景可能是我的失败。使用Redis或Phoenix或任何新的无sql数据库都与sql有很大不同。我的建议是“阅读你正在使用的产品的说明”,并按照他们的指示去做

根据,没有必要将Phoenix JDBC连接集中在一起

Phoenix的连接对象与大多数其他JDBC连接不同,这是由于底层的HBase连接。Phoenix连接对象被设计为一个创建成本低廉的薄对象。如果重用Phoenix连接,则前一个用户可能不会始终将基础HBase连接保持在正常状态。最好创建新的Phoenix连接,以确保避免任何潜在问题

只需创建一个委托连接,在从池中检索时实例化一个新的Phoenix连接,然后在将其返回到池中时关闭连接,即可实现Phoenix的池化(请参阅Phoenix-2388)。

我认为上面粗体的内容是汇集瘦客户机连接的最佳实践

您可以尝试在客户端设置下面的配置以优化性能,请参阅。


更新:下面是我为Phoenix连接池设计的简单工具

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class DataSource {

    private String driverClass;
    private String jdbcUrl;
    private String user;
    private String password;
    private int min; // The number of connections of initial pool
    private int max;
    private int used; // The number of connections of polled and not released from poll
    private Queue<Connection> pool = null;

    public DataSource(String driverClass, String jdbcUrl, String user, String password, int min, int max) {
        this.driverClass = driverClass;
        this.jdbcUrl = jdbcUrl;
        this.user = user;
        this.password = password;
        this.min = min;
        this.max = max;
        this.used = 0;
        this.pool = new ConcurrentLinkedQueue<Connection>();
        init();
    }

    private void init() {
        try {
            Class.forName(driverClass);
            for (int i = 0; i < min; i++) {
                Connection conn = DriverManager.getConnection(jdbcUrl, user, password);
                pool.add(conn);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection() {
        Connection conn  = null;
        if (pool.size() > 0) {
            conn = pool.poll();
            Thread connGen = new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        Connection conn = DriverManager.getConnection(jdbcUrl, user, password);
                        pool.add(conn);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            });
            connGen.start();
            used ++;
        } else if(used < max) {
            try {
                conn = DriverManager.getConnection(jdbcUrl, user, password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return conn;
    }

    public void releaseConnection(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
                used--;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.SQLException;
导入java.util.Queue;
导入java.util.concurrent.ConcurrentLinkedQueue;
公共类数据源{
专用字符串驱动器类;
私有字符串jdbcUrl;
私有字符串用户;
私有字符串密码;
private int min;//初始池的连接数
私人int max;
private int used;//轮询和未从轮询中释放的连接数
专用队列池=null;
公共数据源(字符串驱动程序类、字符串jdbcUrl、字符串用户、字符串密码、int-min、int-max){
this.driverClass=driverClass;
this.jdbcUrl=jdbcUrl;
this.user=用户;
this.password=密码;
this.min=min;
this.max=max;
此值为0;
this.pool=新的ConcurrentLinkedQueue();
init();
}
私有void init(){
试一试{
类forName(driverClass);
对于(int i=0;i0){
conn=pool.poll();
Thread connGen=新线程(new Runnable()){
@凌驾
公开募捐{
试一试{
Connection conn=DriverManager.getConnection(jdbcUrl、用户、密码);
池。添加(康涅狄格州);
}捕获(SQLE异常){
e、 printStackTrace();
}
}
});
connGen.start();
使用++;
}否则,如果(使用<最大值){
试一试{
conn=DriverManager.getConnection(jdbcUrl、用户、密码);
}捕获(SQLE异常){
e、 printStackTrace();
}
}
返回连接;
}
公共无效释放连接(连接连接){
如果(conn!=null){
试一试{
康涅狄格州关闭();
使用--;
}捕获(SQLE异常){
e、 printStackTrace();
}
}
}
}

是的,我看到了,但是创建“新凤凰连接”需要很长时间。通过重复使用连接,我们可以节省一半的时间。知道什么是“代理连接”吗?我想要一些代码…@markthegrea我只是为phoenix实现了一个池。没有测试,只是作为参考。