HBase之 java 客户端创建 namespace 和 table 操作(5)

一  前期准备篇

在java端创建一个Maven项目 ,将Hbase的jar包和依赖等添加到 pom.xml 文件中,添加内容如下 ;

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-auth</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-client</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>2.2.5</version>
        </dependency>
        <!-- 使用mr程序操作hbase 数据的导入 -->
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-mapreduce</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>
        <!-- phoenix 凤凰 用来整合Hbase的工具 -->
        <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>5.0.0-HBase-2.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <!-- bind to the packaging phase -->
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

可能遇到的异常及解决办法 : 导入/下载jar包依赖的时候可能会出现个别不能下载成功的jar包 ,根据提示,将没有成功的jar文件删除掉,重新在 pom.xml 文件中单击右键,选择"maven"=>"reload project" ,和单击界面右上角"maven栏"=>单击左上角的刷新符号 ,然后回到pom.xml文件界面重新下载之前没有下载成功的文件 .

二  实践篇

1 Hbase的java客户端入门程序

/**
 * description : 使用java客户端操作 hbase
 * 1)zookeeper上记录着hbase集群的信息
 * 2)获取hbase的连接对象
 * 3)建表 建namespace 修改表结构.. 对数据的操作.. get put delete
 * 4) admin  管理者 建namespace  建表  表结构  删除表/名称空间  工具  合并切割移动   刷写
 * 5) table  表对象  对数据操作  put delete  get  scan
 **/
public class Test {
    public static void main(String[] args) throws IOException {
        // 获取 zookeeper 的连接对象
        // 1 创建配置对象
        Configuration conf = HBaseConfiguration.create();

        // 1.1 设置 zookeeper的位置  找到hbase
        conf.set("hbase.zookeeper.quorum","doit03:2181,doit04:2181,doit05:2181");

        // 2 获取连接对象
        Connection connection = ConnectionFactory.createConnection(conf);

        // 3 获取操作对象
        Admin admin = connection.getAdmin();

        // 3.1 操作hbase   得到默认namespace的名字和其下的表的名字
        TableName[] tableNames = admin.listTableNames();

        // 遍历,将所有tablename取出来
        for (TableName tableName : tableNames) {

            // 获取表的名字
            String tbname = tableName.getNameAsString();
            
            // 获取 名字空间
            String namespace = tableName.getNamespaceAsString();
            System.out.println(namespace+"---"+tbname);
        }

        // 关闭连接
        admin.close();
        connection.close();
    }
}

2  为了减少重复编写代码 ,将"获取配置对象 / 设置 zookeeper 位置 / 获取连接对象"的流程封装成方法 ,每次需要用到的时候直接调用就可以了

/**
 *
 * @Description : 将 获取配置对象 /设置zookeeper位置 /获取连接对象 步骤封装起来
 *
 **/

public class HabaseUtil {
    public static Connection getHbaseConnection() throws IOException {
        
        // 获取 hbase 配置对象
        Configuration conf = HBaseConfiguration.create();

        // 设置 zookeeper 位置
        conf.set("hbase.zookeeper.quorum","linux03:2181,linux04:2181,linux05:2181");

        //创建连接对象
        Connection con = ConnectionFactory.createConnection(conf);
        return con;
    }
}

3  操作 namespace( 创建 / 删除 / 设置属性 / 更新属性)

/**
 *
 * @Description : 操作名字空间
 **/
public class NewSpaceClient {
    public static void main(String[] args) throws IOException {
        
        // 调用创建名字空间的方法
        createNameSpace();
............................................................

        // 获取hbase连接对象
        Connection connection = Util.getConnection();
        // 获取hbase的namespace的操作对象
        Admin admin = connection.getAdmin();

        // 调用更改名字空间属性的方法
        modifyNameSpace(admin);

        // 关闭连接
        admin.close();
        connection.close();
    }

    /**
     * 修改 namespace 的属性
     * @param admin
     */
    public static void modifyNameSpace(Admin admin) throws IOException {
        // 获取更改'hbase04'的属性的构造器对象
        NamespaceDescriptor.Builder hbase04 = NamespaceDescriptor.create("hbase04");
        // 调用构造器里面封装的方法添加一个新的属性
        hbase04.addConfiguration("day","2020-08-28");
        // 调用构造器里面封装的方法移除一个属性
        hbase04.removeConfiguration("ctime");
        // 构造器对象调用构建方法 ,返回一个名字空间构建对象
        NamespaceDescriptor namespaceDescriptor = hbase04.build();
        // 操作对象调用修改方法 ,并将修改好的构建对象放到修改名字空间方法里面
        admin.modifyNamespace(namespaceDescriptor);
    }

    /**
     * 创建名称空间/namespace
     */
    public static void createNameSpace(){
        try {
            // 获取连接对象
            Connection conn = HbaseUtil.getHbaseConnection();
            // 获取操作对象
            Admin admin = conn.getAdmin();

            //获取namespace对象
            NamespaceDescriptor hbase = admin.getNamespaceDescriptor("hbase04");
            //判断这个namespace是否存在
            if(hbase != null){
                //如果这个namespace存在 ,遍历namespace,将里面的table都取出来
                TableName[] hbase01s = admin.listTableNamesByNamespace("hbase04");
                for (TableName tableName : hbase01s) {
                    // 禁用表(禁用表后,才能对表进行删除/更新等操作)
                    admin.disableTable(tableName);
                    // 删除表
                    admin.deleteTable(tableName);
                }
                // 删除 namespace
                admin.deleteNamespace("hbase04");
            }
            // 获取名称空间的构建器对象
            NamespaceDescriptor.Builder hbase1 = NamespaceDescriptor.create("hbase04");
            //设置namespace的属性信息
            Map<String, String> map = new HashMap<>();
            map.put("author","cch");
            map.put("ctime",System.currentTimeMillis()+"");
            hbase1.addConfiguration(map);
            // 构造器对象调用构建方法,返回/获取构建对象
            NamespaceDescriptor build = hbase1.build();
            //创建名称空间
            admin.createNamespace(build);

            //关闭连接
            admin.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4  操作table(创建表/更新属性/删除表)

/**
 * @Description : 操作table
 **/
public class TableClient {
    public static void main(String[] args) throws IOException {
 
      createTable();
      tableSplit(); 
}


    // 创建表的方法
    public static void createTable(){
        try{
        //获得链接对象
        Connection connection = HbaseUtil.getHbaseConnection();
        //获取操作对象
        Admin admin = connection.getAdmin();
        // 获取创建表的构造器
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf("ns_order:tb_user"));
            // 创建一个list集合,用来装 列族
            List<ColumnFamilyDescriptor> list = new ArrayList<>();
            // 需要添加列族 ,需要获取列族构造器对象
            // 获取列族1构造器
            ColumnFamilyDescriptorBuilder familyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder("cf1".getBytes());
            // 列族构造器对象设置属性
            familyDescriptorBuilder.setTimeToLive(240);
            familyDescriptorBuilder.setMaxVersions(3);
            // 设置属性完毕后获取列族1构建对象
            ColumnFamilyDescriptor family1Build = familyDescriptorBuilder.build();

            //  // 获取创建列族2的构造器
            ColumnFamilyDescriptorBuilder familyDescriptorBuilder1 = ColumnFamilyDescriptorBuilder.newBuilder("cf2".getBytes());
            // 列族2 设置属性
            familyDescriptorBuilder1.setMaxVersions(3);
            familyDescriptorBuilder1.setTimeToLive(240);
            // 列族2 获取构建对象
            ColumnFamilyDescriptor family2Build = familyDescriptorBuilder1.build();
            // 将设置完成的列族并且获取了构建对象的列族放到集合里面
            list.add(family1Build);
            list.add(family2Build);
            // 将装有列族的集合放到设置列族方法里面
            builder.setColumnFamilies(list);

            // 表构造器对象获取构建对象
            TableDescriptor tablebuild = builder.build();
            admin.createTable(tablebuild);

            }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建一个预分region的表
     * 为了避免插入热点问题 ,将key进行切割split
     * @param admin
     */
    public static void tableSplit(){
        try {
            // 获取连接对象
            Connection connection = HbaseUtil.getHbaseConnection();
            // 获取操作对象
            Admin admin = connection.getAdmin();
            // 获取表构造器对象
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf("tb_web"));
            // 获取表列族构造器对象
            ColumnFamilyDescriptorBuilder familyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes());
            // 获取表列族构建对象
            familyDescriptorBuilder.setTimeToLive(60*60*24*7);
            familyDescriptorBuilder.setMaxVersions(3);
            ColumnFamilyDescriptor familyBuild = familyDescriptorBuilder.build();

            // 表构造器需要将列族信息设置
            builder.setColumnFamily(familyBuild);
            // 获取表构建对象
            TableDescriptor build = builder.build();
            // 获取切割点 ,按照字典顺序,指定三个切割点,切分成4个区
            byte[][] keys = new byte[][]{"e".getBytes(),"g".getBytes(),"h".getBytes()};

            // 创建表
            admin.createTable(build,keys);

             // 关闭连接
            admin.close();
            connection.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // 封装判断表是否存在的方法
    public static void isTableExists(Admin admin) throws IOException {
        // 指定 namespace 下是否有指定的表
        admin.tableExists(TableName.valueOf("hbase01:tb_user"));
        // 默认的 namespace 下是否有表
        admin.tableExists(TableName.valueOf("tb_user"));
    }
}

为了避免热点插入问题 ,创建预分region的表 ,将keys进行指定切割点切分 .

按照字典的顺序 / ASCLL码表..指定切割点进行 regions 的切割 ,上述是按照指定的 'e' 'g' 'h' 三个指定的字母进行切分 ,一共切分成四个区 ,得到四个 region .

 list_regions 'tb_web'              // 查看创建的指定的表的 regions 个数 

// 结果很明显 ,创建的表 'tb_web' 被切分为四个区 ,分别存储在 hbase 集群中的不同节点上

 linux03,16020,1598542043871 |  tb_web,,1598740852699.0a8f4f923e2af28a23dc117845219eac. | | e | 0 | 0 |0.0 |
 linux05,16020,1598542042061 | tb_web,e,1598740852699.f3e626cf00fc5f95b23ce94ebc74da8c. | e | g | 0 | 0 | 0.0 |
 linux04,16020,1598542041507 | tb_web,g,1598740852699.184e42a850fda74b771d9890a3f5dab0. | g | h | 0 | 0 | 0.0 |
 linux03,16020,1598542043871 | tb_web,h,1598740852699.009c16914ad16579c906c5ff4f11b00b. | h |  | 0 | 0 | 0.0 |

构造器 builder 注释 : 

当进行 createTable / createNamespace / modifiyNamespace 等等操作时,需要使用到构造器 .

构造器被封装 ,里面有各种方法(有各种逻辑代码/可以实现各种功能), 通过new一个构造器对象来调用这些方法, 然后对namespace / table / 列族(columnfamily)等进行一系列操作 ,最后构造器对象调用构建方法 ,返回描述构建对象 ,然后之前获取的操作对象adnin(对namespace /table属性,结构进行操作的对象)调用createTable() / createNamespace() / modifiyNamespace()等方法,并将描述构建对象放进去 .

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值