简单认识hbase(上)

1.简介

hbase依赖于hdfs,hbase是一个nosql数据库,是一个非关系型的数据库。支持读写查询操作等等。hdfs对随机读写不是支持的太良好,hbase是一个数据库,支持随机读写。

hbase当中所有的数据都是byte[]

HBase中的表一般有这样的特点:

  • 大:一个表可以有上十亿行,上百万列

  • 面向列:面向列(族)的存储和权限控制,列(族)独立检索。

  • 稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。

2.特征简要
1.海量存储

Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正式因为Hbase良好的扩展性,才为海量数据的存储提供了便利。

2.列式存储

这里的列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。

3.极易扩展

Hbase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。
通过横向添加RegionSever的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbsae服务更多Region的能力。

备注:RegionServer的作用是管理region、承接业务的访问,这个后面会详细的介绍通过横向添加Datanode的机器,进行存储层扩容,提升Hbase的数据存储能力和提升后端存储的读写能力。

4. 高并发

由于目前大部分使用Hbase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。

5.稀疏

稀疏主要是针对Hbase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。

3.基础架构
1.HBase的数据存储架构:

主节点:HMaster

​ 监控regionServer的健康状态

​ 处理regionServer的故障转移

​ 处理元数据变更

​ 处理region的分配或者移除

​ 空闲时间做数据的负载均衡

从节点:HRegionServer

​ 负责存储HBase的实际数据

​ 处理分配给他的region

​ 刷新缓存的数据到HDFS上面去

​ 维护HLog

​ 执行数据的压缩

​ 负责处理region的分片

1个HRegionServer = 1个HLog + n个region

1个region = n个store模块

1个store模块 = 1个memoryStore + n个storeFile

HLog:hbase当中预写日志模块,write ahead log

2.HBase的表模型

rowKey:行键,每一条数据都是使用行键来进行唯一标识的

columnFamily:列族。列族下面可以有很多列

column:列的概念。每一个列都必须归属于某一个列族

timestamp:时间戳,每条数据都会有时间戳的概念

versionNum:版本号,每条数据都会有版本号,每次数据变化,版本号都会进行更新

创建一张HBase表最少需要两个条件:表名 + 列族名

注意:rowkey是我们在插入数据的时候自己指定的,
列名也是在我们插入数据的时候动态指定的,时间戳是插入数据的时候,系统自动帮我们生成的,versionNum是系统自动维护的

4.集群环境搭建
1.下载安装包
http://archive.apache.org/dist/hbase/2.0.0/hbase-2.0.0-bin.tar.gz
2.解压
tar -zxf hbase-2.0.0-bin.tar.gz -C /export/servers/
3.修改配置文件
3.1 第一个配置文件
cd /export/servers/hbase-2.0.0/conf
vim hbase-env.sh
写入修改
export JAVA_HOME=自己的jdk地址(可以用echo $JAVA_HOME查询)
export HBASE_MANAGES_ZK=false

3.2 第二个配置文件
vim hbase-site.xml
写入
<configuration>
        <property>
                <name>hbase.rootdir</name>
                <value>hdfs://node-1:8020/hbase</value>  
        </property>

        <property>
                <name>hbase.cluster.distributed</name>
                <value>true</value>
        </property>

   <!-- 0.98后的新变动,之前版本没有.port,默认端口为60000 -->
        <property>
                <name>hbase.master.port</name>
                <value>16000</value>
        </property>

        <property>
                <name>hbase.zookeeper.quorum</name>
                <value>node-1:2181,node-2:2181,node-3:2181</value>
        </property>

        <property>
                <name>hbase.zookeeper.property.dataDir</name>
         <value>/export/servers/zookeeper-3.4.9/zkdatas</value>
        </property>
</configuration>
3.3第三个文件
vim regionservers 
写入
node-1
node-2
node-3

3.4第四个文件
vim backup-masters
写入
node-2
4.分发给其它服务器
scp -r hbase-2.0.0/ node-2:$PWD
scp -r hbase-2.0.0/ node-3:$PWD
5.创建软连接
ln -s /export/servers/hadoop-2.7.5/etc/hadoop/core-site.xml /export/servers/hbase-2.0.0/conf/core-site.xml
ln -s /export/servers/hadoop-2.7.5/etc/hadoop/hdfs-site.xml /export/servers/hbase-2.0.0/conf/hdfs-site.xml

6.三台机器添加HBASE_HOME的环境变量
vim /etc/profile
export HBASE_HOME=/export/servers/hbase-2.0.0
export PATH=:$HBASE_HOME/bin:$PATH

编辑完后执行
source /etc/profile
7.HBase集群启动
cd /export/servers/hbase-2.0.0
bin/start-hbase.sh


另外一种启动方式:
我们也可以执行以下命令单节点进行启动
启动HMaster命令
bin/hbase-daemon.sh start master
启动HRegionServer命令
bin/hbase-daemon.sh start regionserver

8.页面访问
http://node-1:16010/master-status
7.常用shell
1.进入HBase客户端命令操作界面
cd /export/servers/hbase-2.0.0
bin/hbase shell //启动
 bin/stop-hbase.sh 停止
2.查看帮助命令
hbase(main):001:0> help
3.查看当前数据库中有哪些表
hbase(main):002:0> list
4.创建一张表
创建user表,包含info、data两个列族
hbase(main):010:0> create 'user', 'info', 'data'
或者
hbase(main):010:0> create 'user', {NAME => 'info', VERSIONS => '3'},{NAME => 'data'}

5.java开发
package cn.test.hbaseDemo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CompareOperator;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.FamilyFilter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.PageFilter;
import org.apache.hadoop.hbase.filter.PrefixFilter;
import org.apache.hadoop.hbase.filter.QualifierFilter;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HbaseDemo {
	// 创建表
	@Test
	public void createTable() throws IOException {
		// 连接hbase集群
		Configuration conf = HBaseConfiguration.create();
		// 指定hbasedezk连接地址
		conf.set("hbase.zookeeper.quorum", "node-1:2181,node-2:2181,node-3:2181");
		Connection conn = ConnectionFactory.createConnection(conf);

		// 获取管理员对象
		Admin admin = conn.getAdmin();

		// 通过管理员对象创建表
		HTableDescriptor desc = new HTableDescriptor(TableName.valueOf("myuser"));
		HColumnDescriptor f1 = new HColumnDescriptor("f1");
		HColumnDescriptor f2 = new HColumnDescriptor("f2");
		desc.addFamily(f1);
		desc.addFamily(f2);
		admin.createTable(desc);

		admin.close();
		conn.close();

	}

	// 添加数据
	@Test
	public void createData() throws IOException {
		// 连接hbase集群
		Configuration conf = HBaseConfiguration.create();
		// 指定hbasedezk连接地址
		conf.set("hbase.zookeeper.quorum", "node-1:2181,node-2:2181,node-3:2181");
		Connection conn = ConnectionFactory.createConnection(conf);

		// 获取表对象
		Table myuser = conn.getTable(TableName.valueOf("myuser"));

		// 通过管理员对象创建表
		Put put = new Put("0001".getBytes());
		put.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(1));
		put.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("张三"));
		put.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(18));
		put.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("火星"));
		put.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("12545857814"));

		myuser.put(put);

		// 关闭
		myuser.close();
		conn.close();

	}

	@Test
	public void insertBatchData() throws IOException {

		// 获取连接
		Configuration configuration = HBaseConfiguration.create();
		configuration.set("hbase.zookeeper.quorum", "node-1:2181,node-2:2181");
		Connection connection = ConnectionFactory.createConnection(configuration);
		// 获取表
		Table myuser = connection.getTable(TableName.valueOf("myuser"));
		// 创建put对象,并指定rowkey
		Put put = new Put("0002".getBytes());
		put.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(1));
		put.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("曹操"));
		put.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(30));
		put.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("沛国谯县"));
		put.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("16888888888"));
		put.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("helloworld"));

		Put put2 = new Put("0003".getBytes());
		put2.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(2));
		put2.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("刘备"));
		put2.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(32));
		put2.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put2.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("幽州涿郡涿县"));
		put2.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("17888888888"));
		put2.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("talk is cheap , show me the code"));

		Put put3 = new Put("0004".getBytes());
		put3.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(3));
		put3.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("孙权"));
		put3.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(35));
		put3.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put3.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("下邳"));
		put3.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("12888888888"));
		put3.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("what are you 弄啥嘞!"));

		Put put4 = new Put("0005".getBytes());
		put4.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(4));
		put4.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("诸葛亮"));
		put4.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(28));
		put4.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put4.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("四川隆中"));
		put4.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("14888888888"));
		put4.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("出师表你背了嘛"));

		Put put5 = new Put("0005".getBytes());
		put5.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(5));
		put5.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("司马懿"));
		put5.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(27));
		put5.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put5.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("哪里人有待考究"));
		put5.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("15888888888"));
		put5.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("跟诸葛亮死掐"));

		Put put6 = new Put("0006".getBytes());
		put6.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(5));
		put6.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("xiaobubu—吕布"));
		put6.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(28));
		put6.addColumn("f2".getBytes(), "sex".getBytes(), Bytes.toBytes("1"));
		put6.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("内蒙人"));
		put6.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("15788888888"));
		put6.addColumn("f2".getBytes(), "say".getBytes(), Bytes.toBytes("貂蝉去哪了"));

		List<Put> listPut = new ArrayList<Put>();
		listPut.add(put);
		listPut.add(put2);
		listPut.add(put3);
		listPut.add(put4);
		listPut.add(put5);
		listPut.add(put6);

		myuser.put(listPut);
		myuser.close();
	}

	Configuration conf;
	Connection conn;
	Table myuser;

	// 连接初始化
	@Before
	public void initTable() throws IOException {
		conf = HBaseConfiguration.create();
		// 指定hbasedezk连接地址
		conf.set("hbase.zookeeper.quorum", "node-1:2181,node-2:2181,node-3:2181");
		conn = ConnectionFactory.createConnection(conf);
		myuser = conn.getTable(TableName.valueOf("myuser"));
		// 获取表对象

	}

	// 关闭连接
	@After
	public void closeTable() throws IOException {
		myuser.close();
		conn.close();
	}

	// 查询
	@Test
	public void getData() throws IOException {
		// 查询rowkey为0003的人,所有的列
		Get get = new Get("0003".getBytes());
		// 只查询f1列族的值,不加查询所有
		get.addFamily("f1".getBytes());
		// 只查询f1下id列
		get.addColumn("f1".getBytes(), "id".getBytes());
		// result封装了所有的结果数据
		Result result = myuser.get(get);
		// 获取0003这条数据的所有cell值
		List<Cell> cells = result.listCells();
		for (Cell cell : cells) {
			// 获取列族的名称
			String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
			// 获取列的名称
			String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
					cell.getQualifierLength());
			// 获取值
			if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
				int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

				System.out.println("列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
			} else {
				String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

				System.out.println("列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
			}

		}

	}

	// 按照rowkey扫描,范围是0004-0006
	@Test
	public void scanRange() throws IOException {
		Scan scan = new Scan();
		// 设置起始结束的rowkey,包括0004,不包括0006 ,注释掉,全表扫描
		// scan.setStartRow("0004".getBytes());
		// scan.setStopRow("0006".getBytes());
		// 返回的多条结果集封装在scanner
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}
	}

	// 比较过滤器
	// 过滤器 rowFilter,查询rowkey比0003小
	@Test
	public void rowFilter() throws IOException {
		Scan scan = new Scan();
		// 查询rowkey比0003小
		RowFilter rowFilter = new RowFilter(CompareOperator.LESS, new BinaryComparator(Bytes.toBytes("0003")));
		scan.setFilter(rowFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 列族过滤器 familyFilter,查询比f2小的列族
	@Test
	public void familyFilter() throws IOException {
		Scan scan = new Scan();
		// 查询比f2小的列族
		FamilyFilter familyFilter = new FamilyFilter(CompareOperator.LESS, new SubstringComparator("f2"));
		scan.setFilter(familyFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 列的过滤器 qualifierFilter,只获取name这一列的值
	@Test
	public void qualifierFilter() throws IOException {
		Scan scan = new Scan();
		// 查询比f2小的列族
		QualifierFilter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL, new SubstringComparator("name"));
		scan.setFilter(qualifierFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 值的过滤器 valueFilter,只获取value包含8的数据
	@Test
	public void valueFilter() throws IOException {
		Scan scan = new Scan();
		// 查询比f2小的列族
		ValueFilter valueFilter = new ValueFilter(CompareOperator.EQUAL, new SubstringComparator("8"));
		scan.setFilter(valueFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 专用过滤器
	// 单列值过滤器 SingleColumnValueFilter
	@Test
	public void singleColumnValueFilter() throws IOException {
		Scan scan = new Scan();
		// 查询name值为 刘备 的数据
		SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("f1".getBytes(),
				"name".getBytes(), CompareOperator.EQUAL, "刘备".getBytes());
		scan.setFilter(singleColumnValueFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// rowkey前缀过滤器PrefixFilter
	@Test
	public void prefixFilter() throws IOException {
		Scan scan = new Scan();
		// 查询以00开头的所有前缀的rowkey
		PrefixFilter prefixFilter = new PrefixFilter("00".getBytes());
		scan.setFilter(prefixFilter);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 实现hbase的分页功能
	// 分页过滤器PageFilter
	@Test
	public void hbasePage() throws IOException {
		int pageNum = 3;
		int pageSize = 2;
		if (pageNum == 1) {
			String startRowKey = "";
			Scan scan = new Scan();
			// 如果查询第一页,按照空来扫描
			scan.withStartRow("".getBytes());
			PageFilter pageFilter = new PageFilter(pageSize);
			scan.setFilter(pageFilter);
			ResultScanner scanner = myuser.getScanner(scan);
			for (Result result : scanner) {
				byte[] row = result.getRow();
				startRowKey = new String(row);
			}
		} else {
			String startRowKey = "";
			Scan scan = new Scan();
			// 计算前两页的最后一条,再加上一条,就是第三页的起始rowkey
			scan.withStartRow("".getBytes());
			PageFilter pageFilter = new PageFilter((pageNum - 1) * pageSize + 1);
			scan.setFilter(pageFilter);
			ResultScanner scanner = myuser.getScanner(scan);
			for (Result result : scanner) {
				byte[] row = result.getRow();
				startRowKey = new String(row);
			}
			// 获取第三页的数据
			scan.withStartRow(startRowKey.getBytes());
			PageFilter pageFilter1 = new PageFilter(pageSize);
			scan.setFilter(pageFilter1);
			ResultScanner scanner1 = myuser.getScanner(scan);
			for (Result result : scanner1) {
				byte[] row = result.getRow();
				startRowKey = new String(row);
				System.out.println(startRowKey);
			}
		}
	}

//	/多过滤器综合查询FilterList
	@Test
	public void filterList() throws IOException {
		// 使用SingleColumnValueFilter查询f1列族,name为刘备的数据,并且同时满足rowkey的前缀以00开头的数据(PrefixFilter)
		SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("f1".getBytes(),
				"name".getBytes(), CompareOperator.EQUAL, "刘备".getBytes());
		PrefixFilter prefixFilter = new PrefixFilter("00".getBytes());
		FilterList filterList = new FilterList(singleColumnValueFilter, prefixFilter);
		Scan scan = new Scan();
		// 查询以00开头的所有前缀的rowkey
		scan.setFilter(filterList);
		ResultScanner scanner = myuser.getScanner(scan);
		for (Result result : scanner) {
			List<Cell> cells = result.listCells();
			for (Cell cell : cells) {
				// 获取rowkey
				String rowkey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
				// 获取列族的名称
				String familyName = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(),
						cell.getFamilyLength());
				// 获取列的名称
				String columnName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(),
						cell.getQualifierLength());
				// 获取值
				if ((familyName.equals("f1") && columnName.equals("id")) || columnName.equals("age")) {
					int value = Bytes.toInt(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				} else {
					String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());

					System.out
							.println("rowkey:" + rowkey + ";列族名:" + familyName + ";列名:" + columnName + ";列值:" + value);
				}

			}
		}

	}

	// 删除数据,根据rowkey删除某条记录
	@Test
	public void delDate() throws IOException {
		Delete delete = new Delete("0006".getBytes());
		myuser.delete(delete);
	}

	// 删除表
	@Test
	public void delTable() throws IOException {
		Admin admin = conn.getAdmin();
		// 禁用表
		admin.disableTable(TableName.valueOf("myuser"));
		// 删除表
		admin.deleteTable(TableName.valueOf("myuser"));
		admin.close();
	}

	//更新数据,和插入一样,如果rowkey存在,更新.如果不存在插入
	@Test
	public void updateDate() throws IOException {
		Put put = new Put("0001".getBytes());
		put.addColumn("f1".getBytes(), "id".getBytes(), Bytes.toBytes(1));
		put.addColumn("f1".getBytes(), "name".getBytes(), Bytes.toBytes("法外狂徒"));
		put.addColumn("f1".getBytes(), "age".getBytes(), Bytes.toBytes(18));
		put.addColumn("f2".getBytes(), "address".getBytes(), Bytes.toBytes("火星"));
		put.addColumn("f2".getBytes(), "phone".getBytes(), Bytes.toBytes("12545857814"));

		myuser.put(put);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值