1. 程式人生 > >HBase總結(7)--專用過濾器

HBase總結(7)--專用過濾器

一、介紹

除了上述介紹的比較過濾器以外,hbase還提供了許多專門用於一些特殊場景的過濾器,這樣的過濾器叫做專用過濾器

二、例子

1、單列值過濾器:SingleColumnValueFilter

該過濾器用在用使用者指定的某一類來過濾一行,即如果某一行的指定列的最大版本的資料不符合條過濾器條件時,整行資料將要被過濾掉。

該過濾器有兩個建構函式:

(1)SingleColumnValueFilter(byte[] family,byte[] column,CompareOp compareOp,byte[] value)

(2)SingleColumnValueFilter(byte[] family,byte[] column,CompareOp compareOp,ByteArrayComparable valuessss)

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			conf=init();
			HTable table=new HTable(conf, tableName);
			//建立單行值過濾器
			SingleColumnValueFilter filter=new SingleColumnValueFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL,Bytes.toBytes("value5"));
			//也可以使用其他比較器
			SingleColumnValueFilter filter2=new SingleColumnValueFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL, new SubstringComparator("value"));
			//建立scan
			Scan scan=new Scan();
			filter.setFilterIfMissing(true);
			scan.setFilter(filter2);
			//獲取結果並盡心顯示
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
					System.out.println(kv.getValue().toString());
				}
			}
			//釋放資源
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	

2、單列值排除過濾器:SingleColumnValueExcludeFilter

該過濾器功能與上述的過濾器基本上是相同的,唯一的不同點就在於,該過濾器會將參考列進行過濾,即返回的資料中不含有參考列的資料。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			conf=init();
			HTable table=new HTable(conf, tableName);
			//建立單行值過濾器
			SingleColumnValueExcludeFilter filter=new SingleColumnValueExcludeFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL,Bytes.toBytes("value5"));
			//也可以使用其他比較器
			SingleColumnValueExcludeFilter filter2=new SingleColumnValueExcludeFilter(Bytes.toBytes("test"),Bytes.toBytes("test1"),CompareOp.EQUAL, new SubstringComparator("value"));
			//建立scan
			Scan scan=new Scan();
			
			scan.setFilter(filter2);
			//獲取結果並盡心顯示
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
					System.out.println(kv.getValue().toString());
				}
			}
			//釋放資源
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

3、字首過濾器:PrefixFilter(byte[] prefix)

對rowKey的字首進行篩選,字首不符合過濾器條件的行被過濾掉

該過濾器在構造時直接指定字首條件為:

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			
			HTable table=new HTable(conf, tableName);
			//建立字首過濾器
			PrefixFilter filter=new PrefixFilter(Bytes.toBytes("row"));
			Scan scan=new Scan();
			scan.setFilter(filter);
			//獲取結果資料
			ResultScanner rs=table.getScanner(scan);
			//進行資料顯示
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
					System.out.println(Bytes.toString(kv.getValue()));
				}
			}
			//釋放資源
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

4、分頁過濾器:PageFilter(int n)

分頁過濾器,每次只返回從開始的row,個數為n(建構函式中的 n)的連續行的資料。

需要注意的是:分頁過濾器只能返回一次資料,因此如果需要將下一頁的資料返回時,需要重新發送請求,並且需要設定好相應的startRow的值,如果沒有設定startRow的話,其永遠只返回前 n 個數據。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//準備迴圈表 結果
			byte[] endRow=null;
			while(true)
			{
				//建立scan物件
				Scan scan=new Scan();
				//判斷endrow是否為null
				if(endRow!=null)
				{
					byte[] startRow=Bytes.add(endRow,Bytes.toBytes("row-1"));
					scan.setStartRow(startRow);
				}
				//生成過濾器
				PageFilter filter=new PageFilter((long)3);
				scan.setFilter(filter);
				//獲取資料並顯示
				ResultScanner rs=table.getScanner(scan);
				Result result=null;
				int localCount=0;
				while((result=rs.next())!=null)
				{
					localCount++;
					KeyValue[] kvs=result.raw();
					for(KeyValue kv:kvs)
					{
						System.out.println(kv.toString());
						System.out.println(Bytes.toString(kv.getValue()));
					}
					//設定最後的進位制
					endRow=result.getRow();
				}
				//釋放資源
				rs.close();
				//判斷迴圈是否完成
				if(localCount==0)
				{
					table.close();
					break;
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

5、行健過濾器:KeyOnlyFilter

行健和行值需要進行區分:

行值(row):在一行資料中,其row值的是一行中的唯一標示。

行鍵(Key):在HBase底層儲存中,資料都是以KeyValue物件的形式存在,而在KeyValue物件中,Key包含了一個單元格的row、family、qualifier、ts、type 幾個重要的資訊,而Value中只有單元格真是的資料。也就是說Key是包含row的。

該過濾器在進行資料過濾器值返回Key,而不返回Value值。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立過濾器
			KeyOnlyFilter filter=new KeyOnlyFilter();
			Scan scan=new Scan();
			scan.setFilter(filter);
			
			//進行資料查詢返回資料
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				System.out.println("1");
				
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
					System.out.println(Bytes.toString(kv.getValue()));
				}
			}
			//釋放ziyuan
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

6、首次行鍵值過濾器:FirstKeyColumnValueFilter

該過濾器值返回一行中第一個KeyValue物件的Key值,也就是每行只返回一個Key值。因此非常適合使用在一些行數統計上。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立過濾器
			FirstKeyOnlyFilter filter=new FirstKeyOnlyFilter();
			Scan scan=new Scan();
			scan.setFilter(filter);
			//獲取資料並遍歷
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//釋放資源
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

7、包含結果過濾器:InclusiveStopFilter

因為Scan的掃描範圍為左閉右開的,當有時候我們無法判斷指定的endrow的下一個row是什麼,卻要必須要將endrow包含在掃描範圍之內時就可以使用該過濾器,通過該過濾器,scan只需要設定startRow,在過濾器中設定endRow,掃描器就會掃描 [startRow,endRow]這個範圍的資料

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立filter
			InclusiveStopFilter filter=new InclusiveStopFilter(Bytes.toBytes("row-5"));
			Scan scan=new Scan();
			scan.setFilter(filter);
			//獲取資料並沾水
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

8、時間戳過濾器:TimeStampFilter(long timeStamp)

該過濾器主要是用於過濾時間戳的,即符合指定的時間戳是既可以進行返回,因此可以做到細粒度的控制資料返回。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立過濾器
			List<Long> stamps=new ArrayList<>();
			stamps.add(new Long("1457019405362"));
			TimestampsFilter filter=new TimestampsFilter(stamps);
			Scan scan=new Scan();
			scan.setFilter(filter);
			//獲取資料並返回
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//釋放資源
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

9、列計數過濾器:ColumnCountGetFilter(int n)

該過濾器只返回指定的前n個列的資料。超過 n的列的資料不進行返回。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//闖進過濾器
			ColumnCountGetFilter filter=new ColumnCountGetFilter(1);
			Scan scan=new Scan();
			scan.setFilter(filter);
			//獲取資料並返回
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

9、列分頁過濾器:ColumnPaginationFilter(int limit,int off)

該過濾器對列進行分頁,每次返回limit個列,並且從第off個列開始返回。因此建構函式中的兩個數字是用來規定返回的其實位置和返回資料數量的。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立掃描器
			ColumnPaginationFilter filter=new ColumnPaginationFilter(1, 0);
			Scan scan=new Scan();
			scan.setFilter(filter);
			//
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

10、列字首過濾器:ColumnPrefixFilter(byte[] prefix)

該過濾器和字首過濾器很相似,不同的是其過濾物件是針對列的,即列名不符合要求的列中的資料將被過濾掉,不返回到客戶端中。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立掃描器
			ColumnPrefixColumn filter=new ColumnPrefixColumn(Bytes.toBytes("col"));
			Scan scan=new Scan();
			scan.setFilter(filter);
			//
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

11、隨機過濾器:RandomFilter(float chance)

過濾器擁有一個float型別的引數,該引數決定了返回資料的數量:

chance >=1 時,資料全部被返回

0< chance <1 時,按照比例隨機返回資料

chance < 0時,不返回任何資料。

public void example(String tableName)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf, tableName);
			//建立掃描器
			RandomColumn filter=new RandomColumn(0.6f);
			Scan scan=new Scan();
			scan.setFilter(filter);
			//
			ResultScanner rs=table.getScanner(scan);
			Result result=null;
			while((result=rs.next())!=null)
			{
				KeyValue[] kvs=result.raw();
				for(KeyValue kv:kvs)
				{
					System.out.println(kv.toString());
				}
			}
			//
			rs.close();
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

三、總結

過濾器由於剛推出不久,因此在版本變化過程中會出現較大的改變,因此當用戶在使用過濾器時,一定要結合hbase 版本的API文件進行使用。防止出現錯誤使用。因為本文章並沒有對每一個過濾器的詳細的方法進行介紹,因此如果想要進一步瞭解每一個過濾器的作用,請參考HBase 1.1.2 版本的 API進行檢視。