全部产品

HBase冷存储

更新时间:2019-03-07 17:01:08

介绍

冷数据是大数据存储当中常见的场景。阿里云HBase针对冷数据存储的场景,提供一种新的冷存储介质,其存储成本仅为高效云盘的1/3,写入性能与云盘相当,并能保证数据随时可读。冷存储适用于数据归档、访问频率较低的历史数据等各种冷数据场景。冷存储的使用非常简单,用户可以在购买云HBase实例时选择冷存储作为一个附加的存储空间,并通过建表语句指定将冷数据存放在冷存储介质上面,从而降低存储成本。

开通冷存储

冷存储可以独立购买,作为一个附加存储空间使用。购买冷存储介质后,可以在建表时候中指定把表创建在冷存储上(即冷表),默认是创建在云盘介质上(即热表)。

创建新的HBase实例时,可在购买页面选择是否选购冷存储和冷存储的容量。创建集群时购买冷存储

也可以对一个已有集群增加冷存储介质。方法是在实例的控制台点击“冷存储设置”-“立即开通”,选择冷存储容量后,即可开通冷存储。现有集群开通冷存储

使用冷存储

开通冷存储之后,可以在创建表时通过HFILE_STORAGE_POLICY属性指定要把是表创建在普通存储介质上(热表)还是创建在冷存储上(冷表),不指定默认为热表。如下语句表明test被创建为一个冷表,之后test表的数据将被存储在冷介质上:

  1. create 'test',"info",CONFIGURATION => {'HFILE_STORAGE_POLICY'=>'COLD'}

冷表创建出来之后,其使用和数据写入与普通的表是一样的,通过HBase API操作即可。例如,我们可以通过HBase Shell写入和查询数据:

  1. hbase(main):017:0> put 'test','row1','info:a','a'
  2. Took 0.0154 seconds
  3. hbase(main):018:0> put 'test','row2','info:a','b'
  4. Took 0.0048 seconds
  5. hbase(main):019:0> flush 'test'
  6. Took 2.2975 seconds
  7. hbase(main):020:0> scan 'test'
  8. ROW COLUMN+CELL
  9. row1 column=info:a, timestamp=1539573371860, value=a
  10. row2 column=info:a, timestamp=1539573377499, value=b
  11. 2 row(s)
  12. Took 0.1031 seconds

冷热分离场景下的自动同步

自动同步功能适用于如下场景:数据刚写进去时是热数据(需要比较好的查询性能),随着时间推移逐渐变成冷数据(几乎不查)。例如对于一个订单系统,新创建的订单通常是热数据,但是半年前的订单就是冷数据了。针对这样的场景,自动同步功能通过配置表属性将热表和冷表关联起来,并指定数据在热表中的存活时间TTL,将热表中超过TTL的数据自动移动到冷表中。

前提

  • 自动同步功能从HBase2.0.4和1.5.1版本开始支持,如果您的实例低于此版本,请先进行升级。
  • 使用自动同步功能,要求热表和冷表具有一致的结构(列族相同)。
  • 自动同步功能并不能保证超过TTL的数据立刻被移动到冷表中,而是有一个过程。因此如果使用开源客户端,需要注意有一部分冷数据仍然存在于热表中。也可以使用阿里客户端,我们对这种情况做了处理,使得在应用看来冷热数据是严格按照TTL切分的。

使用开源客户端

举例:我们已经建立好了目标表cold,使用如下语句在新建hot表时指定将hot表中超过1天的数据同步到cold表中:

  1. create 'hot','info',CONFIGURATION => {'hbase.hstore.engine.class' => 'org.apache.hadoop.hbase.regionserver.TransferStoreEngine','hbase.transfercompactor.sink.table'=> 'cold', 'hbase.transfercompactor.source.ttl' =>86400}

如果hot表是一张已经存在的表,可以使用如下语句修改表的属性:

  1. alter'hot',CONFIGURATION => {'hbase.hstore.engine.class' => 'org.apache.hadoop.hbase.regionserver.TransferStoreEngine','hbase.transfercompactor.sink.table'=> 'cold', 'hbase.transfercompactor.source.ttl' => 86400}

字段说明:

  • hbase.hstore.engine.class指定为org.apache.hadoop.hbase.regionserver.TransferStoreEngine表示需要在compact的时候进行数据迁移。
  • hbase.transfercompactor.sink.table 要同步到的目标表名称,用户需要确保目标表已经建好且结构和源表一致。
  • hbase.transfercompactor.source.ttl 表示要将多久之前的数据移动到目标表。单位秒。

使用阿里客户端

使用阿里客户端2.0.2版本(参见阿里云开源HBase客户端)。在HBase Shell中使用如下语句建表:

  1. create_layered 'hot','cold',86400, 'info',...(其他参数同create

这个语句会同时创建hot和cold,将cold设置为冷表,并配置hot中的数据在1天后被移动到cold中。使用如下代码创建connection:

  1. config.set(ClusterConnection.HBASE_CLIENT_CONNECTION_IMPL,
  2. LayeredConnectionImplementation.class.getName());
  3. connection = ConnectionFactory.createConnection(config);

使用针对冷热分离场景做了特殊处理的LayeredConnectionImplementation类,这样就可以做到应用看来冷热数据是严格按照TTL切分的。

注意事项

1.冷存储的读IOPS能力很低(每个节点上限为25),所以冷表只适合低频查询场景。

2.写入吞吐上,冷表和基于高效云盘的热表相当,可以放心写入数据。

3.冷表不适合并发大量读请求,如果有这种行为可能会导致请求异常。

4.购买冷存储空间特别大的客户可以酌情调整 读IOPS 能力,详情工单。

5.建议平均每个core节点管理冷数据不要超过30T。如果是同时有冷热表的集群,需要看region数量来衡量。如果需要单个core节点管理更大数据量的冷数据,可以工单咨询优化建议。

6.冷表无法转换成热表

7.如果未购买冷存储,但是建表时候指定了冷存储,会导致实际开通冷存储后表里数据迁移到冷存储。这个过程会影响表的访问,非常不建议这么操作。

性能数据

测试场景1:随机写

环境

Core配置:

  • ecs.sn2ne.2xlarge (8核32G )
  • 300G高效云盘 * 4
  • 6台

Master配置:

  • ecs.sn1ne.2xlarge(8核16G)
  • 2台

HBase配置:

  • 表 BLOCKCACHE => ‘false’
  • short-circuit 关闭
  • 1台Core启动RS

HDFS配置:

  • 6台Core都启动DataNode

测试机器:

  • ecs.sn1ne.2xlarge(8核16G)

测试

  1. hbase pe --nomapred --valueSize=100 --rows=1000000 --table=test --presplit=64 randomWrite 120

结果

存储类型 TPS(120线程/无batch/value100B) TPS(120线程/无batch/value100B/SKIP_WAL)
冷表 193116.68 211393.4
热表 192819.72 219569.1

测试场景2:Get延迟对比

环境

Core配置:

  • ecs.sn2ne.2xlarge (8核32G )
  • 300G高效云盘 * 4
  • 6台

Master配置:

  • ecs.sn1ne.2xlarge(8核16G)
  • 2台

HBase配置:

  • 表 BLOCKCACHE => ‘false’
  • short-circuit 关闭
  • 只有1台Core启动RS

HDFS配合:

  • 6台均Core启动DataNode

测试机器:

  • ecs.sn1ne.2xlarge(8核16G)

数据准备

  1. #冷表
  2. hbase pe --nomapred --oneCon=true --valueSize=1024 --presplit=32 --rows=2000000 --table=$TABLE --autoFlush=true --storagePolicyHFile=COLD sequentialWrite 15
  3. #热表
  4. hbase pe --nomapred --oneCon=true --valueSize=1024 --presplit=32 --rows=2000000 --table=$TABLE --autoFlush=true sequentialWrite 15
  5. #大约30G数据, 生成完毕后flush一次表

测试

  1. hbase pe --nomapred --oneCon=true --rows=2000 --table=$TABLE randomRead 15

结果

存储类型 平均延迟us p999延迟us
冷表 13414 320414
热表 3862 265905

测试场景3:Scan顺序读耗时对比

环境

Core配置:

  • ecs.sn2ne.2xlarge (8核32G )
  • 300G高效云盘 * 4
  • 6台

Master配置:

  • ecs.sn1ne.2xlarge(8核16G)
  • 2台

HBase配置:

  • 表 BLOCKCACHE => ‘false’
  • short-circuit 关闭
  • hbase.storescanner.use.pread=false
  • 只有1台Core启动RS

HDFS配合:

  • 6台均Core启动DataNode

测试机器:

  • ecs.sn1ne.2xlarge(8核16G)

数据准备

  1. #冷表
  2. hbase pe --nomapred --oneCon=true --valueSize=1024 --rows=2000000 --table=$TABLE --autoFlush=true --storagePolicyHFile=COLD sequentialWrite 1
  3. #热表
  4. hbase pe --nomapred --oneCon=true --valueSize=1024 --rows=2000000 --table=$TABLE --autoFlush=true sequentialWrite 1
  5. #大约2G数据, 2个region,生成完毕后flush一次表,并做一个major,HDFS数据全在本地

测试

  1. hbase pe --nomapred --oneCon=true --rows=2000000 --caching=1000 --table=$TABLE scan 1
  2. #一个线程顺序scan 2G数据

结果

存储类型 2G数据耗时(caching30) 2G数据耗时(caching1000)
冷表 464659ms, 4.23MB/s 109779ms, 17.91MB/s
热表 51457ms, 38.22MB/s 17764m, 110.7MB/s