数据冷热分离,需要以时间分界点为依据,对数据进行存储。本文介绍如何设置冷热分离时间分界点。
已创建实例,且已开通容量型存储,详情请参见开通容量型存储。
已连接 HBase 实例:
通过 HBase Shell 连接实例,详情请参见使用 HBase Shell 连接实例。
通过 Java API 连接实例,详情请参见使用 Java API 连接实例。
通过调整 COLD_BOUNDARY
来设置冷热分离时间分界点,单位为秒(s),取值如下所示:
取值大于 0,表示将该时间点之前的数据存储至冷存储中。例如,设置为 86400 秒(24 小时),表示 24 小时前写入的数据会被自动归档至冷存储中。
取值为 0,表示数据全部存储在冷存储中。
取值为 -1,表示关闭冷热分离。
注意
修改冷热分离时间分界点或取消冷热分离后,需要等待系统下一次执行完 compaction 后(周期为 3.5 天~10.5 天内的随机数),数据才能按照新的冷热分离分界进行迁移。如果想要数据立即进行迁移,您可以在 HBase 命令行中执行 major_compact 'tableName'
或 major_compact 'regionName'
。关于 major_compact
命令的更多用法,可执行 help "major_compact"
查看详情。
创建冷热分离表,并设置冷热分离时间分界点。
示例:创建表 ch_table
,冷热分离时间分界点为 86400 秒(24 小时),表示 24 小时前写入的数据会被自动归档至容量型存储中。
hbase(main):002:0> create 'ch_table', {NAME=>'f', COLD_BOUNDARY=> 86400}
参数说明:
NAME
:需要冷热分离的列簇。
COLD_BOUNDARY
:冷热分离分界点,单位:秒(s)。
为存量表设置冷热分离时间分界点,或修改冷热分离时间分界点。
hbase(main):003:0> alter 'ch_table', {NAME=>'f', COLD_BOUNDARY=> 86400}
取消冷热分离。
hbase(main):004:0> alter 'ch_table', {NAME=>'f', COLD_BOUNDARY=> -1}
创建冷热分离表,并设置冷热分离时间分界点。
Admin admin = connection.getAdmin(); TableName tableName = TableName.valueOf("ch_table"); HTableDescriptor descriptor = new HTableDescriptor(tableName); HColumnDescriptor cf = new HColumnDescriptor("f"); cf.setValue(COLD_BOUNDARY, "86400"); descriptor.addFamily(cf); admin.createTable(descriptor);
为存量表设置冷热分离时间分界点,或修改冷热分离时间分界点。
HTableDescriptor descriptor = admin .getTableDescriptor(tableName); HColumnDescriptor cf = descriptor.getFamily("f".getBytes()); cf.setValue(COLD_BOUNDARY, "86400"); admin.modifyTable(tableName, descriptor);
取消冷热分离。
HTableDescriptor descriptor = admin .getTableDescriptor(tableName); HColumnDescriptor cf = descriptor.getFamily("f".getBytes()); cf.setValue(COLD_BOUNDARY, -1); admin.modifyTable(tableName, descriptor);
冷热分离表与普通表数据写入方式完全一致,数据写入时间戳使用当前时间。数据写入时先存储在热存储中,随着时间的推移,若数据的当前时间 - 写入时间 > COLD_BOUNDARY
指定的阈值,则在 major_compact 后会归档至冷存储中。
冷热数据存储在同一张表总共,因此数据读取时只需要和一张表进行交互。可直接在 Get/Scan
命令中设置 HOT_ONLY
,指明仅查询热数据。也可以设置 TimeRange
限定数据时间范围,HBase 自动根据设置的 TimeRange
与 COLD_BOUNDARY
进行比较,决定是查询热数据、冷数据或同时查询热数据和冷数据。若都不设置,则并行访问冷数据和热数据合并后的结果。查询冷数据延迟比热数据延迟高,且查询吞吐会收到冷存储限制。
指定 HOT_ONLY
,仅查询热数据。
hbase(main):001:0> get 'ch_table', 'row1', {HOT_ONLY=>true}
不指定 HOT_ONLY
,同时查询冷数据和热数据。
hbase(main):002:0> get 'ch_table', 'row1'
指定 TimeRange
(Unix 时间戳,单位为毫秒(ms)),系统会对 TimeRange
和 COLD_BOUNDARY
进行比较,决定是查询热数据、冷数据或同时查询热数据和冷数据。
hbase(main):003:0> get 'ch_table', 'row1', {TIMERANGE => [0, 1568203111265]}
指定 HOT_ONLY
,仅查询热数据。
get = new Get("row1".getBytes()); get.setAttribute(HOT_ONLY, Bytes.toBytes(true));
不指定 HOT_ONLY
,同时查询冷数据和热数据。
Get get = new Get("row1".getBytes()); System.out.println("result: " + table.get(get));
指定 TimeRange
(Unix 时间戳,单位为毫秒(ms)),系统会对 TimeRange
和 COLD_BOUNDARY
进行比较,决定是查询热数据、冷数据或同时查询热数据和冷数据。
get = new Get("row1".getBytes()); get.setTimeRange(0, 1568203111265)
指定 HOT_ONLY
,仅查询热数据。
hbase(main):001:0> scan 'ch_table', {STARTROW =>'row1', STOPROW=>'row9', HOT_ONLY=>true}
不指定 HOT_ONLY
,同时查询冷数据和热数据。
hbase(main):002:0> scan 'ch_table', {STARTROW =>'row1', STOPROW=>'row9'}
指定 TimeRange
(Unix 时间戳,单位为毫秒(ms)),系统会对 TimeRange
和 COLD_BOUNDARY
进行比较,决定是查询热数据、冷数据或同时查询热数据和冷数据。
hbase(main):003:0> scan 'ch_table', {STARTROW =>'row1', STOPROW=>'row9', TIMERANGE => [0, 1568203111265]}
指定 HOT_ONLY
,仅查询热数据。
scan = new Scan(); scan.setAttribute(HOT_ONLY, Bytes.toBytes(true));
不指定 HOT_ONLY
,同时查询冷数据和热数据。
Scan scan = new Scan(); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { System.out.println("scan result:" + result); }
指定 TimeRange
(Unix 时间戳,单位为毫秒(ms)),系统会对 TimeRange
和 COLD_BOUNDARY
进行比较,决定是查询热数据、冷数据或同时查询热数据和冷数据。
scan = new Scan(); scan.setTimeRange(0, 1568203111265);