HBase:列族TTL和单元格TTL
Posted 你是小KS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HBase:列族TTL和单元格TTL相关的知识,希望对你有一定的参考价值。
1.声明
当前内容主要用于本人学习和复习,当前内容主要为使用TTL和测试
当前内容主要借鉴官方文档
2.Time To Live (TTL)
ColumnFamilies can set a TTL length in seconds, and HBase will automatically delete rows once the expiration time is reached. This applies to all versions of a row - even the current one. The TTL time encoded in the HBase for the row is specified in UTC.
列族可以设置TTL使用秒,HBase将会自动删除达到过期时间的row
.包含这个行的所有版本和当前版本。这个TTL时间是使用UTC编码的
Store files which contains only expired rows are deleted on minor compaction. Setting hbase.store.delete.expired.storefile to false disables this feature. Setting minimum number of versions to other than 0 also disables this.
存储过期行的文件将在下一个压缩时被删除。设置(hbase-site.xml文件中)hbase.store.delete.expired.storefile为false禁用这个特性。将最小版本数设置为0以外的其他版本也会禁用此功能。(也就是说实际上删除的row是存储的,只有下次压缩才会删除,可以通过设置属性禁用删除存储)
Recent versions of HBase also support setting time to live on a per cell basis. See HBASE-10560 for more information. Cell TTLs are submitted as an attribute on mutation requests (Appends, Increments, Puts, etc.) using Mutation#setTTL. If the TTL attribute is set, it will be applied to all cells updated on the server by the operation. There are two notable differences between cell TTL handling and ColumnFamily TTLs:
最近的HBase斑斑也支持设置单元格ttl,查看HBASE-10560获取更多信息。单元格ttl作为一个属性提交到请求中(Appends,Increments,Puts),使用Mutation的setTTL
。如果这个TTL属性被设置,它将应用于服务器上由操作更新的所有单元格。这有两个不同点关于单元格TTL和列族TTL:
• Cell TTLs are expressed in units of milliseconds instead of seconds.
• A cell TTLs cannot extend the effective lifetime of a cell beyond a ColumnFamily level TTL setting.
- 单元格TTL使用的单位是毫秒而不是秒
- 一个单元格TTL不能设置存活时间比列族的TTL时间长
也就是说,单元格可以设置TTL单位是毫秒,列族是秒。单元格的TTL必须小于列族的TTL
3.使用和测试列族TTL
/**
* @description 当前内容主要用于学习和测试当前的列族的TTL的设置
* @author hy
* @date 2020-06-17
*/
public class ColumnFamilyTTLTest
public static void main(String[] args) throws IOException, InterruptedException
HBaseUtils hBaseUtils = new HBaseUtils("192.168.1.104:2181");
Admin admin = hBaseUtils.getAdmin();
// 1. 创建一个测试表,并添加列族cf
TableName tableName = TableName.valueOf("test");
TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder("cf".getBytes()).build())
.build();
admin.createTable(tableDescriptor);
System.out.println("创建表并添加列族cf成功");
// 2.为当前的表添加一个ttl的列族(默认设定时间为10秒)
ColumnFamilyDescriptor cfDesc = ColumnFamilyDescriptorBuilder.newBuilder("ttl-cf".getBytes()).setTimeToLive(10)
.build();
admin.addColumnFamily(tableName, cfDesc);
System.out.println("为表添加一个具有TTL的列族ttl-cf,设定超时时间为10s");
// 3.测试为当前的ttl列族添加数据
Connection conn = hBaseUtils.getConnection();
Table table = conn.getTable(tableName);
table.put(new Put("ttl-row".getBytes()).addColumn("ttl-cf".getBytes(), "a".getBytes(), "aaaa".getBytes()));
System.out.println("添加一行数据.....");
// 4.扫描当前的表
System.out.println("开始扫描表中数据.....");
Scan scan=new Scan();
ResultScanner scanner = table.getScanner(scan);
Iterator<Result> iterator = scanner.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
scanner.close();
// 5.等待10秒
System.out.println("开始休眠十秒.....");
Thread.sleep(10000L);
// 6.再次扫描表
System.out.println("再次开启表扫描.....");
scan=new Scan();
scanner = table.getScanner(scan);
iterator = scanner.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
hBaseUtils.close();
执行结果:
这里的列族设置了TTL确实实现了超时设定,但是表现不出来到底是删除了整行还是只删除了该行的一个列族中的数据
继续使用shell命令行开始测试
查看ui界面中的table
发现当前的超时只是将数据删除并没有删除列族
通过向一行中添加cf:a数据和添加ttl-cf:a数据方式,则测试发现(和描述不同)
- 该过期是针对当前的列族而言的数据,就是让该列族具有过期时间效果
- 默认所有的创建的列族都具有过期时间
- 该过期列族删除的并不是行数据,而是列族中的数据,其他列族的数据保留
4.使用单元格TTL
/**
* @description 设置单元格ttl(结果就是如果设置的单元格ttl大于列族的ttl时,那么就按照列族的ttl来算,否则按照单元格的ttl算)
* @author hy
* @date 2020-06-17
*/
public class CellTTLTest
public static void main(String[] args) throws IOException, InterruptedException
HBaseUtils hBaseUtils = new HBaseUtils("192.168.1.104:2181");
// 1.测试为当前的cf列族添加数据
TableName tableName = TableName.valueOf("test");
Connection conn = hBaseUtils.getConnection();
Table table = conn.getTable(tableName);
Put addPut = new Put("ttl-cell-row".getBytes()).addColumn("cf".getBytes(), "a".getBytes(), "aaaa".getBytes());
addPut.setTTL(10000L);
table.put(addPut);
System.out.println("添加一行数据.....");
// 2.为ttl-cf中添加一个ttl单元格不超过10秒
Put put2 = new Put("ttl-cell-row".getBytes()).addColumn("ttl-cf".getBytes(), "b".getBytes(), "bbbb".getBytes());
put2.setTTL(8000L);
table.put(put2);
// 添加一个超过列族TTL的单元格TTL
try
Put put3 = new Put("ttl-cell-row".getBytes()).addColumn("ttl-cf".getBytes(), "c".getBytes(), "cccc".getBytes());
put3.setTTL(50000L);
table.put(put3);
System.out.println("添加成功..........");
catch (Exception e)
e.printStackTrace();
System.out.println("出现错误.....");
// 3.扫描当前的表
System.out.println("开始扫描表中数据.....");
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
Iterator<Result> iterator = scanner.iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
scanner.close();
// 4.等待10秒
System.out.println("开始休眠十秒.....");
Thread.sleep(10000L);
// 5.再次扫描表
System.out.println("再次开启表扫描.....");
scan = new Scan();
scanner = table.getScanner(scan);
iterator = scanner.iterator();
while (iterator.hasNext())
System.out.println(iterator.next());
hBaseUtils.close();
设定了ttl-cf的两个单元格过期时间:8秒和50秒
设定了cf的单元格过期时间:10秒
此时的结果:
结果发现当前的数据可以添加,并且当前的在10秒过后数据都消失了,这说明了
- 如果为没有设置ttl的列族添加单元格并设置TTL时,那么就按照单元格的TTL计算
- 如果为一个具有TTL的列族添加带有TTL的单元格时,如果该单元格TTL时间大于列族的TTL时间,就按照列族的TTL时间计算,否则按照单元格的TTL计算
5.总结
1.可以为列族或单元格都添加TTL
2.具有TTL的列族下的单元格都具有TTL,如果添加时设定了单元格的TTL,那么久按照小的设置TTL
以上纯属个人见解,如有问题请联系本人!
以上是关于HBase:列族TTL和单元格TTL的主要内容,如果未能解决你的问题,请参考以下文章