HBASE 基础
1 HBASE 简介
hbase是一种分布式、可扩展、支持海量数据存储的NoSQL数据库
like big table。主要用于存数据。
1.1 HBASE逻辑结构
不同的列簇 放于不同的文件夹里。文件夹的分配根据列簇来定。
Row key 行键,为字典序,(唯一)
1.2 HBASE物理存储结构
1.3 HBASE基础架构
2 安装
https://www.apache.org/dyn/closer.lua/hbase/hbase-1.3.6/hbase-1.3.6-bin.tar.gz
下载安装包 解压到/opt/module 下
修改名字为hbase
打开zkServer.sh start
打开hdfs start-dfs.sh
修改 hbase/conf下的配置文件
vim hbase-env.sh
export JAVA_HOME=/opt/module/jdk
export HBASE_MANAGES_ZK=false
修改hbase-site.xml
vim hbase-site.xml
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:9000/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.master.port</name>
<value>16000</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>master,slave1,slave2</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/module/zookeepe/zkData</value>
</property>
修改regionservers
vim regionservers
master
slave1
slave2
建立软链接
ln -s /opt/module/hadoop/etc/hadoop/core-site.xml /opt/module/hbase/conf/core-site.xml
ln -s /opt/module/hadoop/etc/hadoop/hdfs-site.xml /opt/module/hbase/conf/hdfs-site.xml
分发文件
scp -r /opt/module/hbase/ root@slave1:/opt/module/
scp -r /opt/module/hbase/ root@slave2:/opt/module/
配置环境变量
vim /etc/profile
export HBASE_HOME=/opt/module/hbase
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin
scp到别的节点
source /etc/profile
单点启动hbase
bin/hbase-daemon.sh start master
可以登录master:16010
查看ui界面
你会发现里面啥都没有因为regionserver没启动呀
bin/hbase-daemon.sh start regionserver
在启动集群的所有hbase之前需要做的是将时间同步
date -s "2019-10-28 11:31:30"
然后在别的节点启动hbase master
群启命令:
bin/start-hbase.sh
3 hbase shell 操作
(Data Manipulation Language)数据操纵语言:
适用范围:对数据库中的数据进行一些简单操作,如insert,delete,update,select等.
DDL(Data Definition Language)数据定义语言:
适用范围:对数据库中的某些对象(例如,database,table)进行管理,如Create,Alter和Drop.
启动hbase
bin/hbase shell
查看已有表
list
创表
create 'student','info'
create 'stu','info1','info2'
改表信息
alter 'student',{NAME=>'info',VERSIONS=>'3'}
删除表
disable 'table_name'
drop 'table_name'
查命名空间
list_namespace
创建命名空间
create_namespace 'bigdata'
该命名空间下创建表
create "bigdata:stu","info"
删命名空间
先删命名空间里的表
disable "bigdata:stu"
drop "bigdata:stu"
再删命名空间
drop_namespace "bigdata"
增加数据
例put 'ns1:t1', 'r1', 'c1', 'value'
put "stu","1001",'info1:name','zhangsan'
查看数据
Scan方法
scan "table_name"
get方法
get "stu",'1001'
查询限制
scan 'stu',{STARTROW=>'1',STOPROW=>'2'}
修改数据
只要直接将新的数据put到原始数据上
查看所有时间戳的数据
scan 'table_name',{RAW=>true,VERSIONS=>10}
这里的versions是hbase最大保留的版本数
若versions是2
你put3个数据进入,它只保留两个数据
删row key
deleteall 'stu','10010'
4 消息架构
架构
写流程
读流程
同时读磁盘和内存,查出时间戳大的数据
5 JAVA API - HBASE
创建基础连接hbase
package com.csz.test;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import java.io.IOException;
/*
DDL:
1:判断表是否存在
2:创建表
3:创建命名空间
4:删除表
DML:
5:插入数据
6:查数据get
7:插数据scan
8:删除数据
*/
public class TestAPI {
private static Connection connection = null;
private static Admin admin = null;
static{
try{
//获取配置信息
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum","master,slave1,slave2");
connection = ConnectionFactory.createConnection(conf);
admin = connection.getAdmin();
}
catch (IOException e){
e.printStackTrace();
}
}
public static void close(){
if(admin != null){
try{
admin.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
}
}
查询表是否存在
package com.csz.test;
import org.apache.hadoop.hbase.TableName;
import org.apache.log4j.BasicConfigurator;
import java.io.IOException;
public static boolean isTableExist(String tableName) throws IOException {
boolean exists = admin.tableExists(TableName.valueOf(tableName));
close();
return exists;
}
DDL 创建表
public static void createTable(String TableName,String... cfs) throws IOException{
//1. 判断是否存在
if(cfs.length <= 0){
System.out.println("请设置列族信息");
return;
}
if(isTableExist(TableName)){
System.out.println(TableName + "表已经存在");
return;
}
//创建表描述器
HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(TableName));
//循环添加列族信息
for(String cf : cfs){
//创建列族描述器
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);
//添加具体的列族信息
hTableDescriptor.addFamily(hColumnDescriptor);
}
//创建表
admin.createTable(hTableDescriptor);
}
DDL删除表
public static void dropTable(String tableName) throws IOException{
if(!isTableExist(tableName)){
System.out.println(tableName + " 不存在");
}
//让表下线
admin.disableTable(TableName.valueOf(tableName));
admin.deleteTable(TableName.valueOf(tableName));
}
创建namespace
public static void createNamespace(String ns) throws IOException{
//c创建命名空间描述器
NamespaceDescriptor build = NamespaceDescriptor.create(ns).build();
try{
admin.createNamespace(build);
}catch (NamespaceExistException e){
System.out.println("命名空间已经存在拉哈哈哈");
}
catch (IOException e){
e.printStackTrace();
}
System.out.println("尽管存在,还是走到这里");
}
插入数据
public static void put(String tableName,String rowKey,String cf,String cn,String value) throws IOException {
Table table = connection.getTable(TableName.valueOf(tableName));
Put put = new Put(Bytes.toBytes(rowKey));
put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn),Bytes.toBytes(value));
table.put(put);
table.close();
}
查询数据
public static void getData(String tableName,String rowKey,String cf,String cn) throws IOException{
//获取表对象
Table table = connection.getTable(TableName.valueOf(tableName));
//创建get对象
Get get = new Get(Bytes.toBytes(rowKey));
//指定获取的列族
// get.addFamily(Bytes.toBytes(cf));
//设置获取的版本数
get.setMaxVersions();
//指定列族和列
// get.addColumn(Bytes.toBytes(cf),Bytes.toBytes(cn));
//获取数据
Result result = table.get(get);
//解析result 打印
for (Cell cell : result.rawCells()) {
System.out.println(
"CF: " + Bytes.toString(CellUtil.cloneFamily(cell))+
".CN:" + Bytes.toString(CellUtil.cloneQualifier(cell))+
". Value: " + Bytes.toString(CellUtil.cloneValue(cell))
);
}
table.close();
}
scan数据
public static void scanTable(String tableName) throws IOException {
//获取表对象
Table table = connection.getTable(TableName.valueOf(tableName));
//构建scan对象
Scan scan = new Scan(Bytes.toBytes("1001"),Bytes.toBytes("1003"));
//扫描全表
ResultScanner resultScanner = table.getScanner(scan);
//解析resultScanner
for(Result result : resultScanner){
//解析result打印
for (Cell cell : result.rawCells()) {
System.out.println(
"RK:"+ Bytes.toString(CellUtil.cloneRow(cell)) +
",CF : " + Bytes.toString(CellUtil.cloneFamily(cell))+
",CN : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
",Value :"+ Bytes.toString(CellUtil.cloneValue(cell)));
}
}
table.close();
}
Delete数据
public static void deleteData(String tableName,String rowKey,String cf,String cn) throws IOException{
//获取表对象
Table table = connection.getTable(TableName.valueOf(tableName));
//构建删除对象
Delete delete = new Delete(Bytes.toBytes(rowKey));
//设置删除的列
delete.addColumns(Bytes.toBytes(cf),Bytes.toBytes(cn));
//执行删除操作
table.delete(delete);
//关闭连接
table.close();
}
项目
6 问题汇总
HBase提示已创建表,但是list查询时,却显示表不存在。
1.问题出现在zookeeper上。
2.启动zkCli.sh服务
3.ls /hbase/table-lock查看已经建立的表。rmr /hbase/table-lock/[tableName]
ls /hbase/table查看已经建立的表。rmr /hbase/table/[tableName]