ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

HBase_HBase从介绍到Java客户端开发

2020-01-30 17:02:20  阅读:331  来源: 互联网

标签:Java namespace Bytes 命令 toBytes HBase hbase 客户端


文章目录

HBase入门认识

HBase介绍

  • HBase是参考google的bigtable的一个开源产品,建立在hdfs之上的一个提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统。
  • 是一种介于nosql和RDBMs之间的一种数据库系统,仅支持通过rowkeyrange进行数据的检索,主要存储非结构化数据和半结构化数据。
  • HBase和Hadoop一样,目标是通过横向扩展,添加普通机器来增加存储性能和计算性能。
  • HBase特点:(一个表可以有上亿行以及百万级的行)、面向行存储稀疏(由于null不占用存储空间,所有表结果可以设计的非常稀疏)。

HBase

  • HBase使用Zookeeper进行集群节点管理,当然HBase自身集成了一个ZK系统,不过一般情况在实际生产环境中不使用。
  • HBase由masterregionserver两类节点(如果使用HBase自带的zk服务,那么还有HQuorumPeer进程)。
  • Hbase支持提供****backup** master**进行master备份。其中master节点负责和zk进行通信以及存储regionserver的相关位置信息,regionserver节点实现具体对数据的操作,最终数据存储在hdfs上。

HBase架构

在这里插入图片描述

RegionServer集群结构

在这里插入图片描述

HBase逻辑存储结构

在这里插入图片描述

HBase物理存储结构

在这里插入图片描述

key:rowkey:列簇:列名:时间戳

HBase安装

前期准备

  • HBase有三种安装方式,第一种独立模式,第二种是分布式模式(集成zookeeper),第三种是分布式模式(独立zookeeper)
  • 安装步骤:
    1. 安装jdk,至少1.6(版本u18除外)。
    2. 安装ssh免密码登录。
    3. 修改hostname和hosts,hbase通过hostname获取ip地址。
    4. Hadoop安装。
    5. 生成环境集群(NTP + ulimit&nproc + hdfs的dfs.datanode.max.xcievers)
    6. hbase下载安装

HBase安装步骤

  1. 下载hbase,选择版本hbase-0.98.6-cdh5.3.6,下载地址http://archive.cloudera.com/cdh5/cdh/5/。
  2. 解压压缩包到目录/home/hadoop/bigdater/下。
  3. 在hbase的根目录下创建一个文件夹hbase来存储临时文件和pid等。默认/tmp。
  4. 修改配置信息hbase.home/conf/hbasesite.xml{hbase.home}/conf/hbase-site.xml和hbase.home/conf/hbase−site.xml和{hbase.home}/conf/hbase-env.sh文件。
    在这里插入图片描述
    在这里插入图片描述
<configuration>
	<property>
		<name>hbase.rootdir</name>
		<value>hdfs://oda.com/hbase</value>
	</property>
	<property>
		<name>hbase.cluster.distributed</name>
		<value>true</value>
	</property>
		<property>
		<name>hbase.tmp.dir</name>
		<value>/home/jlu/bd/hbase-0.98.6-cdh5.3.6/hbase/tmp</value>
	</property>

</configuration>
  1. 指定regionserver节点hostname,修改文件regionservers。

  2. 创建到hdfs-site.xml的软连接或者配置连接hdfs的配置信息(推荐)。

  3. 添加hbase相关信息到环境变量中(vi ~/.bash_profile)。
    在这里插入图片描述

  4. 启动hbase集群并验证。

Hbase启动

  • 启动集群命令: start-hbase.sh
  • 停止集群命令: stop-hbase.sh
  • 单独启动/停止进程命令: (单独的启动master或者regionserver)
    hbase-daemon.sh (start|stop) (master|regionserver|zookeeper)
    hbase-daemons.sh (start|stop) (regionserver|zookeeper)

HBase验证

验证分为四种方式:

  1. jsp查看是否有hbase的正常启动。
  2. web界面查看是否启动成功。http://192.168.162.121:60010/
  3. shell命令客户端查看是否启动成功。
  4. 查看hbase是否安装成功,查看hdfs文件下是否有hbase的文件夹。

在这里插入图片描述

备份master

  • 如果需要使用hbase的多master结构,那么需要在conf文件夹下添加backup-masters文件,然后一行一个主机名,和regionservers是一样的;
  • 或者在hbase-env.sh中添加变量HBASE_BACKUP_MASTERS,对应value为backup-masters存储路径(启动命令一样)。

HBase命令

HBase 命令介绍

  • HBase命令主要分为两大类,
  • 第一类是指操作hbase表的相关的shell命令
  • 第二类是提供hbase其他相关服务的命令
  • 第一类命令全部在****hbase** shell命令中,那么第二类命令主要以thrift/thrift2等服务为主**。

在这里插入图片描述

HBase Shell命令介绍

  • HBase的Shell命令是以JRuby为核心编写的,主要分为DDL和DML两大类,除此两类之外还有一起其他的命令运维相关的命令,比如snapshots等。
  • 当我们进入hbase的shell命令客户端的时候,我们可以通过help命令查看帮助信息,也可以通过help命令查看具体命令的使用方法。

status命令

  • 作用:查看hbase集群状态信息
  • 参数:simple(简洁),summary(概述),detailed(详细,具体到表);默认是summary。

在这里插入图片描述在这里插入图片描述

命名空间namespace相关命令

介绍

  • 作用:类似关系型数据库中的database,作用是将hbase的表按照业务作用分割开,有益于维护。Hbase默认有两个命名空间,分别是hbase和default。其中hbase命名空间存储hbase自身的表信息,default存储用户创建的表。
  • 命令:
    • create_namespace(创建命名空间),
    • alter_namespace(命名空间修改),
    • describe_namespace(显示命名空间描述信息),
    • drop_namespace(删除命名空间,前提是该命名空间是空的),
    • list_namespace(显示所有命名空间),
    • list_namespace_tables(显示对于命名空间中的table名称)。

create_namespace命令

  • 作用:创建命名空间。
  • 示例:create_namespace ‘bigdater’, {‘comment’=>‘this is ourself namespace’,‘keyname’=>‘valuename’}
    在这里插入图片描述

drop_namespace命令

  • 作用:删除指定命名空间;注意删除的命名空间内不能有table存在,也就是说只能删除空的namespace
  • 示例:drop_namespace ‘bigdater’

在这里插入图片描述

describe_namespace命令

  • 作用:显示命名空间的相关信息。
  • 示例:describe_namespace ‘bigdater’

在这里插入图片描述

list_namespace命令

  • 作用:显示所有存在的命名空间。
  • 示例:list_namespace或者list_namespace ‘regex_str’

list命令

  • 作用:显示hbase表名称,类似mysql中的show tables;
  • 可以通过指定命名空间来查看对应命名空间中的表,默认是显示所有用户表,也支持模糊匹配。类似命令list_namespace_tables查看对应命名空间内有那些表。

在这里插入图片描述

创建hbase用户表

  • 命令格式:create ‘[namespace_name:]table_name’, ‘family_name_1’,…‘family_name_n’(family_name_1表示列簇名)
  • 如果不给定namespace的名称,默认创建在default命名空间中。
  • 示例:create ‘bigdater:test’,‘f’

在这里插入图片描述

删除用户表

  • 删除用户表之前需要将表设置为disable的,然后才可以删除。
  • 其实在hbase中如果需要对已有表进行ddl操作,均需要将其disable在ddl操作完成后,再进行enable操作即可。
    • 命令格式:
      • disable ‘[namespace_name:]table_name’
      • drop ‘[namespace_name:]table_name’
    • 示例:
      • disable ‘bigdater:test’
      • drop ‘bigdater:test’

在这里插入图片描述

put命令

  • 在默认命名空间中创建users表,然后在这个表的基础上进行操作。hbase的put命令是进行数据添加的命令。
    命令格式:
    put ‘[namespace_name:]table_name’, ‘rowkey’, ‘family:[column]’, ‘value’ [, timestamp] [, {ATTRIBUTES=>{‘mykey’=>‘myvalue’}, VISIBILITY=>‘PRIVATE|SECRET’}]
    示例:put ‘users’,‘row1’,‘f:id’,‘1’

在这里插入图片描述

HbaseShell使用Java的Api

在这里插入图片描述

表赋给临时变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sgp5j29-1580359533267)(926BB91E1F3E428284F466202778426C)]

get命令

  • get命令的作用是获取对应表中对应rowkey的数据。默认获取最新版本的全部列数据,可以通过时间戳指定版本信息,也可以指定获取的列
  • 命令格式:
    get ‘[namespace_name:]table_name’, ‘rowkey’
  • 示例:get ‘users’,‘row1’

在这里插入图片描述在这里插入图片描述

scan命令

  • scan命令是hbase的另外一种检索方式,是通过范围查找hbase中的数据。默认情况下是获取table的全部数据,可以通过指定column和filter等相关信息进行数据的过滤。
  • 命令格式:
    scan ‘[namespace_name:]table_name’
  • 示例:scan ‘users’

scan-filter相关命令

  • scan提供多种filter命令,常用filter命令如下:ColumnPrefixFilter,MultipleColumnPrefixFilter,RowFilter,SingleColumnValueFilter,SingleColumnValueExcludeFilter等。

  • 需要注意的是:在指定的value之前需要加’binary:’,比如:scan ‘users’,{FILTER=>“SingleColumnValueFilter(‘f’,‘id’,=,'binary:1)”}

  • MultipleColumnPrefixFilter匹配多个列前缀
    在这里插入图片描述

  • RowFilter需要两个参数
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qOC2nOf5-1580359533269)(23AF861E661D4067A7B2318E24BF056C)]

  • SingleColumnValueFilter最常用,需要的参数也比较多,图中,因为id存的是字符串类型,所以按字典序比较过滤
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZ64ZsjV-1580359533271)(AC3ADF2F8DD3470AA7007513DA9BC538)]

  • 多个过滤条件结合使用
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0B1rCVC1-1580359533271)(F01211FAF31E43FEAE7E5623E8F2860B)]

scan其他参数

  • scan命令除了使用filter外,我们还可以定义我们需要的column,开始扫描的rowkey,结束扫描的rowkey,获取行数等信息。
  • eg:
    • scan ‘users’, {COLUMN=>[‘f:id’,‘f:name’]}
    • scan ‘users’, {STARTROW=>‘row1’,ENDROW=>‘row2’}
    • scan ‘users’, {LIMIT=>1}
  • 限制输出三条记录(row1开头的都属于一条)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nQPOSgCy-1580359533272)(F450F0E069984DA89766746A9680202F)]
  • 指定开始rowkey并限制输出三条记录

在这里插入图片描述

  • STARTROW和ENDROW

在这里插入图片描述

count命令

  • count命令是统计hbase表行数的一个命令,由于相当于一个内置的mapreduce程序,所以当数据量比较大的时候可以选择使用协处理器方式计算行数。
  • 命令格式:
    • count ‘[namespace:]table_name’ [INTERVAL => 1000,] [CACHE => 10]
  • 默认情况下INTERVAL是1000(间隔数),CACHE是10。

在这里插入图片描述

delete命令

  • delete命令是删除指定table的指定rowkey的指定列,也就是说delete命令适合删除列的情况。
  • 命令格式:
    • delete ‘[namespace:]table_name’, ‘rowkey’, ‘family:column’
  • 如果需要删除当然rowkey的所有列数据,那么可以使用deleteall命令。

在这里插入图片描述

truncate命令

  • truncate命令的作用是清空数据库,当我们数据库中的数据比较多的时候,我们可以选择该命令将数据库清空。
  • 命令格式: truncate ‘[namespace_name:]table_name’
    在这里插入图片描述

describe命令

  • 查看描述信息
  • 也可以直接通过web界面查看
    在这里插入图片描述

Java客户端

Java客户端

Java客户端其实就是shell客户端的一种实现,操作命令基本上就是shell客户端命令的一个映射。Java客户端使用的配置信息是被映射到一个HBaseConfiguration的实例对象中的,当使用该类的create方法创建实例对象的时候,会从classpath路径下获取hbase-site.xml文件并进行配置文件内容的读取,同时会读取hadoop的配置文件信息。也可以通过java代码指定命令信息,只需要给定zk的相关环境变量信息即可。代码如下:

Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "hh1,hh2.."); // 第二个参数是主机名 

HBaseAdmin

HBaseAdmin类是主要进行DDL操作相关的一个接口类,主要包括命名空间管理,用户表管理。通过该接口我们可以创建、删除、获取用户表,也可以进行用户表的分割、紧缩等操作。

HTable,HTableDescriptor

HTable是hbase中的用户表的一个映射的java实例,我们可以通过该类进行表数据的操作,包括数据的增删查改,也就是在这里我们可以类似shell中put,get和scan进行数据的操作
HTableDescriptor是hbase用户表的具体描述信息类,一般我们创建表获取获取(给定)表信息,就是通过该类进行的。

Put,Get,Scan,Delete

  • Put类是专门提供插入数据的类。
  • Get类是专门提供根据rowkey获取数据的类。
  • Scan是专门进行范围查找的类。
  • Delete是专门进行删除的类。

HBase连接池

 在web应用中,如果我们之间使用HTable来操作hbase,那么在创建连接和关闭连接的时候,一定会浪费资源。那么HBase提供了一个连接池的基础,主要涉及到的类和接口包括:HConnection,HConnectionManager,HTableInterface,ExecutorService四个。

  • 其中HConnection就是hbase封装好的hbase连接池
  • HConnectionManager是管理连接池的一个类,
  • HTableInterface是在类HTable的基础上进行的一个接口抽象,
  • ExecutorService是jdk的线程池对象

Java客户端编程

HBaseAdmin类详细介绍

  • 测试创建表
    在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述- 获取表信息以及删除表
    在这里插入图片描述

HTable类和连接池详细介绍

package com.jluzh.oda.hbase.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
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.filter.FilterList;
import org.apache.hadoop.hbase.filter.FilterList.Operator;
import org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter;
import org.apache.hadoop.hbase.util.Bytes;

import com.jluzh.oda.hbase.util.HBaseUtil;

public class TestHTable {

	static byte[] family = Bytes.toBytes("f");
	
	public static void main(String[] args) {
		Configuration conf = HBaseUtil.getHBaseConfiguration();
		try {
//			testUseHTable(conf);
			testUseHbaseConnectionPool(conf);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	// 集中调用测试方法
	static void testUseHTable(Configuration conf) throws IOException {
		HTable hTable = new HTable(conf, "users");
		try {
//			 testPut(hTable);
//			 testGet(hTable);
//			 testDelete(hTable);
			testScan(hTable);	// 参数是实现了接口的类实例
		} finally {
			hTable.close();
		}
	}

	// 最好还是使用线程池
	static void testUseHbaseConnectionPool(Configuration conf) throws IOException {
		ExecutorService threads = Executors.newFixedThreadPool(10);	// 10个线程
		HConnection pool = HConnectionManager.createConnection(conf, threads);
		HTableInterface hTable = pool.getTable("users");
		try {
			// testPut(hTable);	// 参数是实现了接口的类实例
			// testGet(hTable);
			// testDelete(hTable);
			testScan(hTable);
		} finally {
			hTable.close(); // 每次htable操作完 关闭 其实是放到pool中
			pool.close(); // 最终的时候关闭
		}
	}
	
	/**
	 * 测试scan
	 * 
	 * @param hTable;接口
	 * @throws IOException
	 */
	static void testScan(HTableInterface hTable) throws IOException{
		Scan scan = new Scan();
		// 增加起始row key
		scan.setStartRow(Bytes.toBytes("row1"));
		scan.setStopRow(Bytes.toBytes("row5"));
		// 使用指定布尔运算符求值的筛选器的有序列表
		FilterList list = new FilterList(Operator.MUST_PASS_ALL);	// 相当于AND
		byte[][] prefixes = new byte[2][];	// 过滤前缀
		prefixes[0] = Bytes.toBytes("id");
		prefixes[1] = Bytes.toBytes("name");
		// 创建多重列前缀过滤器实例
		MultipleColumnPrefixFilter mcpf = new MultipleColumnPrefixFilter(prefixes);
		list.addFilter(mcpf);	// 添加过滤器
		scan.setFilter(list);	// scan操作设置过滤器

		// Returns a scanner on the current table as specified 
		// by the {@link Scan} object.
		ResultScanner rs = hTable.getScanner(scan);
		Iterator<Result> iter = rs.iterator();
		while (iter.hasNext()) {
			// Single row result of a {@link Get} or {@link Scan} query.
			Result result = iter.next();
			printResult(result);
		}
	}

	/**
	 * 打印result对象
	 * 
	 * @param result
	 */
	static void printResult(Result result) {
		System.out.println("*********************" + Bytes.toString(result.getRow())); // 获取rowkey
		// 
		// getMap(): 将族映射到其限定符和值的所有版本。
		NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> map = result.getMap();
		// 遍历map
		for (Map.Entry<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>> entry : map.entrySet()) {
			String family = Bytes.toString(entry.getKey());		// 获取family
			for (Map.Entry<byte[], NavigableMap<Long, byte[]>> columnEntry : entry.getValue().entrySet()) {
				String column = Bytes.toString(columnEntry.getKey());	// 获取column
				String value = "";
				if ("age".equals(column)) {
					value = "" + Bytes.toInt(columnEntry.getValue().firstEntry().getValue());
				} else {
					value = Bytes.toString(columnEntry.getValue().firstEntry().getValue());
				}
				System.out.println(family + ":" + column + ":" + value);
			}
		}
	}

	/**
	 * 测试put操作
	 * 
	 * @param hTable
	 * @throws IOException
	 */
	static void testPut(HTableInterface hTable) throws IOException {
		// 单个put
		Put put = new Put(Bytes.toBytes("row1"));
		put.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("11"));
		put.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("zhangsan"));
		put.add(Bytes.toBytes("f"), Bytes.toBytes("age"), Bytes.toBytes(27));
		put.add(Bytes.toBytes("f"), Bytes.toBytes("phone"), Bytes.toBytes("021-11111111"));
		put.add(Bytes.toBytes("f"), Bytes.toBytes("email"), Bytes.toBytes("zhangsan@qq.com"));
		hTable.put(put);	// 执行put

		// 同时put多个
		Put put1 = new Put(Bytes.toBytes("row2"));
		put1.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("2"));
		put1.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user2"));

		Put put2 = new Put(Bytes.toBytes("row3"));
		put2.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("3"));
		put2.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user3"));

		Put put3 = new Put(Bytes.toBytes("row4"));
		put3.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("4"));
		put3.add(Bytes.toBytes("f"), Bytes.toBytes("name"), Bytes.toBytes("user4"));

		List<Put> list = new ArrayList<Put>();
		list.add(put1);
		list.add(put2);
		list.add(put3);
		hTable.put(list);	// 执行多个put

		// 检测put,条件成功就插入,要求rowkey是一样的。
		Put put4 = new Put(Bytes.toBytes("row5"));
		put4.add(Bytes.toBytes("f"), Bytes.toBytes("id"), Bytes.toBytes("7"));
		hTable.checkAndPut(Bytes.toBytes("row5"), Bytes.toBytes("f"), Bytes.toBytes("id"), null, put4);
		System.out.println("插入成功");
	}
	
	/**
	 * 测试get命令
	 * 
	 * @param hTable
	 * @throws IOException
	 */
	static void testGet(HTableInterface hTable) throws IOException {
		// Create a Get operation for the specified row.
		Get get = new Get(Bytes.toBytes("row1"));
		// Single row result of a {@link Get} or {@link Scan} query.
		Result result = hTable.get(get);	// 执行get
		// Get the latest version of the specified column.
		byte[] buf = result.getValue(family, Bytes.toBytes("id"));	// 获取id
		System.out.println("id:" + Bytes.toString(buf));
		buf = result.getValue(family, Bytes.toBytes("age"));	// 获取age
		System.out.println("age:" + Bytes.toInt(buf));
		buf = result.getValue(family, Bytes.toBytes("name"));
		System.out.println("name:" + Bytes.toString(buf));
		buf = result.getRow();
		System.out.println("row:" + Bytes.toString(buf));
	}
	
	/**
	 * 测试delete
	 * 
	 * @param hTable
	 * @throws IOException
	 */
	static void testDelete(HTableInterface hTable) throws IOException {
		// Create a Delete operation for the specified row.
		Delete delete = new Delete(Bytes.toBytes("row3"));
		// 删除列
		delete = delete.deleteColumn(family, Bytes.toBytes("id"));
		// 直接删除family
		// delete.deleteFamily(family);
		hTable.delete(delete);	// 删除rowkey(Delete delete = new Delete(Bytes.toBytes("row3"));)
		System.out.println("删除成功");
	}	
	
}

pomelorange 发布了8 篇原创文章 · 获赞 5 · 访问量 633 私信 关注

标签:Java,namespace,Bytes,命令,toBytes,HBase,hbase,客户端
来源: https://blog.csdn.net/whisky_12/article/details/104114154

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有