海量列式非关系数据库HBase 架构,shell与API
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的更多相关文章
- 海量列式非关系数据库HBase 原理深入
HBase读数据流程: 前置关键词描述: Block Cache :读缓存,缓存上一次读的数据,整个ReginServer只有一个 MemStore :写缓存,缓存上一次写的数据,每个Store有一个 ...
- 列式存储hbase系统架构学习
一.Hbase简介 HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现的编程语言为 Java.它是Apache软件基金会的Hadoop项目的一部分,运行 ...
- HBase 是列式存储数据库吗
在介绍 HBase 是不是列式存储数据库之前,我们先来了解一下什么是行式数据库和列式数据库. 行式数据库和列式数据库 在维基百科里面,对行式数据库和列式数据库的定义为:列式数据库是以列相关存储架构进行 ...
- 【HBase】与关系型数据库区别、行式/列式存储
[HBase]与关系型数据库区别 1.本质区别 mysql:关系型数据库,行式存储,ACID,SQL,只能存储结构化数据 事务的原子性(Atomicity):是指一个事务要么全部执行,要么不执行,也就 ...
- Hbase与Oracle比较(列式数据库与行式数据库)
Hbase与Oracle比较(列式数据库与行式数据库) 1 主要区别 Hbase适合大量插入同时又有读的情况 Hbase的瓶颈是硬盘传输速度,Oracle的瓶颈是硬盘寻道时间. Hbase本质上只 ...
- HBase:分布式列式NoSQL数据库
传统的ACID数据库,可扩展性上受到了巨大的挑战.而HBase这类系统,兼具可扩展性的同时,也提出了类SQL的接口. HBase架构组成 HBase采用Master/Slave架构搭建集群,它隶属于H ...
- Hadoop HBase概念学习系列之HBase里的列式数据库(十七)
列式数据库,从数据存储方式上有别于行式数据库,所有数据按列存取. 行式数据库在做一些列分析时,必须将所有列的信息全部读取出来 而列式数据库由于其是按列存取,因此只需在特定列做I/O即可完成查询与分析, ...
- Hbase架构与原理
Hbase架构与原理 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang所撰写的Google论文"Bigtable:一个结构化数据的分布式存储系统".就 ...
- Hbase架构与原理(转)
Hbase架构与原理 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利 ...
随机推荐
- 凯撒密码(Caesar cipher) 详解
------------恢复内容开始------------ 最近训练CTF的时候,发现密码学这块的知识不太系统,所以自己接下来会陆陆续续整理出来 就先从古典密码中的凯撒密码说起吧 凯撒密码内容比较简 ...
- noip模拟35[第一次4题·裂了]
noip模拟35 solutions 这是我第一次这么正式的考四个题,因为这四个题都出自同一个出题人,并不是拼盘拼出来的. 但是考得非常的不好,因为题非常难而且一直想睡觉.. 有好多我根本就不会的算法 ...
- ceph介绍和安装
目录 1.Ceph简介 2.Ceph的特点 3.Ceph的缺点 4.架构与组件 4.1.组件介绍 4.2.存储过程 5.部署 5.1 设置主机名.配置时间同步 5.2 配置添加清华源 5.3 初始化c ...
- 跟我一起写 Makefile(五)
六.多目标 Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似.于是我们就能把其合并起来.当然,多个目标的生成规则的执行命令是同 ...
- 痞子衡嵌入式:i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项. 最近痞子衡在支持一个印度客户,这个客户项目主芯片选择 ...
- 关于 phpstudy环境下在MySQL中执行into outfile无法导入导出文件解决方法
之前在做sqli-labs练习,需要用到into outfile 出现以下问题: 执行SQL语句后在指定的路径下无文件生成. 例如: 执行 select into outfile "C:\\ ...
- 10BASE—T的主要技术特性
1)数据传输速率10Mbps基带传输 2)每段双绞线最大长度100m 3)一条通路允许连接HUB数4个,最多5段传输介质 4)拓扑结构星型 5)访问控制方式CSMA/CD 6)帧长度可变,最大1518 ...
- noip10
T1 直接暴力可拿60pts,不开 long long 会挂5pts,时间复杂度 \(\mathcal O(n^{4})\) , 然而这过不了400的数据,至少也要 \(\mathcal O(n^{3 ...
- 干货!4大实验项目,深度解析Tag在可观测性领域的最佳实践!
Opentelemetry协议,是CNCF(Cloud Native Computing Foundation-云原生计算基金会)定义的最新一代的可观测规范(目前还在孵化中),该规范定义了可观测性的三 ...
- windows笔记-在可执行文件或DLL的多个实例之间共享静态数据
全局数据和静态数据不能被同一个. exe或DLL文件的多个映像共享,这是个安全的默认设置.但是,在某些情况下,让一个. exe文件的多个映像共享一个变量的实例是非常有用和方便的. 每个. exe或DL ...