主页 > 新闻资讯 > 大数据学习:HBase Connection的使用

大数据学习:HBase Connection的使用

作者:张老师 浏览次数: 2021-07-05 16:51
Hbase作为Hadoop原生数据库,在数据存储上与底层的HDFS是互相配合的重要组件。Hbase也提供相应的API,来帮助开发者能够更便捷地完成开发任务。今天的大数据学习分享,我们就主要来讲讲Hbase Connection的使用。

大数据学习:HBase Connection的使用

对于很多初次接触HBase的伙伴,在使用其客户端API来构建Connection连接对象的时候,有可能会陷入以下几个误区。

类比druid等mysql数据库连接池,自己封装一个Connection对象的资源池,每次使用都从池中取出一个Connection对象;

在多线程的工作环境中,每个线程都会创建一个Connection对象,造成Connection对象被频繁创建,快速消耗;

每次访问HBase的时候临时创建一个Connection对象,使用完之后调用close方法,关闭连接;

一、HBase Connection的正确使用姿势

参考HBase技术社区文章连接HBase的正确姿势中对Connection的源码分析,们可知:

HBase客户端中的Connection对象并不是简单对应一个socket连接。

HBase客户端的Connection包含了对Zookeeper、HBase Master、HBase RegionServer三种socket连接的封装。因此,Connection对象每次被创建出来的开销是很大的,使用完毕之后断开,会带来严重的性能损耗。

在HBase中Connection类已经实现了对连接的管理功能,所以们不需要自己在Connection之上再做额外的管理。另外,Connection是线程安全的,而Table和Admin则不是线程安全的,因此正确的做法是,在一个JVM进程中共用一个Connection对象,而在不同的线程中使用单独的Table和Admin对象。

二、单例模式维护HBase的Connection

在普通的Java程序中,如果没有并发场景的存在,们可以简单地使用下面这种方式来创建Connection的对象。

///所有进程共用一个connection对象
connection=ConnectionFactory.createConnection(config);
...
///每个线程使用单独的table对象
Table table=connection.getTable(TableName.valueOf("test"));
try{
...
}finally{
table.close();
}

然而,在多线程中的场景中,们又该如何来管理们的连接对象呢?聪明的你,一定会首先想到单例模式。

单例模式是一种简单的设计模式,它的优点是只生成一个实例,可以保证在同一个JVM进程中,对象只存在一个。所以能节约系统资源,减少性能开销,同时能够严格控制用户对它的访问。

关于单例模式的实现,常见的有饿汉式、懒汉式、双重检测锁式、静态内部类式和枚举单例。

上述实现方式各有优劣,但使用时需要注意,线程是否安全和平衡效率。关于其具体的实现细节,网上有很多文章可供参考,这里不做详细罗列,只举例双重检测锁式的单例实现方式,在管理HBase客户端连接对象中的应用。具体实现代码:

public class SingleConnectionFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(SingleConnectionFactory.class);
   
   private volatile static Connection connection;
   
   private SingleConnectionFactory() {}
   
   public static Connection getConnection(Configuration configuration) {
        if (connection == null) {
            synchronized (SingleConnectionFactory.class) {
                if (connection == null) {
                    try {
                        connection = ConnectionFactory.createConnection(configuration);
                        LOGGER.info("the connection of HBase is created successfully.");
                    } catch (IOException e) {
                        LOGGER.error("the connection of HBase is created failed.");
                        throw new HBaseSdkConnectionException(e);
                    }
                }
            }
        }
        return connection;
    }
}

上述单例Connection对象创建工厂类,在多线程的测试环境中亦可保证同一个JVM进程中,只有一个Connection对象被创建出来,观察ZK客户端连接数监控,几乎无波动。

三、多例模式中维护HBase的Connection

在cuckoo-cloud(布谷鸟,微服务版大数据组件统一管理平台,目前已集成hbase-manager和kafka-manager的功能)中迁移们的hbase-manager应用时,遇到这样一个问题。

cuckoo-cloud平台上会管理们的多个HBase集群,这些HBase集群的连接信息被保存进数据库中,可以进行动态维护。在设计HBase的连接管理功能时,如果采用单例模式,那么,无论切换任意一个集群,始终操作的是最开始被初始化连接的集群;如果放弃单例模式,Connection对象又会被滥用。

所以,需要一个容器,它能保存不同集群的连接对象,且每个对象在一个JVM进程中只保留一个。

网上贴出来的多例实现代码都是基于创建多个固定对象的,但需要的是动态创建对象,最终的实现效果如下:

public class MultipleConnectionFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(MultipleConnectionFactory.class);
    private volatile static Map<String, Connection> connectionMap;
    private MultipleConnectionFactory() {
    }
    public static Connection getConnection(Configuration configuration) {
        String cluster = configuration.get(HConstants.ZOOKEEPER_QUORUM);
        if (connectionMap == null || !connectionMap.containsKey(cluster)) {
            synchronized (MultipleConnectionFactory.class) {
                if (connectionMap == null || !connectionMap.containsKey(cluster)) {
                    try {
                        if (connectionMap == null) {
                            connectionMap = new HashMap<>(2);
                        }
                        if (!connectionMap.containsKey(cluster)) {
                            Connection connection = ConnectionFactory.createConnection(configuration);
                            LOGGER.info("the connection of HBase cluster [{}] is created successfully.", cluster);
                            connectionMap.put(cluster, connection);
                        }
                    } catch (IOException e) {
                        LOGGER.error("the connection of HBase is created failed.");
                        throw new HBaseSdkConnectionException(e);
                    }
                }
            }
        }
        return connectionMap.get(cluster);
    }
}

类比双重检测锁式的单例实现方式,在此使用ZK的连接地址为key,来保证每一个集群的连接对象在同一个JVM进程中唯一存在。

关于大数据学习,HBase Connection的使用,以上就为大家做了基本的介绍了。Hbase通过API进行开发任务的时候,Connection的使用还是要根据具体的需求来确定。成都加米谷大数据,专业大数据培训机构,大数据开发、数据分析与挖掘,零基础班本月正在招生中,课程大纲及试学视频,可联系客服获取!
热点排行
推荐文章
立即申请>>