HBase学习笔记

HBase

1. 简介

  • HBase是Hadoop Database,是一个分布式的、可扩展的大数据存储仓库。
  • 当需要随机访问数据、实时的读写数据时使用。
  • HBase是No-SQL数据库。

2. 工作机制

读写流程

HMaster, HRegionServer

两个特殊的表

  • -ROOT- : 记录了.META.表的Region信息,-ROOT-只有一个region,其location记录在ZooKeeper中(该表已废弃,仅存在.META.)
  • .META. : 记录了用户创建的表的Region信息,.META.可以有多个Region

HBase表存储结构,多行三列(行键、属性、值)
HBase学习笔记

HBase学习笔记

3. 环境搭建

  1. 下载hbase安装包,并解压

  2. 配置HBase集群需要ZooKeeper集群,配置见zookeeper配置

  3. 修改配置文件

    • vim conf/hbase-env.sh
    # 配置JAVA_HOME JDK1.7以上
    export JAVA_HOME=/hadoop/jdk1.8.0_172
    # 配置是否使用HBase自带的ZooKeeper
    export HBASE_MANAGES_ZK=false
    
    • vim conf/hbase-site.xml
    <configuration>
        <!-- 指定hbase在HDFS上存储的路径 -->
        <property>
            <name>hbase.rootdir</name>
            <value>hdfs://hh1:9000/hbase</value>
        </property>
        <!-- 指定hbase是分布式的 -->
        <property>
            <name>hbase.cluster.distributed</name>
            <value>true</value>
        </property>
        <!-- 指定zk的地址,多个用","分割 -->
        <property>
            <name>hbase.zookeeper.quorum</name>
            <value>hh1:2181,hh2:2181,hh3:2181</value>
        </property>
    </configuration>
    
    • vim conf/regionservers配置提供搭建HBase的服务器地址
    • 如果配置了HA则需要将hadoop的core-site.xmlhdfs-site.xml复制到HBase的配置路径下
  4. 通过scp分发至其他主机

  5. 启动Zookeeper ./zkServer.sh start

  6. 启动HDFS ./start-dfs.sh

  7. 启动HBase ./start-hbase.sh

  8. 可启动多个HMaster保障集群的可靠性 ./hbase-daemon.sh start master

  9. 通过web界面浏览HBase管理界面,v1.0 => http://hh1:16010 , v0.x => http://hh1:60010

4. 使用

4.1 Shell操作

具体指令操作看shell提供的帮助文档即可

  • 查看帮助文档
    • help 查看帮助概述(显示所有的指令)
    • help '指令名称'查看某个指令的帮助(引号必须有)
  • general
    • status HBase集群状态
    • table_help 简单介绍创建、删除表,添加、查询、删除数据
    • version HBase版本信息
    • whoami 当前登录HBase的用户信息
  • namespace
    • list_namespace 列出当前的namespace
    • create_namespace 创建namespace
    • describe_namespace 查看namespace信息
    • alter_namespace 修改namespace
    • drop_namespace 删除namespace
    • list_namespace_tables 列出指定namespace下的所有表
  • DDL(Data Definition Language)
    • list 列出所有的表
    • exists 判断表是否存在
    • describe 查看表信息
    • alter 修改表
    • alter_async 异步修改column family
    • alter_status 获取alter命令的状态
    • create 创建表
    • enable启用单个表
    • disable 禁用单个表
    • drop 删除单个表
    • enable_all 启动多个表(正则匹配)
    • disable_all 禁用多个表(正则匹配)
    • drop_all删除多个表(正则匹配)
    • get_table 获得一个表对象
    • is_disabled 是否被禁用
    • is_enabled 是否被启动
    • show_filters 查看过滤器
  • DML(Data Manipulation Language)
    • append 在指定的table/row/column位置添加值
    • put 在指定table/row/column位置放置值
    • incr 指定表/行/列坐标处的计数器单元格值增加
    • count 统计记录行数
    • get 获取某行的数据,或某行指定列的数据
    • scan 扫描一张表。
    • delete 删除指定的table/row/column位置的值
    • deleteall 删除某行、某行的某列
    • get_counter 返回指定表/行/列坐标处的计数器单元格值。 应使用原子增量函数HBase管理单元格,并且数据应该是二进制编码的。
    • truncate 禁用、删除并创建指定的表
    • truncate_preserve 禁用,删除并重新创建指定的表,同时仍保留以前的区域边界。

4.2 Java API 操作

  • 导包
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>0.98.6.1-hadoop2</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-server</artifactId>
    <version>0.98.6.1-hadoop2</version>
</dependency>
  • Java程序
public class TestHBase {
	
	private Configuration conf = null;
	
	@Before
	public void init() {
		conf = HBaseConfiguration.create();
//		conf.set("hbase.rootir", "hdfs://hh1:9000/hbase");
		conf.set("hbase.zookeeper.quorum", "hh1");
	}
	
	/**
	 * 创建命名空间
	 * @throws Exception
	 */
	@Test
	public void createNamespace() throws Exception {
		
		HBaseAdmin admin = new HBaseAdmin(conf);
		
		NamespaceDescriptor nn = NamespaceDescriptor.create("ns4").build();
		
		admin.createNamespace(nn);
	
		admin.close();
	}
	
	/**
	 * 删除命名空间
	 * @throws Exception
	 */
	@Test
	public void dropNamespace() throws Exception {
		
		HBaseAdmin admin = new HBaseAdmin(conf);
				
		admin.deleteNamespace("ns2");
	
		admin.close();
	}
	
	
	/**
	 * 创建表
	 * @throws IOException
	 */
	@Test
	public void createTable() throws IOException {
		
		TableName tableName = TableName.valueOf("ns4:stu");
		HTableDescriptor tabDesc = new HTableDescriptor(tableName);
		HColumnDescriptor colDesc = new HColumnDescriptor("info");
		colDesc.setMaxVersions(5);
		
		tabDesc.addFamily(colDesc);
		
		
		HBaseAdmin admin = new HBaseAdmin(conf);
		admin.createTable(tabDesc);
		admin.close();
	}
	
	/**
	 * 删除表
	 * @throws IOException
	 */
	@Test
	public void dropTable() throws IOException {
		
		HBaseAdmin admin = new HBaseAdmin(conf);
		TableName tableName = TableName.valueOf("ns4:stu");
		admin.disableTable(tableName);
		admin.deleteTable(tableName);
		admin.close();
	}
	
	
	/**
	 * 添加数据
	 * @throws IOException 
	 */
	@Test
	public void putData() throws IOException {
		
		TableName tableName = TableName.valueOf("ns4:stu");
		HTable table = new HTable(conf, tableName);
		
		Put put = new Put(Bytes.toBytes("rk001"));
		put.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("wangcuihua"));
		put.add(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("18"));
		
		table.put(put);
		table.close();
	}

	/**
	 * 获取数据
	 * @throws IOException
	 */
	@Test
	public void getData() throws IOException {
		
		TableName tableName = TableName.valueOf("ns4:stu");
		HTable table = new HTable(conf, tableName);
		
		Get get = new Get(Bytes.toBytes("rk001"));
		Result res = table.get(get);
		
		for(Cell cell : res.rawCells()) {
			System.out.println("f=" + Bytes.toString(CellUtil.cloneFamily(cell)));
			System.out.println("q=" + Bytes.toString(CellUtil.cloneQualifier(cell)));
			System.out.println("r=" + Bytes.toString(CellUtil.cloneRow(cell)));
			System.out.println("v=" + Bytes.toString(CellUtil.cloneValue(cell)));
			System.out.println(cell.getTimestamp());
			System.out.println();
		}
		
//		for(KeyValue kv : res.list()) {
//			System.out.println("family :" + new String(kv.getFamily()));
//			System.out.println("key :" + new String(kv.getKey()));
//			System.out.println("qualifer :" + new String(kv.getQualifier()));
//			System.out.println("row :" + new String(kv.getRow()));
//			if(new String(kv.getQualifier()).equals("age"))
//				System.out.println("value :" + Bytes.toInt(kv.getValue()));
//			else
//				System.out.println("value :" + new String(kv.getValue()));
//			System.out.println();
//		}
		
		
		
		table.close();
	}
	
	
	/**
	 * 扫描
	 * @throws IOException
	 */
	@Test
	public void scan() throws IOException {

		TableName tableName = TableName.valueOf("ns4:stu");
		HTable table = new HTable(conf, tableName);
		
		Scan scan = new Scan();
		scan.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
		scan.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"));
		
		ResultScanner resScanner = table.getScanner(scan);
		
		for(Result res : resScanner) {
			
			for(Cell cell : res.rawCells()) {
				System.out.println("f=" + Bytes.toString(CellUtil.cloneFamily(cell)));
				System.out.println("q=" + Bytes.toString(CellUtil.cloneQualifier(cell)));
				System.out.println("r=" + Bytes.toString(CellUtil.cloneRow(cell)));
				System.out.println("v=" + Bytes.toString(CellUtil.cloneValue(cell)));
				System.out.println(cell.getTimestamp());
				System.out.println();
			}
			
		}

		table.close();
	}
	
	
	/**
	 * 删除数据
	 * @throws IOException 
	 */
	@Test
	public void deleteData() throws IOException {
		TableName tableName = TableName.valueOf("ns4:stu");
		HTable table = new HTable(conf, tableName);
		
		Delete delete = new Delete(Bytes.toBytes("rk001"));
				
		table.delete(delete);
		
		table.close();
	}
}