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.

  1. 單元格TTL使用的單位是毫秒而不是秒
  2. 一個單元格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數據方式,則測試發現(和描述不同)

  1. 該過期是針對當前的列族而言的數據,就是讓該列族具有過期時間效果
  2. 默認所有的創建的列族都具有過期時間
  3. 該過期列族刪除的並不是行數據,而是列族中的數據,其他列族的數據保留

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秒過後數據都消失了,這說明了

  1. 如果爲沒有設置ttl的列族添加單元格並設置TTL時,那麼就按照單元格的TTL計算
  2. 如果爲一個具有TTL的列族添加帶有TTL的單元格時,如果該單元格TTL時間大於列族的TTL時間,就按照列族的TTL時間計算,否則按照單元格的TTL計算

5.總結

1.可以爲列族或單元格都添加TTL

2.具有TTL的列族下的單元格都具有TTL,如果添加時設定了單元格的TTL,那麼久按照小的設置TTL

以上純屬個人見解,如有問題請聯繫本人!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章