HBase的特点:

  • 海量存储: 底层基于HDFS存储海量数据
  • 列式存储:HBase表的数据是基于列族进行存储的,一个列族包含若干列
  • 极易扩展:底层依赖HDFS,当磁盘空间不足的时候,只需要动态增加DataNode服务节点就可以
  • 高并发:支持高并发的读写请求
  • 稀疏:稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情 况下,是不会占用存储空间的。
  • 数据的多版本:HBase表中的数据可以有多个版本值,默认情况下是根据版本号去区分,版本号就 是插入数据的时间戳
  • 数据类型单一:所有的数据在HBase中是以字节数组进行存储

HBase的应用场景:

  HBase适合海量明细数据的存储,并且后期需要有很好的查询性能(单表超千万、上亿, 且并发要求高)

HBase数据模型:

HBase整体架构:

Zookeeper

  • 实现了HMaster的高可用
  • 保存了HBase的元数据信息,是所有HBase表的寻址入口
  • 对HMaster和HRegionServer实现了监控

HMaster(Master)

  • 为HRegionServer分配Region 维护整个集群的负载均衡
  • 维护集群的元数据信息
  • 发现失效的Region,并将失效的Region分配到正常的HRegionServer上

HRegionServer(RegionServer)

  • 负责管理Region 接受客户端的读写数据请求
  • 切分在运行过程中变大的Region

Region

  • 每个HRegion由多个Store构成, 每个Store保存一个列族(Columns Family),表有几个列族,则有几个Store,
  • 每个Store由一个MemStore和多个StoreFile组成,MemStore是Store在内存中的内容,写到文件 后就是StoreFile。
  • StoreFile底层是以HFile的格式保存

HBase shell 基本操作:

入口:hbase shell

hbase(main):001:0> create 'lagou', 'base_info', 'extra_info'
或者(Hbase建表必须指定列族信息)
create 'lagou', {NAME => 'base_info', VERSIONS => '3'},{NAME =>
'extra_info',VERSIONS => '3'}
VERSIONS 是指此单元格内的数据可以保留最近的 3 个版本

添加数据操作:

向lagou表中插入信息,row key为 rk1,列族base_info中添加name列标示符,值为wang
put 'lagou', 'rk1', 'base_info:name', 'wang' 向lagou表中插入信息,row key为rk1,列族base_info中添加age列标示符,值为30
put 'lagou', 'rk1', 'base_info:age', 30

向lagou表中插入信息,row key为rk1,列族extra_info中添加address列标示符,值为shanghai
put 'lagou', 'rk1', 'extra_info:address', 'shanghai'

查询,更新,删除:

获取表中row key为rk1的所有信息
get 'lagou', 'rk1'
获取lagou表中row key为rk1,base_info列族的所有信息
get 'lagou', 'rk1', 'base_info'
获取表中row key为rk1,base_info列族的name、age列标示符的信息
get 'lagou', 'rk1', 'base_info:name', 'base_info:age' 获取lagou表中row key为rk1,base_info、extra_info列族的信息
hbase(main):010:0> get 'lagou', 'rk1', 'base_info', 'extra_info'
或者
hbase(main):011:0> get 'lagou', 'rk1', {COLUMN => ['base_info', 'extra_info']}
或者
hbase(main):012:0> get 'lagou', 'rk1', {COLUMN => ['base_info:name',
'extra_info:address']} 获取表中row key为rk1,cell的值为wang的信息
get 'lagou', 'rk1', {FILTER => "ValueFilter(=,
'binary:wang')"} 获取表中row key为rk1,列标示符中含有a的信息
get 'lagou', 'rk1', {FILTER => "
(QualifierFilter(=,'substring:a'))"} 查询lagou表中的所有信息:
scan 'lagou' 查询表中列族为 base_info 的信息:
hbase(main):001:0> scan 'lagou', {COLUMNS => 'base_info'}
hbase(main):002:0> scan 'lagou', {COLUMNS => 'base_info', RAW => true, VERSIONS
=> 3}
## Scan时可以设置是否开启Raw模式,开启Raw模式会返回包括已添加删除标记但是未实际删除的数据
## VERSIONS指定查询的最大版本数 指定多个列族与按照数据值模糊查询:
查询lagou表中列族为 base_info 和 extra_info且列标示符中含有a字符的信息 hbase(main):001:0> scan 'lagou', {COLUMNS => ['base_info', 'extra_info'], FILTER
=> "(QualifierFilter(=,'substring:a'))"} rowkey的范围值查询(非常重要)
查询lagou表中列族为base_info,rk范围是[rk1, rk3)的数据(rowkey底层存储是字典序)
按rowkey顺序存储。
scan 'lagou', {COLUMNS => 'base_info', STARTROW => 'rk1',
ENDROW => 'rk3'} 查询lagou表中row key以rk字符开头的
hbase(main):001:0> scan 'lagou',{FILTER=>"PrefixFilter('rk')"} 更新数据值:
把lagou表中rowkey为rk1的base_info列族下的列name修改为liang
put 'lagou', 'rk1', 'base_info:name', 'liang' 删除数据和表:
删除lagou表row key为rk1,列标示符为 base_info:name 的数据
> delete 'lagou', 'rk1', 'base_info:name' 指定rowkey,列名以及时间戳信息进行删除
删除lagou表row key为rk1,列标示符为base_info:name的数据
delete 'lagou', 'rk1', 'base_info:name',1600660619655 删除 base_info 列族
alter 'lagou', 'delete' => 'base_info' 删除lagou表数据
truncate 'lagou' 删除lagou表
#先disable 再drop
hbase(main):036:0> disable 'lagou'
hbase(main):037:0> drop 'lagou'
#如果不进行disable,直接drop会报错
ERROR: Table user is enabled. Disable it first.

HBase JAVA  API:

<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
</dependencies>

创建连接:

package com.lagou.hbase.client;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import java.io.IOException; public class HbaseClientDemo {
Configuration conf = null;
Connection conn = null; @Before
public void init() throws IOException {
//获取一个配置文件对象
conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "linux121,linux122");
conf.set("hbase.zookeeper.property.clientPort", "2181");
//通过conf获取到hbase集群的连接
conn = ConnectionFactory.createConnection(conf);
} //释放连接
@After
public void realse() {
if (conn != null) {
try {
conn.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

创建表:

 //创建一张hbase表
@Test
public void createTable() throws IOException {
//获取HbaseAdmin对象用来创建表
HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();
//创建Htabledesc描述器,表描述器
final HTableDescriptor worker = new HTableDescriptor(TableName.valueOf("worker"));
//指定列族
worker.addFamily(new HColumnDescriptor("info"));
admin.createTable(worker);
System.out.println("worker表创建成功!!");
}

插入数据:

  //插入一条数据
@Test
public void putData() throws IOException {
//需要获取一个table对象
final Table worker = conn.getTable(TableName.valueOf("worker")); //准备put对象
final Put put = new Put(Bytes.toBytes("110"));//指定rowkey put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("addr"), Bytes.toBytes("beijing"));
//插入数据,参数类型是put
worker.put(put);
//准备list<puts>,可以执行批量插入
//关闭table对象
worker.close();
System.out.println("插入数据到worker表成功!!");
}

查询数据:

//查询数据
@Test
public void getData() throws IOException {
//准备table对象
final Table worker = conn.getTable(TableName.valueOf("worker"));
//准备get对象
final Get get = new Get(Bytes.toBytes("110"));
//指定查询某个列族或者列
get.addFamily(Bytes.toBytes("info"));
//执行查询
final Result result = worker.get(get);
//获取到result中所有cell对象
final Cell[] cells = result.rawCells();
//遍历打印
for (Cell cell : cells) {
final String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
final String f = Bytes.toString(CellUtil.cloneFamily(cell));
final String column = Bytes.toString(CellUtil.cloneQualifier(cell));
final String value = Bytes.toString(CellUtil.cloneValue(cell)); System.out.println("rowkey-->" + rowkey + "--;cf-->" + f + "---;column--->" + column + "--;value-->" + value);
}
worker.close();
}

删除数据:

   //删除一条数据
@Test
public void deleteData() throws IOException {
//需要获取一个table对象
final Table worker = conn.getTable(TableName.valueOf("worker")); //准备delete对象
final Delete delete = new Delete(Bytes.toBytes("110"));
//执行删除
worker.delete(delete);
//关闭table对象
worker.close();
System.out.println("删除数据成功!!");
}

通过Scan全表扫描:

/**
* 全表扫描
*/
@Test
public void scanAllData() throws IOException {
HTable teacher = (HTable) conn.getTable(TableName.valueOf("teacher"));
Scan scan = new Scan();
ResultScanner resultScanner = teacher.getScanner(scan);
for (Result result : resultScanner) {
Cell[] cells = result.rawCells();//获取改行的所有cell对象
for (Cell cell : cells) {
//通过cell获取rowkey,cf,column,value
String cf = Bytes.toString(CellUtil.cloneFamily(cell));
String column = Bytes.toString(CellUtil.cloneQualifier(cell));
String value = Bytes.toString(CellUtil.cloneValue(cell));
String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
System.out.println(rowkey + "----" + cf + "--" + column + "---"
+ value);
}
}
teacher.close(); }

通过startRowKey和endRowKey进行扫描:

//指定scan 开始rowkey和结束rowkey,这种查询方式建议使用,指定开始和结束rowkey区间避免全表扫描
@Test
public void scanStartEndData() throws IOException {
//准备table对象
final Table worker = conn.getTable(TableName.valueOf("worker"));
//准备scan对象
final Scan scan = new Scan();
//指定查询的rowkey区间,rowkey在hbase中是以字典序排序
scan.setStartRow(Bytes.toBytes("001"));
scan.setStopRow(Bytes.toBytes("004"));
//执行扫描
final ResultScanner resultScanner = worker.getScanner(scan);
for (Result result : resultScanner) {
//获取到result中所有cell对象
final Cell[] cells = result.rawCells();
//遍历打印
for (Cell cell : cells) {
final String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
final String f = Bytes.toString(CellUtil.cloneFamily(cell));
final String column = Bytes.toString(CellUtil.cloneQualifier(cell));
final String value = Bytes.toString(CellUtil.cloneValue(cell));
System.out.println("rowkey-->" + rowkey + "--;cf-->" + f + ";column--->" + column + "--;value-->" + value);
}
} worker.close();
}

海量列式非关系数据库HBase 架构,shell与API的更多相关文章

  1. 列式存储hbase系统架构学习

    一.Hbase简介 HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java.它是Apache软件基金会的Hadoop项目的一部分,运行 ...

  2. HBase 是列式存储数据库吗

    在介绍 HBase 是不是列式存储数据库之前,我们先来了解一下什么是行式数据库和列式数据库. 行式数据库和列式数据库 在维基百科里面,对行式数据库和列式数据库的定义为:列式数据库是以列相关存储架构进行 ...

  3. 【HBase】与关系型数据库区别、行式/列式存储

    [HBase]与关系型数据库区别 1.本质区别 mysql:关系型数据库,行式存储,ACID,SQL,只能存储结构化数据 事务的原子性(Atomicity):是指一个事务要么全部执行,要么不执行,也就 ...

  4. Hbase与Oracle比较(列式数据库与行式数据库)

    Hbase与Oracle比较(列式数据库与行式数据库) 1 主要区别 Hbase适合大量插入同时又有读的情况 Hbase的瓶颈是硬盘传输速度,Oracle的瓶颈是硬盘寻道时间.   Hbase本质上只 ...

  5. HBase:分布式列式NoSQL数据库

    传统的ACID数据库,可扩展性上受到了巨大的挑战.而HBase这类系统,兼具可扩展性的同时,也提出了类SQL的接口. HBase架构组成 HBase采用Master/Slave架构搭建集群,它隶属于H ...

  6. Hadoop HBase概念学习系列之HBase里的列式数据库(十七)

    列式数据库,从数据存储方式上有别于行式数据库,所有数据按列存取. 行式数据库在做一些列分析时,必须将所有列的信息全部读取出来 而列式数据库由于其是按列存取,因此只需在特定列做I/O即可完成查询与分析, ...

  7. Hbase架构与原理

    Hbase架构与原理 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang所撰写的Google论文"Bigtable:一个结构化数据的分布式存储系统".就 ...

  8. Hbase架构与原理(转)

    Hbase架构与原理 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利 ...

  9. NoSQL数据库探讨之一 - 为什么要用非关系数据库?

    随着互联网web2.0网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速.而传统的关系数据库在应付 web2.0网站,特别是超大规模和高并发的SNS类型的web2 ...

  10. hadoop生态圈列式存储系统--kudu

    介绍 Kudu 是一个针对 Apache Hadoop 平台而开发的列式存储管理器.Kudu 共享 Hadoop 生态系统应用的常见技术特性: 它在 commodity hardware(商品硬件)上 ...

随机推荐

  1. Atitit Atitit.软件兼容性原理----------API兼容 Qa7

    Atitit Atitit.软件兼容性原理----------API兼容 Qa7 1. 兼容性的重要性与反面教材1 2. 提升兼容性的原则2 2.1. What 与how 分离2 2.2. 老人老办法 ...

  2. JSBinding+Bridge.NET:Unity游戏热更新方案

    老版本链接如下:http://www.cnblogs.com/answerwinner/p/4469021.html 新用户不要再使用老版本了. 新版本 JSBinding 将抛弃 SharpKit ...

  3. Win10 IoT C#开发 1 - Raspberry安装IoT系统及搭建开发环境

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. The ...

  4. C#----对时间结构DateTime的使用(时间日期的使用)

    1.其初始化时间是0001--0--0 0:0:0 class Program { DateTime dt; static void Main(string[] args) { Program pp ...

  5. UTF-8/UTF-16/UTF-32

    UTF-8/UTF-16/UTF-32 一.UTF-8/UTF-16/UTF-32三者的区别 二.BOM的检测与删除 1.用VIM去除<feff>,即 U+FEFF.注意:这是一个字符,而 ...

  6. Python基础----函数

    1.作用域: 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 1==1: name = 'wupeiqi' print name 下面的结论对吗? 外层变量,可以被内 ...

  7. HDU 2064 汉诺塔III(递归)

    题目链接 Problem Description 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘 ...

  8. js 的 骚操作

    单行的js 代码虽然简洁,但却不易维护,甚至难以理解, 但这却并不影响前端童鞋们编写简洁代码的热情, 一   , 生成随机ID // 生成长度为10的随机字母数字字符串 Math.random().t ...

  9. git客户端保存用户名密码

    [转载]原文地址:https://blog.csdn.net/qq_26819733/article/details/52735123/ 看图说话,直接在Tortoisegit的设置中,点git-&g ...

  10. Python内置函数(7)——bytearray

    英文文档: class bytearray([source[, encoding[, errors]]]) Return a new array of bytes. The bytearray cla ...