更新时间:2024-12-24 GMT+08:00

冷热分离命令简介

此章节主要介绍CloudTable HBase冷热分离命令的使用,HBase集群基本命令使用请参见HBase Shell命令简介

设置表的冷热分界线

  • Shell
    • 创建冷热分离表。
      hbase(main):002:0> create 'hot_cold_table', {NAME=>'f', COLD_BOUNDARY=>'86400'}

      参数说明。

      • NAME:需要冷热分离的列族。
      • COLD_BOUNDARY:冷热分离时间点,单位为秒(s)。例如COLD_BOUNDARY为86400,代表86400秒(一天)前写入的数据会被自动归档到冷存储。

        冷热分离时间点要大于Major Compaction执行周期。Major Compaction默认执行周期为7天。

    • 取消冷热分离。
      hbase(main):004:0> alter 'hot_cold_table', {NAME=>'f', COLD_BOUNDARY=>""}
    • 为已经存在的表设置冷热分离,或者修改冷热分离分界线,单位为秒。
      hbase(main):005:0> alter 'hot_cold_table', {NAME=>'f', COLD_BOUNDARY=>'86400'}

      查询冷热分离是否设置或者修改成功。

      hbase:002:0> desc 'hot_cold_table'
      Table hot_cold_table is ENABLED
      hot_cold_table
      COLUMN FAMILIES DESCRIPTION
      {NAME => 'f', VERSIONS => '1', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', IN_MEMORY => 'false', COMPRE
      SSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536', METADATA => {'COLD_BOUNDARY' => '1200'}}
      1 row(s)
      Quota is disabled
      Took 0.0339 seconds
  • Java API方式
    • 新建冷热分离表。
      • COLD_BOUNDARY设置冷热分离时间分界点,单位为秒, 示例表示1天之前的数据归档为冷数据。
      Admin admin = connection.getAdmin();
      TableName tableName = TableName.valueOf("hot_cold_table");
      HTableDescriptor descriptor = new HTableDescriptor(tableName);
      HColumnDescriptor cf = new HColumnDescriptor("f");
      cf.setValue(HColumnDescriptor.COLD_BOUNDARY, "86400");
      descriptor.addFamily(cf);
      admin.createTable(descriptor);
    • 取消冷热分离。
      HTableDescriptor descriptor = admin.getTableDescriptor(tableName);
      HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
      cf.setValue(HColumnDescriptor.COLD_BOUNDARY, null);
      admin.modifyTable(tableName, descriptor);
    • 为已经存在的表设置冷热分离功能,或者修改冷热分离分界线。

      COLD_BOUNDARY设置冷热分离时间分界点,单位为秒, 示例表示1天之前的数据归档为冷数据。

      HTableDescriptor descriptor = admin.getTableDescriptor(tableName);
      HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
      cf.setValue(HColumnDescriptor.COLD_BOUNDARY, "86400");
      admin.modifyTable(tableName, descriptor);

      数据从热存储到冷存储、从冷存储到热存储,需要执行Major Compaction。

数据写入

冷热分离的表与普通表的数据写入方式完全一致,数据会先存储在热存储(超高IO)中。随着时间的推移,如果一行数据满足当前时间-时间列值>COLD_BOUNDARY设置的值条件,则会在执行Compaction时被归档到冷存储(普通IO)中。

  • 插入记录。

    执行“put”命令往指定表插入一条记录,需要指定表的名称,主键,自定义列,以及插入的具体值。

    hbase(main):004:0> put 'hot_cold_table','row1','cf:a','value1'
    0 row(s) in 0.2720 seconds

    命令中各参数分别代表如下含义:

    • hot_cold_table:表的名称。
    • row1:主键。
    • cf:a:自定义的列。
    • value1:插入的值。

数据查询

由于冷热数据都在同一张表中,因此用户所有的查询操作都只需在一张表内进行。在查询时,建议通过配置TimeRange来指定查询的时间范围,系统将会根据指定的时间范围决定查询模式,即仅查询热存储、仅查询冷存储或同时查询冷存储和热存储。如果查询时未限定时间范围,则会导致查询冷数据。在这种情况下,查询吞吐量会受到冷存储的限制。

  • 冷存储中的数据常用于归档,会很少访问。如果冷存储中的数据被大量频繁请求访问,请检查冷热数据边界(COLD_BOUNDARY)配置是否正确。如果频繁查询的大量数据在冷存储中将会限制查询的性能。
  • 如果冷存储中存储的一行数据中的某个字段更新,则更新的字段存储在热存储中。如果指定HOT_ONLY或TimeRange参数仅查询热存储中的数据,则只返回更新的字段。如果要返回整行的数据,则必须在不指定HOT_ONLY或TimeRange参数的情况下执行查询,或者确保TimeRange指定的时间范围涵盖从插入行的时间点到最后更新行的时间点的时间段。因此,建议您不要更新存储在冷存储中的数据。
  • 随机查询Get。
    • Shell
      • 不指定HOT_ONLY参数来查询数据。在这种情况下,将会查询冷存储中的数据。
        hbase(main):001:0> get 'hot_cold_table', 'row1'
      • 通过指定HOT_ONLY参数来查询数据。在这种情况下,只会查询热存储中的数据。
        hbase(main):002:0> get 'hot_cold_table', 'row1', {HOT_ONLY=>true}
      • 通过指定TimeRange参数来查询数据。在这种情况下,CloudTable将会比较TimeRange和冷热边界值,以确定是只查询热存储还是冷存储中的数据,还是同时查询热冷存储中的数据。
        hbase(main):003:0> get 'hot_cold_table', 'row1', {TIMERANGE => [0, 1568203111265]}

      TimeRange:查询的时间范围。范围中的时间是UNIX时间戳,表示自1970年1月1日00:00 UTC以来经过的毫秒数。

    • Java API
      • 不指定HOT_ONLY参数来查询数据。在这种情况下,将会查询冷存储中的数据。
        Get get = new Get("row1".getBytes());
      • 通过指定HOT_ONLY参数来查询数据。在这种情况下,只会查询热存储中的数据。
        Get get = new Get("row1".getBytes());
        get.setAttribute(HBaseConstants.HOT_ONLY, Bytes.toBytes(true));
      • 通过指定TimeRange参数来查询数据。在这种情况下,CloudTable将会比较TimeRange和冷热边界值(COLD_BOUNDARY ),以确定是只查询热存储还是冷存储中的数据,还是同时查询热冷存储中的数据。
        Get get = new Get("row1".getBytes());
        get.setTimeRange(0, 1568203111265)

        TimeRange:查询的时间范围。范围中的时间是UNIX时间戳,表示自1970年1月1日00:00 UTC以来经过的毫秒数。

  • 范围查询。
    • Shell
      • 不指定HOT_ONLY参数来查询数据。在这种情况下,将会查询冷存储中的数据。
        hbase(main):001:0> scan 'hot_cold_table', {STARTROW =>'row1', STOPROW=>'row9'}
      • 通过指定HOT_ONLY参数来查询数据。在这种情况下,只会查询热存储中的数据。
        hbase(main):002:0> scan 'hot_cold_table', {STARTROW =>'row1', STOPROW=>'row9', HOT_ONLY=>true}
      • 通过指定TimeRange参数来查询数据。在这种情况下,CloudTable将会比较TimeRange和冷热边界值,以确定是只查询热存储还是冷存储中的数据,还是同时查询热冷存储中的数据。
        hbase(main):003:0> scan 'hot_cold_table', {STARTROW =>'row1', STOPROW=>'row9', TIMERANGE => [0, 1568203111265]}

      TimeRange:查询的时间范围。范围中的时间是UNIX时间戳,表示自1970年1月1日00:00 UTC以来经过的毫秒数。

    • Java API
      • 不指定HOT_ONLY参数来查询数据。在这种情况下,将会查询冷存储中的数据。
        TableName tableName = TableName.valueOf("chsTable");
        Table table = connection.getTable(tableName);
        Scan scan = new Scan();
        ResultScanner scanner = table.getScanner(scan);
      • 通过指定HOT_ONLY参数来查询数据。在这种情况下,只会查询热存储中的数据。
        Scan scan = new Scan();
        scan.setAttribute(HBaseConstants.HOT_ONLY, Bytes.toBytes(true));
      • 通过指定TimeRange参数来查询数据。在这种情况下,CloudTable将会比较TimeRange和冷热边界值(COLD_BOUNDARY ),以确定是只查询热存储还是冷存储中的数据,还是同时查询热冷存储中的数据。
        Scan scan = new Scan();
        scan.setTimeRange(0, 1568203111265);

        TimeRange:查询的时间范围。范围中的时间是UNIX时间戳,表示自1970年1月1日00:00 UTC以来经过的毫秒数。

  • 优先查询热数据。

    在查询客户所有记录等信息的范围查询中,CloudTable可以扫描热存储和冷存储中的数据。查询结果将根据数据行按写入表时的时间戳降序返回。在大多数情况下,热数据出现在冷数据之前。如果在范围查询中没有配置HOT_ONLY参数,CloudTable将会扫描热存储和冷存储中的数据,查询响应时间将会增加。如果启用热数据优先特性,CloudTable会优先查询热存储中的数据。只有当热存储中的行数小于要查询的最小行数时,才会查询冷存储中的数据。这样,减少了冷存储的访问提高了响应速度。

    • Shell
      hbase(main):001:0> scan 'hot_cold_table', {STARTROW =>'row1', STOPROW=>'row9',COLD_HOT_MERGE=>true}
    • Java API
      TableName tableName = TableName.valueOf("hot_cold_table");
      Table table = connection.getTable(tableName);
      Scan scan = new Scan();
      scan.setAttribute(HBaseConstants.COLD_HOT_MERGE, Bytes.toBytes(true));
      scanner = table.getScanner(scan);
  • Major Compaction命令。
    • Shell
      • 合并表所有分区的热数据区。
        hbase(main):002:0> major_compact 'hot_cold_table', nil, 'NORMAL', 'HOT'
      • 合并表所有分区的冷数据区。
        hbase(main):002:0> major_compact 'hot_cold_table', nil, 'NORMAL', 'COLD'
      • 合并表所有分区的热冷数据区。
        hbase(main):002:0> major_compact 'hot_cold_table', nil, 'NORMAL', 'ALL'
    • Java API
      • 合并表所有分区的热数据区。
        Admin admin = connection.getAdmin();
        TableName tableName = TableName.valueOf("hot_cold_table");
        admin. majorCompact (tableName,null, CompactType.NORMAL, CompactionScopeType.HOT);
      • 合并表所有分区的冷数据区。
        Admin admin = connection.getAdmin();
        TableName tableName = TableName.valueOf("hot_cold_table");
        admin. majorCompact (tableName,null, CompactType.NORMAL, CompactionScopeType.COLD);
      • 合并表所有分区的热冷数据区。
        Admin admin = connection.getAdmin();
        TableName tableName = TableName.valueOf("hot_cold_table");
        admin. majorCompact (tableName,null, CompactType.NORMAL, CompactionScopeType.ALL);