项目实训第十三天

本文最后更新于:2021年7月24日 晚上

HBase

基本操作

API操作

  1. 获取一行数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    @Test
    public void getLine() throws IOException {
    // 封装Get对象
    Get get = new Get("u1".getBytes(StandardCharsets.UTF_8));
    // 查询数据,获取结果集
    Result result = users.get(get);
    // 获取结果
    NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = result.getMap();
    // 遍历映射
    for (Map.Entry<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> entry : map.entrySet()) {
    // 键是列族名
    System.out.println("Column Family:" + new String(entry.getKey()));
    // 值是列族中包含的列
    NavigableMap<byte[], NavigableMap<Long, byte[]>> columns = entry.getValue();
    for (Map.Entry<byte[], NavigableMap<Long, byte[]>> column : columns.entrySet()) {
    // 键是列名
    System.out.println("\tColumn:" + new String(column.getKey()));
    // 值是实际数据
    NavigableMap<Long, byte[]> values = column.getValue();
    for (Map.Entry<Long, byte[]> value : values.entrySet()) {
    // 键是时间戳
    System.out.println("\t\tTimestamp:" + value.getKey());
    // 值是实际数据
    System.out.println("\t\tValue:" + new String(value.getValue()));
    }
    }
    }
    }
  2. 获取指定行键指定列族的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @Test
    public void getColumnFamily() throws IOException {
    // 封装Get对象
    Get get = new Get("u1".getBytes(StandardCharsets.UTF_8));
    // 指定列族
    byte[] basic = "basic".getBytes(StandardCharsets.UTF_8);
    get.addFamily(basic);
    // 获取数据
    Result result = users.get(get);
    // 解析结果
    NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(basic);
    for (Map.Entry<byte[], byte[]> entry : familyMap.entrySet()) {
    // 键是数据的列名,值是实际数据
    System.out.println("Key:" + new String(entry.getKey()) + ", Value:" + new String(entry.getValue()));
    }
    }
  3. 获取指定行键指定列的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Test
    public void getValue() throws IOException {
    // 封装Get对象
    Get get = new Get("u1".getBytes(StandardCharsets.UTF_8));
    // 指定列族和列
    byte[] basic = "basic".getBytes(StandardCharsets.UTF_8);
    byte[] name = "name".getBytes(StandardCharsets.UTF_8);
    get.addColumn(basic, name);
    // 查询数据,获取结果
    Result result = users.get(get);
    // 解析结果
    byte[] value = result.getValue(basic, name);
    System.out.println(new String(value));
    }
  4. 遍历结果集

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    @Test
    public void scanTable() throws IOException {
    // 封装Scan对象
    Scan scan = new Scan();
    // 添加Scan对象,来获取结果集
    ResultScanner results = users.getScanner(scan);
    // 指定列族和列
    byte[] basic = "basic".getBytes(StandardCharsets.UTF_8);
    byte[] password = "password".getBytes(StandardCharsets.UTF_8);
    // 遍历结果集
    Iterator<Result> iterator = results.iterator();
    while(iterator.hasNext()){
    // 获取结果
    Result result = iterator.next();
    // 解析结果
    byte[] value = result.getValue(basic, password);
    System.out.println(new String(value));
    }
    }
  5. 过滤数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Test
    public void filter() throws IOException {
    // 封装Scan对象
    Scan scan = new Scan();
    // 构建过滤器
    Filter filter = new ValueFilter(CompareOperator.EQUAL, new RegexStringComparator(".*AAA.*"));
    // 设置过滤器
    scan.setFilter(filter);
    // 过滤数据
    ResultScanner results = users.getScanner(scan);
    // 指定列族
    byte[] basic = "basic".getBytes(StandardCharsets.UTF_8);
    byte[] password = "password".getBytes(StandardCharsets.UTF_8);
    // 遍历结果
    for (Result result : results) {
    // 解析结果
    byte[] value = result.getValue(basic, password);
    System.out.println(new String(value));
    }
    }
  6. 删除指定行键指定列的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void deleteValue() throws IOException {
    // 封装Delete对象
    Delete delete = new Delete("u1".getBytes(StandardCharsets.UTF_8));
    // 指定列族和列
    delete.addColumn("info".getBytes(StandardCharsets.UTF_8),
    "address".getBytes(StandardCharsets.UTF_8));
    // 删除数据
    users.delete(delete);
    }
  7. 删除指定行间指定列族的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void deleteFamily() throws IOException {
    // 封装Delete对象
    Delete delete = new Delete("u1".getBytes(StandardCharsets.UTF_8));
    // 指定列族
    delete.addFamily("info".getBytes(StandardCharsets.UTF_8));
    // 删除数
    users.delete(delete);
    }
  8. 删除指定行键的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Test
    public void deleteFamily() throws IOException {
    // 封装Delete对象
    Delete delete = new Delete("u1".getBytes(StandardCharsets.UTF_8));
    // 指定列族
    delete.addFamily("info".getBytes(StandardCharsets.UTF_8));
    // 删除数
    users.delete(delete);
    }
  9. 删除表

    1
    2
    3
    4
    5
    6
    7
    @Test
    public void deleteTable() throws IOException {
    // 禁用表
    admin.disableTable(TableName.valueOf("users"));
    // 删除表
    admin.deleteTable(TableName.valueOf("users"));
    }
  10. 关流

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @After
    public void close() throws IOException {
    // 关闭表
    users.close();
    // 关闭管理权
    admin.close();
    // 关闭连接
    connection.close();
    }

基本结构

HRegion

  1. 在HBase中,会从行键方向上来对表进行切分,切分出来的每一部分都称之为是一个HRegion。一个表中会包含1个到多个HRegion

  2. 切分出来的每一个HRegion都会交给HRegionServer来处理。HRegionServer是HBase的从进程

  3. 在HBase中,会默认对行键来进行排序,按照字典序来进行排序,因此导致切分出来的HRegion之间的数据是不交叉的

  4. 因为HRegion之间的数据是不交叉的,因此请求就可以发送到不同的HRegionServer上来进行处理,此时就能保证请求不会集中在一个节点上而是分布在不同的节点上,从而保证请求的均衡以及数据的均衡

  5. 随着运行时间的延长,HRegion中的数据会越来越多,此时当HRegion达到指定大小(默认是10G)的时候,会进行分裂,均裂为两个等大的HRegion。分裂完成之后,其中的一个HRegion会发生转移,转交给其他的HRegionServer来进行管理。这个过程中,一般不会发生数据的转移,一般指的是管理权的转移

  6. 一个HRegion中包含1个到多个HStore,其中HStore的数量由列族的数量决定

  7. 每一个HStore中,会包含1个memStore(写缓存),以及0到多个HFile/StoreFile

    HRegion结构


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!