hbase shell命令与hbase API的调用

HBase

HBase shell

  1. Region信息观察

    create 'namespace:tb','cf'
    

    查看命名空间里的所有表

    list_namespace_tables 'n1'
    

    查看region中的某列族数据

    hbase hfile -p -f //hbase/data/default/tbl_user/...
    

    刷新数据:flush 'tb'

    合并数据:major_compact 'tb'

    1. 查看表的所有region

      list_regions '表名'
      
    2. 强制将表切分出来一个region

      split '表名','行键'
      
    3. 查看某一行在哪个region中

      locate_region '表名','行键'
      
  2. 预分region解决热点问题

    在默认的拆分策略中 ,region的大小达到一定的阈值以后才会进行拆分,并且拆分的region在同一个regionserver中 ,只有达到负载均衡的时机时才会进行region重分配!并且开始如果有大量的数据进行插入操作,那么并发就会集中在单个RS中, 形成热点问题,所以如果有并发插入的时候尽量避免热点问题 ,应当预划分 Region的rowkeyRange范围 ,在建表的时候就指定预region范围

    实现思路:

    • 分析数据分布:首先,需要分析和预测数据的分布模式。了解数据的键值范围和写入频率是关键。
    • 预定义分区点:根据分析结果,确定适当的分区点。这些分区点将用于初始Region的划分。
    • 创建预分区Region:在表创建时使用预定义的分区点,创建多个初始Region。
    • 数据导入和均衡:在数据导入过程中,确保数据按照预定义的分区点写入相应的Region,并监控Region的负载情况。
    • 动态调整:在运行过程中,动态监控数据分布和访问模式,必要时进行Region的拆分或合并。
  3. 日志查看

    -- 日志目录
    /.../hbase-版本号/logs
    
  4. scan使用

    查看所有的命名空间

    list_namespace
    

    查看某个命名空间下的所有表

    list_namespace_tables 'namespace'
    

    修改命名空间,设置一个属性

    alter_namespace 'namespace',{METHOD=>'set',author=>'yulu'}
    

    查看命名空间属性

    describe_namespace 'namespace'
    

    删除一个属性

    alter_namespace 'namespace',{METHOD=>'unset',NAME=>'author'}
    

    删除一个命名空间

    drop_namespace 'namespace'
    

    显示三行数据

    scan 'tb_name',{LIMIT=>3}
    

    从后三行查

    scan 'tb_name',{LIMIT=>3,REVERSED=>true}
    

    查看指定的列

    scan 'tb_name',{LIMTT=>3,COLUMNS=>['cf:name']}
    --简化写法
    scan 'tb_name',LIMTT=>3,COLUMNS=>['cf:name']
    

    在已有的值后面追加值

    append 'tb_name','行键','列族:列属性','追加值'
    
  5. get的使用

    简单使用,获取某一行数据

    get 'tb_name','rowkey'
    

    获取某一行的某个列族

    get 'tb_name','rowkey','cf'
    

    获取某一行的某一列(属性)

    get 'tb_name','rowkey','cf:colname'
    

    查看历史版本

    修改表可以存储多个版本

    alter 'tb_name',NAME=>'cf',VERSIONS=>N
    

    修改列族的过期时间TTL单位是秒,这个时间是与插入的时间比较,而不是现在开始6 0s

    alter 'tb_name',{NAME=>'cf2',TTL=>'10'}
    
  6. 插入时间指定时间戳

    put 'tb_name','rowkey','info:colname','value',1718356919312
    

    数据时间:数据产生那一刻的时间

    事务时间(操作时间):接收到数据并处理的那一刻时间

  7. delete删除

    delete(只能删除一个单元格,不能删除列簇)

    delete 'tb_name','rowkey','cf:colname'

    deleteall(删除不了某个列簇,但是可以删除多个单元格)

    • 删除一行,如果不指定列簇,删除的是一行中的所有列簇
    • deleteall 'tb_name','rowkey'
    • 删除单元格
    • deleteall 'tb_name','rowkey','cf:colname','cf2:colname2'
  8. 获取region的分割点,清除数据,快照

    获取region的分割点

    get_splits 'tb_name'
    

    清除表数据

    truncate 'tb_name'
    

    拍摄快照

    snapshot 'tb_name','快照名'
    

    列出所有快照

    list_table_snapshots 'tb_name'
    

    恢复快照

    disable 'tb_split'
    restore_snapshot '快照名'
    enable ' tb_name'
    

Java API

java操作数据的步骤:

  • 注册驱动
  • 创建数据连接对象
  • 创建数据操作对象
  • 进行增删改查
  • 如果时查询的话,可以对查询的结果进行分析
  • 释放资源
//先设置成员变量
private Connection conn;
private Admin admin;
// 在写方法之前要创建数据连接对象、创建数据操作对象
@Before
    public void connection() {
        try {
            //创建hbase的运行环境对象
            //旧版本的写法,已弃用
//        HBaseConfiguration conf = new HBaseConfiguration();
            //新版本创建配置文件对象的方式
            Configuration conf = HBaseConfiguration.create();

            //设置zookeeper的节点信息
            conf.set("hbase.zookeeper.quorum", "master:2181,node1:2181,node2:2181");

            //创建hbase连接对象
            conn = ConnectionFactory.createConnection(conf);

            //创建数据库操作对象
//            HBaseAdmin hBaseAdmin = new HBaseAdmin(conn);

            admin = conn.getAdmin();

            System.out.println("成功获取数据库连接对象:" + conn);
            System.out.println("成功获取数据库操作对象:" + admin);
            System.out.println("=================================================");


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
// 之后要关闭连接对象,释放资源
 @After
    public void close() {
        if (admin != null) {
            try {
                admin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

创建一张表

public void createOneTable() {
        /**
         *在hbase中,表和列族需要分开创建并设置,然后再将列族对象添加到表中
         * 1、创建一个表的描述对象
         * 将表名封装成Tablename的对象
         */

        TableName name = TableName.valueOf("students");
        // 创建表描述器
        TableDescriptorBuilder test2 = TableDescriptorBuilder.newBuilder(name);
        //创建一个表描述器对象
        try {
            ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of("info");
            //将一个列族添加到表描述器中
            test2.setColumnFamily(info);
            //判断表是否存在
            if (admin.tableExists(name)) {
                System.out.println(Bytes.toString(name.getName()) + "表已经存在!!");
                return;
            }
            admin.createTable(test2.build());
            System.out.println(Bytes.toString(test2.build().getTableName().getName()) + "表创建成功!!");
        } catch (IOException e) {
            System.out.println(Bytes.toString(test2.build().getTableName().getName()) + "表创建失败!!");
            e.printStackTrace();
        }
    }

删除一张表

public void deleteOneTable() {
        // 将表名封装成一个TableName对象
        try {
            TableName name = TableName.valueOf("students");
            //判断表是否存在
            if (!admin.tableExists(name)) {
                System.out.println(Bytes.toString(name.getName()) + "表不存在,无法删除");
                return;
            }
            // 禁用表
            admin.disableTable(name);
            // 删除表
            admin.deleteTable(name);
            System.out.println(Bytes.toString(name.getName()) + "表删除成功!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

添加一条数据

public void setOneColData() {
        try {
            // 将表名封装成一个TableName对象
            TableName name = TableName.valueOf("students");
            //判断表是否存在
            if (!admin.tableExists(name)) {
                System.out.println(Bytes.toString(name.getName()) + "表不存在");
            }
            //获取表实例对象
            Table test2 = conn.getTable(name);
            // 将一列数据封装成一个put对象,传入一个行键,需要传入的行键变成一个字节数组格式
            Put put = new Put(Bytes.toBytes("1500100001"));
            //设置列族,列名和列值
            // 设置方法1:
            /*TODO
                Put put1 = put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("xxx"));
                test2.put(put1);
             */
            //设置方式2:
            KeyValue keyValue = new KeyValue(Bytes.toBytes("1500100001"),
                    Bytes.toBytes("info"),
                    Bytes.toBytes("name"),
                    Bytes.toBytes("xxx"));
            put.add(keyValue);
            test2.put(put);
            System.out.println("一列数据已经添加完毕!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

添加多条数据

public void putMoreData() {
        ArrayList<Put> list = new ArrayList<>();
        try {
            TableName tablename = TableName.valueOf("students");
            //判断表是否存在
            if (!admin.tableExists(tablename)) {
                System.out.println(Bytes.toString(tablename.getName()) + "表不存在");
            }
            // 获取表的实例对象
            Table students = conn.getTable(tablename);
            // 创建一个字符缓冲流对象
            BufferedReader br = new BufferedReader(new FileReader("data/students.txt"));
            String line = null;
            Put put = null;
            while ((line = br.readLine()) != null) {
                //1500100001,xxx,22,女,文科六班
                String[] info = line.split(",");
                byte[] rk = Bytes.toBytes(info[0]);
                byte[] name = Bytes.toBytes(info[1]);
                put = new Put(rk);
                put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), name);
                list.add(put);

                byte[] age = Bytes.toBytes(info[2]);
                put = new Put(rk);
                put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), age);
                list.add(put);

                byte[] gender = Bytes.toBytes(info[3]);
                put = new Put(rk);
                put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("gender"), gender);
                list.add(put);

                byte[] clazz = Bytes.toBytes(info[4]);
                put = new Put(rk);
                put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("clazz"), clazz);
                list.add(put);
            }
            students.put(list);
            System.out.println(Bytes.toString(tablename.getName())+"所有数据添加完成!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

获取一条数据

public void getOneData(){
        try {
            TableName tablename = TableName.valueOf("students");
            //判断表是否存在
            if (!admin.tableExists(tablename)) {
                System.out.println(Bytes.toString(tablename.getName()) + "表不存在");
            }
            // 获取表的实例对象
            Table students = conn.getTable(tablename);
            // 创建一个Get对象
            Get get = new Get(Bytes.toBytes("1500100001"));
            Result result = students.get(get);
            /**
             *HBase中Result类常用的方法:
             * getRow()获取行键的字节数组形式
             * getValue(byte [] family, byte [] qualifier) 获取某一列的字节数组形式
             * listCells()获取所有列单元格组成的List集合
             */
            // 第一种方式:列单独取出,但是获取一列数据的前提是知道列名和列族
            // 1500100001,xxx,22,女,文科六班
            /*TODO
                    String id = Bytes.toString(result.getRow());
                    String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
                    String age = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age")));
                    String gender = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("gender")));
                    String clazz = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("clazz")));
                    System.out.println("学号:"+id+",姓名:"+name+",年龄:"+age+",性别:"+gender+",班级:"+clazz);
             */
            // 第二种方式:listCells()
            List<Cell> cells = result.listCells();
            for (Cell cell : cells) {
                String id = Bytes.toString(CellUtil.cloneRow(cell));
                String cf = Bytes.toString(CellUtil.cloneFamily(cell));
                String colName = Bytes.toString(CellUtil.cloneQualifier(cell));
                String colValue = Bytes.toString(CellUtil.cloneValue(cell));
                System.out.println("行键:"+id+"列族:"+cf+"列名:"+colName+"列值:"+colValue);
                System.out.println("-------------------------------------------------");
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

获取多条数据

public void getMoreData(){
        try {
            TableName tablename = TableName.valueOf("students");
            //判断表是否存在
            if (!admin.tableExists(tablename)) {
                System.out.println(Bytes.toString(tablename.getName()) + "表不存在");
            }
            // 获取表的实例对象
            Table students = conn.getTable(tablename);
            // 创建一个Scan对象
            Scan scan = new Scan();
            ResultScanner resultScanner = students.getScanner(scan);
            Iterator<Result> resultIterator = resultScanner.iterator();
            StringBuilder sb = null;
            while (resultIterator.hasNext()){
                Result result = resultIterator.next();
                String id = Bytes.toString(result.getRow());
                /*TODO
                    String name = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("name")));
                    String age = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("age")));
                    String gender = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("gender")));
                    String clazz = Bytes.toString(result.getValue(Bytes.toBytes("info"), Bytes.toBytes("clazz")));
                    System.out.println("学号:"+id+",姓名:"+name+",年龄:"+age+",性别:"+gender+",班级:"+clazz);
                 */
                List<Cell> cells = result.listCells();
                sb = new StringBuilder();
                sb.append(id).append(",");
                for (int i = 0; i < cells.size(); i++) {
                    String colName = Bytes.toString(CellUtil.cloneQualifier(cells.get(i)));
                    String colValue = Bytes.toString(CellUtil.cloneValue(cells.get(i)));
                    if (i != cells.size()-1){
                        sb.append(colName).append(":").append(colValue).append(",");
                    }else {
                        sb.append(colName).append(":").append(colValue);
                    }
                }
                System.out.println(sb);
                System.out.println("------------------------------");
            }


        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

创建预分region表

public void createSplitTable(){
        TableName name = TableName.valueOf("splitTable");
        TableDescriptorBuilder test2 = TableDescriptorBuilder.newBuilder(name);
        try {
            ColumnFamilyDescriptor info = ColumnFamilyDescriptorBuilder.of("info");
            test2.setColumnFamily(info);

            if(admin.tableExists(name)){
                System.out.println(Bytes.toString(name.getName())+"表已经存在");
            }
            byte[][] splitKeys={
                Bytes.toBytes("e"),
                Bytes.toBytes("h"),
                Bytes.toBytes("l"),
                Bytes.toBytes("r")
            };
            admin.createTable(test2.build(),splitKeys);
            System.out.println(Bytes.toString(test2.build().getTableName().getName())+"表创建成功");
        } catch (IOException e) {
            System.out.println(Bytes.toString(test2.build().getTableName().getName())+"表创建失败");
            throw new RuntimeException(e);
        }
    }
posted @ 2024-06-19 09:45  yu_lu  阅读(74)  评论(0)    收藏  举报