欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hbase的过滤器

程序员文章站 2022-05-23 08:37:05
...

hbase的过滤器

1.概述

hbase的API中可以进行查询,但是这种查询一般只能单行或者是指定行键的范围的查询,在正常需要精细查询的场合有诸多的不便,所以系统内置了很多的过滤器

2.过滤器汇总

过滤器分为两大类:比较过滤器和专用过滤器

3.比较过滤器

  • 行键过滤器 RowFilter

Filter filter1 = new RowFilter(CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes(“row-22”)));
scan.setFilter(filter1);

  • 列族过滤器 FamilyFilter

Filter filter1 = new FamilyFilter(CompareFilter.CompareOp.LESS, new BinaryComparator(Bytes.toBytes(“colfam3”)));
scan.setFilter(filter1);

  • 列过滤器 QualifierFilter

Filter filter = new QualifierFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes(“col-2”)));

  • 值过滤器 ValueFilter

Filter filter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator(".4") );

这些过滤器的的构造方法中都有两个参数都是干什么的呢
下边根据FamilyFilter的源码进行分析

 /**
   * Constructor.
   *
   * @param familyCompareOp  the compare op for column family matching
   * @param familyComparator the comparator for column family matching
   */
  public FamilyFilter(final CompareOp familyCompareOp,
                      final ByteArrayComparable familyComparator) {
      super(familyCompareOp, familyComparator);
  }

参数1 是过滤器的比较的运算符CompareOp这是一个枚举类

  public enum CompareOp {
    /** less than也就是小于 */
    LESS,
    /** less than or equal to 小于等于*/
    LESS_OR_EQUAL,
    /** equals等于 */
    EQUAL,
    /** not equal不等于 */
    NOT_EQUAL,
    /** greater than or equal to大于等于 */
    GREATER_OR_EQUAL,
    /** greater than 大于*/
    GREATER,
    /** no operation排除所有 */
    NO_OP,
  }

参数2 是代表过滤器的比较的机制 ByteArrayComparable这是一个抽象类,看看他的实现类列表
hbase的过滤器
hbase的过滤器
下边结合几个例子来学习一下比较过滤器

public class HbaseFilter {
	static private Configuration conf = null;
	static private Connection conn = null;
	static private HTable table = null;
	static {
		// 建立连接
		try {
			// 创建配置文件的对象
			conf = HBaseConfiguration.create();
			// 设置zk
			conf.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
			Connection conn = ConnectionFactory.createConnection(conf);
			TableName tableName = TableName.valueOf("user_info");
			table = (HTable) conn.getTable(tableName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
//列簇过滤器的使用
	@Test
	public void test() throws IOException {
		//封装一个查询的对象
		Scan scan=new Scan();
		//创建一个过滤器的对象
		//参数1 是比较的规则  参数2 是指定比较的机制  BinaryComparator按照字节索引顺序比较
		//这样只能查询出列簇是base-info的数据
		Filter f=new FamilyFilter(CompareOp.EQUAL, new BinaryComparator("base_info".getBytes()));
		scan.setFilter(f);
		ResultScanner scanner = table.getScanner(scan);
		Iterator<Result> it = scanner.iterator();
		while(it.hasNext()) {
			Result result = it.next();
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
				System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
				System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
				System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
				System.out.println();
			}
		}
		
	}
	@Test
	public void test0() throws IOException {
		//封装一个查询的对象
		Scan scan=new Scan();
		//创建一个过滤器的对象
		//参数1 是比较的规则  参数2 是指定比较的机制
		//查询列簇中包含base子串的列簇的数据
		//Filter f=new FamilyFilter(CompareOp.EQUAL, new SubstringComparator("base"));
		//设计一个正则的比较机制的过滤器  查询列簇中以ex开头的列簇的数据
		Filter f=new FamilyFilter(CompareOp.EQUAL,new RegexStringComparator("ex.*$"));
		scan.setFilter(f);
		ResultScanner scanner = table.getScanner(scan);
		Iterator<Result> it = scanner.iterator();
		while(it.hasNext()) {
			Result result = it.next();
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
				System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
				System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
				System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
				System.out.println();
			}
		}
		
	}
	//行键过滤器的使用
		@Test
		public void test1() throws IOException {
			Scan scan =new Scan();
			//查询行键大于baiyc_20150716_0007的所有的内容
			RowFilter f=new RowFilter(CompareOp.GREATER, new BinaryComparator("baiyc_20150716_0007".getBytes()));
			scan.setFilter(f);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}
	//列过滤器的使用  
		@Test
		public void test2() throws IOException {
			Scan scan =new Scan();
			//查询所有的name的列
			QualifierFilter f=new QualifierFilter(CompareOp.EQUAL, new BinaryComparator("name".getBytes()));
			scan.setFilter(f);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}
		//列值和列名过滤器多过滤器的联合使用  
		@Test
		public void test3() throws IOException {
			Scan scan =new Scan();
			//设置一个列的过滤器专门过滤age列
			QualifierFilter f1=new QualifierFilter(CompareOp.EQUAL, new BinaryComparator("age".getBytes()));
			//设置一个value的过滤器转么过滤年龄大于等于25岁de
			ValueFilter f2 = new ValueFilter(CompareOp.GREATER_OR_EQUAL, new BinaryComparator("25".getBytes()));
			//闯将filterList的对象
			FilterList filterList = new FilterList(Operator.MUST_PASS_ALL, f1,f2);
			scan.setFilter(filterList);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}
		
}

4.专用过滤器

单列值过滤器 SingleColumnValueFilter ----会返回满足条件的整行

SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes(“colfam1”),
Bytes.toBytes(“col-5”),CompareFilter.CompareOp.NOT_EQUAL,new SubstringComparator(“val-5”));
filter.setFilterIfMissing(true); //如果不设置为 true,则那些不包含指定 column 的行也会返回
scan.setFilter(filter1);

单列值排除器 SingleColumnValueExcludeFilter -----返回排除了该列的结果 与上面的结果相反

前缀过滤器 PrefixFilter----针对行键

Filter filter = new PrefixFilter(Bytes.toBytes(“row1”));
scan.setFilter(filter1);

列前缀过滤器 ColumnPrefixFilter
Filter filter = new ColumnPrefixFilter(Bytes.toBytes(“qual2”));
scan.setFilter(filter1);

分页过滤器 PageFilter

例子

  • 单列值过滤器(查出age==25的所有的行的所有的信息)
		//单列的过滤器
		@Test
		public void test4() throws IOException {
			Scan scan =new Scan();
			//设置一个列的过滤器专门过滤age列
			SingleColumnValueFilter f = new SingleColumnValueFilter("base_info".getBytes(), "age".getBytes(), CompareOp.EQUAL, "25".getBytes());
			scan.setFilter(f);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}

结果如下:
baiyc_20150716_0005 base_info age 25
baiyc_20150716_0005 base_info name baiyc5
baiyc_20150716_0005 extra_info Hobbies music
rk0001 base_info name zhangsan
user0001 base_info name zhangsan1
zhangsan_20150701_0005 base_info age 25
zhangsan_20150701_0005 base_info name zhangsan5
zhangsan_20150701_0005 extra_info Hobbies music

通过这个例子可以看到查询到了锁有的年龄是25的人的所有的信息

  • 单列值排除器 SingleColumnValueExcludeFilter
    查询年龄是25的所有的人 但是不打印年龄的信息
	//单列值排他过滤器
		@Test
		public void test4() throws IOException {
			Scan scan =new Scan();
			//设置一个列的过滤器专门过滤age列
			SingleColumnValueFilter f = new SingleColumnValueExcludeFilter("base_info".getBytes(), "age".getBytes(), CompareOp.EQUAL, "25".getBytes());
			scan.setFilter(f);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}

结果如下:
baiyc_20150716_0005 base_info name baiyc5
baiyc_20150716_0005 extra_info Hobbies music
rk0001 base_info name zhangsan
user0001 base_info name zhangsan1
zhangsan_20150701_0005 base_info name zhangsan5
zhangsan_20150701_0005 extra_info Hobbies music
通过结果和上一个例子进行比较,找到的人是一样的,就是没有打印出年龄而已

  • 列前缀过滤器(过滤出以a开头的列名的的列的所有的值)
	//列前缀过滤器
		@Test
		public void test5() throws IOException {
			Scan scan =new Scan();
			//设置一个列的过滤器专门过滤age列
			ColumnPrefixFilter f = new ColumnPrefixFilter("a".getBytes());
			scan.setFilter(f);
			ResultScanner scanner = table.getScanner(scan);
			Iterator<Result> it = scanner.iterator();
			while(it.hasNext()) {
				Result result = it.next();
				List<Cell> cells = result.listCells();
				for (Cell cell : cells) {
					System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
					System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
					System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
					System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
					System.out.println();
				}
			}
		}

结果如下:
baiyc_20150716_0001 base_info age 21
baiyc_20150716_0002 base_info age 22
baiyc_20150716_0003 base_info age 23
baiyc_20150716_0004 base_info age 24
baiyc_20150716_0005 base_info age 25
baiyc_20150716_0006 base_info age 26
baiyc_20150716_0007 base_info age 27
baiyc_20150716_0008 base_info age 28
user0000 base_info age 18
zhangsan_20150701_0001 base_info age 21
zhangsan_20150701_0002 base_info age 22
zhangsan_20150701_0003 base_info age 23
zhangsan_20150701_0004 base_info age 24
zhangsan_20150701_0005 base_info age 25
zhangsan_20150701_0006 base_info age 26
zhangsan_20150701_0007 base_info age 27
zhangsan_20150701_0008 base_info age 28

将age列的所有的信息查询出来了

  • 前缀过滤器 PrefixFilter(查询行键中以zhang开头的行键的所有的信息)
	//行键前缀过滤器
				@Test
				public void test6() throws IOException {
					Scan scan =new Scan();
					//设置一个列的过滤器专门过滤age列
					Filter f = new PrefixFilter("zhang".getBytes());
					scan.setFilter(f);
					ResultScanner scanner = table.getScanner(scan);
					Iterator<Result> it = scanner.iterator();
					while(it.hasNext()) {
						Result result = it.next();
						List<Cell> cells = result.listCells();
						for (Cell cell : cells) {
							System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
							System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
							System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
							System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
							System.out.println();
						}
					}
				}

结果如下:

zhangsan_20150701_0001 base_info age 21
zhangsan_20150701_0001 base_info name zhangsan1
zhangsan_20150701_0001 extra_info Hobbies music
zhangsan_20150701_0002 base_info age 22
zhangsan_20150701_0002 base_info name zhangsan2
zhangsan_20150701_0002 extra_info Hobbies sport
zhangsan_20150701_0003 base_info age 23
zhangsan_20150701_0003 base_info name zhangsan3
zhangsan_20150701_0003 extra_info Hobbies music
zhangsan_20150701_0004 base_info age 24
zhangsan_20150701_0004 base_info name zhangsan4
zhangsan_20150701_0004 extra_info Hobbies sport
zhangsan_20150701_0005 base_info age 25
zhangsan_20150701_0005 base_info name zhangsan5
zhangsan_20150701_0005 extra_info Hobbies music
zhangsan_20150701_0006 base_info age 26
zhangsan_20150701_0006 base_info name zhangsan6
zhangsan_20150701_0006 extra_info Hobbies sport
zhangsan_20150701_0007 base_info age 27
zhangsan_20150701_0007 base_info name zhangsan7
zhangsan_20150701_0007 extra_info Hobbies music
zhangsan_20150701_0008 base_info age 28
zhangsan_20150701_0008 base_info name zhangsan8
通过结果可以看出 将所有的以"zhang"开头的行键的信息查询出来了

  • 分页过滤器
    设置一个分页的过滤器,每页显示5行数据
//分页过滤器
@Test
public void test7() throws IOException {
	Scan scan =new Scan();
	//设置分页的过滤器 每页显示5行数据
	PageFilter f = new PageFilter(5);
	scan.setFilter(f);
	ResultScanner scanner = table.getScanner(scan);
	Iterator<Result> it = scanner.iterator();
	while(it.hasNext()) {
		Result result = it.next();
		List<Cell> cells = result.listCells();
		for (Cell cell : cells) {
			System.out.print(new String(CellUtil.cloneRow(cell))+"\t");
			System.out.print(new String(CellUtil.cloneFamily(cell))+"\t");
			System.out.print(new String(CellUtil.cloneQualifier(cell))+"\t");
			System.out.print(new String(CellUtil.cloneValue(cell))+"\t");
			System.out.println();
		}
	}
}

输出结果如下
baiyc_20150716_0001 base_info age 21
baiyc_20150716_0001 base_info name baiyc1
baiyc_20150716_0001 extra_info Hobbies music
baiyc_20150716_0002 base_info age 22
baiyc_20150716_0002 base_info name baiyc2
baiyc_20150716_0002 extra_info Hobbies sport
baiyc_20150716_0003 base_info age 23
baiyc_20150716_0003 base_info name baiyc3
baiyc_20150716_0003 extra_info Hobbies music
baiyc_20150716_0004 base_info age 24
baiyc_20150716_0004 base_info name baiyc4
baiyc_20150716_0004 extra_info Hobbies sport
baiyc_20150716_0005 base_info age 25
baiyc_20150716_0005 base_info name baiyc5
baiyc_20150716_0005 extra_info Hobbies music
结果显示了5个行键的数据,分页成功,
但是这样分页只能显示出第一页的数据,nname如何才可以显示任意页数呢

有这样一个要求,根据用户的输入页码和每页显示的条数显示出指定的内容,就用user_info这张表来实现

public class Testpagefilter {
	public static void main(String[] args) {
		ResultScanner pageCut = pageCut(3, 3);
		Iterator<Result> it = pageCut.iterator();
		while (it.hasNext()) {
			Result next = it.next();
			List<Cell> cells = next.listCells();
			for (Cell cell : cells) {
				System.out.print(new String(CellUtil.cloneRow(cell)) + "\t");
				System.out.print(new String(CellUtil.cloneFamily(cell)) + "\t");
				System.out.print(new String(CellUtil.cloneQualifier(cell)) + "\t");
				System.out.print(new String(CellUtil.cloneValue(cell)) + "\t");
				System.out.println();
			}
		}
	}

//设计一个方法,根据用户输入的页码和每一页显示的数目进行显示
	/**
	 * 
	 * @param pagesize 每一页显示的条数
	 * @param count    显示第几页 从第一页开始
	 * @return 返回多行的结果集
	 */
	public static ResultScanner pageCut(int pagesize, int count) {
		ResultScanner scanner = null;
		if(pagesize<=0) {
			//每页至少有一条
			pagesize=1;
		}
		if(count<=0) {
			// 从第一页开始
			count=1;
		}
		try {
			Configuration conf = HBaseConfiguration.create();
			// 设置zk
			conf.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
			Connection conn = ConnectionFactory.createConnection(conf);
			TableName tableName = TableName.valueOf("user_info");
			Table table = (HTable) conn.getTable(tableName);
			//创建分页过滤器,指定每页的行数
			PageFilter pageFilter = new PageFilter(pagesize);
			Scan scan = new Scan();
			scan.setFilter(pageFilter);
			int num = 1;
			//当页码小于规定的值得时候进入循环,遍历取出最后一个行键,将最后一个行键加上一个"\001"作为下一次分页的起始行键,
			//如果没有这个行键就取比他大的行键作为起始行键"\001"代表大一点点,计算机底层的一个位
			while (num <count) {
				scanner = table.getScanner(scan);
				Iterator<Result> it = scanner.iterator();
				byte[] row = null;
				while (it.hasNext()) {
					Result result = it.next();
					row = result.getRow();
				}
				//找到每页的最后一个行键,加上一个特别小的数作为下一个分页的开始
				scan.setStartRow((new String(row)+"\001").getBytes());
				//进行最后一次的分页,注意这个scanner的对象这里千万不能使用迭代器,这里使用迭代器之后返回值就不能再使用迭代齐了
				//会造成无法输出
				scanner = table.getScanner(scan);
				num++;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return scanner;
	}
}

运行结果:
baiyc_20150716_0007 base_info age 27
baiyc_20150716_0007 base_info name baiyc7
baiyc_20150716_0007 extra_info Hobbies music
baiyc_20150716_0008 base_info age 28
baiyc_20150716_0008 base_info name baiyc8
baiyc_20150716_0008 extra_info Hobbies sport
rk0001 base_info name zhangsan

通过运行结果可以看出输出了第三页的内容

**

hbase中的user_info的数据如下

**
baiyc_20150716_0001 column=base_info:age, timestamp=1559098923727, value=21
baiyc_20150716_0001 column=base_info:name, timestamp=1559098922536, value=baiyc1
baiyc_20150716_0001 column=extra_info:Hobbies, timestamp=1559098925248, value=music
baiyc_20150716_0002 column=base_info:age, timestamp=1559098923899, value=22
baiyc_20150716_0002 column=base_info:name, timestamp=1559098922677, value=baiyc2
baiyc_20150716_0002 column=extra_info:Hobbies, timestamp=1559098925396, value=sport
baiyc_20150716_0003 column=base_info:age, timestamp=1559098924045, value=23
baiyc_20150716_0003 column=base_info:name, timestamp=1559098922856, value=baiyc3
baiyc_20150716_0003 column=extra_info:Hobbies, timestamp=1559098925524, value=music
baiyc_20150716_0004 column=base_info:age, timestamp=1559098924176, value=24
baiyc_20150716_0004 column=base_info:name, timestamp=1559098923008, value=baiyc4
baiyc_20150716_0004 column=extra_info:Hobbies, timestamp=1559098925673, value=sport
baiyc_20150716_0005 column=base_info:age, timestamp=1559098924356, value=25
baiyc_20150716_0005 column=base_info:name, timestamp=1559098923175, value=baiyc5
baiyc_20150716_0005 column=extra_info:Hobbies, timestamp=1559098925778, value=music
baiyc_20150716_0006 column=base_info:age, timestamp=1559098924839, value=26
baiyc_20150716_0006 column=base_info:name, timestamp=1559098923301, value=baiyc6
baiyc_20150716_0006 column=extra_info:Hobbies, timestamp=1559098925898, value=sport
baiyc_20150716_0007 column=base_info:age, timestamp=1559098924997, value=27
baiyc_20150716_0007 column=base_info:name, timestamp=1559098923438, value=baiyc7
baiyc_20150716_0007 column=extra_info:Hobbies, timestamp=1559098925954, value=music
baiyc_20150716_0008 column=base_info:age, timestamp=1559098925132, value=28
baiyc_20150716_0008 column=base_info:name, timestamp=1559098923570, value=baiyc8
baiyc_20150716_0008 column=extra_info:Hobbies, timestamp=1559098927723, value=sport
rk0001 column=base_info:name, timestamp=1559098940985, value=zhangsan
user0000 column=base_info:age, timestamp=1559098810355, value=18
user0000 column=base_info:gender, timestamp=1559098810512, value=female
user0000 column=base_info:name, timestamp=1559098810155, value=luoyufeng
user0000 column=extra_info:size, timestamp=1559098825877, value=34
user0001 column=base_info:name, timestamp=1559098837152, value=zhangsan1
zhangsan_20150701_0001 column=base_info:age, timestamp=1559098919139, value=21
zhangsan_20150701_0001 column=base_info:name, timestamp=1559098837291, value=zhangsan1
zhangsan_20150701_0001 column=extra_info:Hobbies, timestamp=1559098920946, value=music
zhangsan_20150701_0002 column=base_info:age, timestamp=1559098919522, value=22
zhangsan_20150701_0002 column=base_info:name, timestamp=1559098837458, value=zhangsan2
zhangsan_20150701_0002 column=extra_info:Hobbies, timestamp=1559098921133, value=sport
zhangsan_20150701_0003 column=base_info:age, timestamp=1559098919915, value=23
zhangsan_20150701_0003 column=base_info:name, timestamp=1559098837744, value=zhangsan3
zhangsan_20150701_0003 column=extra_info:Hobbies, timestamp=1559098921300, value=music
zhangsan_20150701_0004 column=base_info:age, timestamp=1559098920096, value=24
zhangsan_20150701_0004 column=base_info:name, timestamp=1559098838083, value=zhangsan4
zhangsan_20150701_0004 column=extra_info:Hobbies, timestamp=1559098921640, value=sport
zhangsan_20150701_0005 column=base_info:age, timestamp=1559098920288, value=25
zhangsan_20150701_0005 column=base_info:name, timestamp=1559098838237, value=zhangsan5
zhangsan_20150701_0005 column=extra_info:Hobbies, timestamp=1559098921866, value=music
zhangsan_20150701_0006 column=base_info:age, timestamp=1559098920456, value=26
zhangsan_20150701_0006 column=base_info:name, timestamp=1559098838431, value=zhangsan6
zhangsan_20150701_0006 column=extra_info:Hobbies, timestamp=1559098922014, value=sport
zhangsan_20150701_0007 column=base_info:age, timestamp=1559098920622, value=27
zhangsan_20150701_0007 column=base_info:name, timestamp=1559098838602, value=zhangsan7
zhangsan_20150701_0007 column=extra_info:Hobbies, timestamp=1559098922228, value=music
zhangsan_20150701_0008 column=base_info:age, timestamp=1559098920792, value=28
zhangsan_20150701_0008 column=base_info:name, timestamp=1559098902687, value=zhangsan8