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

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

添加数据操作:

  1. lagou表中插入信息,row key rk1,列族base_info中添加name列标示符,值为wang
  2. put 'lagou', 'rk1', 'base_info:name', 'wang'
  3.  
  4. lagou表中插入信息,row keyrk1,列族base_info中添加age列标示符,值为30
  5. put 'lagou', 'rk1', 'base_info:age', 30

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

查询,更新,删除:

  1. 获取表中row keyrk1的所有信息
  2. get 'lagou', 'rk1'
  3. 获取lagou表中row keyrk1base_info列族的所有信息
  4. get 'lagou', 'rk1', 'base_info'
  5. 获取表中row keyrk1base_info列族的nameage列标示符的信息
  6. get 'lagou', 'rk1', 'base_info:name', 'base_info:age'
  7.  
  8. 获取lagou表中row keyrk1base_infoextra_info列族的信息
  9. hbase(main):010:0> get 'lagou', 'rk1', 'base_info', 'extra_info'
  10. 或者
  11. hbase(main):011:0> get 'lagou', 'rk1', {COLUMN => ['base_info', 'extra_info']}
  12. 或者
  13. hbase(main):012:0> get 'lagou', 'rk1', {COLUMN => ['base_info:name',
  14. 'extra_info:address']}
  15.  
  16. 获取表中row keyrk1cell的值为wang的信息
  17. get 'lagou', 'rk1', {FILTER => "ValueFilter(=,
  18. 'binary:wang')"}
  19.  
  20. 获取表中row keyrk1,列标示符中含有a的信息
  21. get 'lagou', 'rk1', {FILTER => "
  22. (QualifierFilter(=,'substring:a'))"}
  23.  
  24. 查询lagou表中的所有信息:
  25. scan 'lagou'
  26.  
  27. 查询表中列族为 base_info 的信息:
  28. hbase(main):001:0> scan 'lagou', {COLUMNS => 'base_info'}
  29. hbase(main):002:0> scan 'lagou', {COLUMNS => 'base_info', RAW => true, VERSIONS
  30. => 3}
  31. ## Scan时可以设置是否开启Raw模式,开启Raw模式会返回包括已添加删除标记但是未实际删除的数据
  32. ## VERSIONS指定查询的最大版本数
  33.  
  34. 指定多个列族与按照数据值模糊查询:
  35. 查询lagou表中列族为 base_info extra_info且列标示符中含有a字符的信息
  36.  
  37. hbase(main):001:0> scan 'lagou', {COLUMNS => ['base_info', 'extra_info'], FILTER
  38. => "(QualifierFilter(=,'substring:a'))"}
  39.  
  40. rowkey的范围值查询(非常重要)
  41. 查询lagou表中列族为base_infork范围是[rk1, rk3)的数据(rowkey底层存储是字典序)
  42. rowkey顺序存储。
  43. scan 'lagou', {COLUMNS => 'base_info', STARTROW => 'rk1',
  44. ENDROW => 'rk3'}
  45.  
  46. 查询lagou表中row keyrk字符开头的
  47. hbase(main):001:0> scan 'lagou',{FILTER=>"PrefixFilter('rk')"}
  48.  
  49. 更新数据值:
  50. lagou表中rowkeyrk1base_info列族下的列name修改为liang
  51. put 'lagou', 'rk1', 'base_info:name', 'liang'
  52.  
  53. 删除数据和表:
  54. 删除lagourow keyrk1,列标示符为 base_info:name 的数据
  55. > delete 'lagou', 'rk1', 'base_info:name'
  56.  
  57. 指定rowkey,列名以及时间戳信息进行删除
  58. 删除lagourow keyrk1,列标示符为base_info:name的数据
  59. delete 'lagou', 'rk1', 'base_info:name',1600660619655
  60.  
  61. 删除 base_info 列族
  62. alter 'lagou', 'delete' => 'base_info'
  63.  
  64. 删除lagou表数据
  65. truncate 'lagou'
  66.  
  67. 删除lagou
  68. #先disable 再drop
  69. hbase(main):036:0> disable 'lagou'
  70. hbase(main):037:0> drop 'lagou'
  71. #如果不进行disable,直接drop会报错
  72. ERROR: Table user is enabled. Disable it first.

HBase JAVA  API:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.hbase</groupId>
  4. <artifactId>hbase-client</artifactId>
  5. <version>1.3.1</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>junit</groupId>
  9. <artifactId>junit</artifactId>
  10. <version>4.12</version>
  11. <scope>test</scope>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.testng</groupId>
  15. <artifactId>testng</artifactId>
  16. <version>6.14.3</version>
  17. <scope>test</scope>
  18. </dependency>
  19. </dependencies>

创建连接:

  1. package com.lagou.hbase.client;
  2.  
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.hbase.*;
  5. import org.apache.hadoop.hbase.client.*;
  6. import org.apache.hadoop.hbase.util.Bytes;
  7. import org.junit.After;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10.  
  11. import java.io.IOException;
  12.  
  13. public class HbaseClientDemo {
  14. Configuration conf = null;
  15. Connection conn = null;
  16.  
  17. @Before
  18. public void init() throws IOException {
  19. //获取一个配置文件对象
  20. conf = HBaseConfiguration.create();
  21.  
  22. conf.set("hbase.zookeeper.quorum", "linux121,linux122");
  23. conf.set("hbase.zookeeper.property.clientPort", "2181");
  24. //通过conf获取到hbase集群的连接
  25. conn = ConnectionFactory.createConnection(conf);
  26. }
  27.  
  28. //释放连接
  29. @After
  30. public void realse() {
  31. if (conn != null) {
  32. try {
  33. conn.close();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }
  39. }

创建表:

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

插入数据:

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

查询数据:

  1. //查询数据
  2. @Test
  3. public void getData() throws IOException {
  4. //准备table对象
  5. final Table worker = conn.getTable(TableName.valueOf("worker"));
  6. //准备get对象
  7. final Get get = new Get(Bytes.toBytes("110"));
  8. //指定查询某个列族或者列
  9. get.addFamily(Bytes.toBytes("info"));
  10. //执行查询
  11. final Result result = worker.get(get);
  12. //获取到result中所有cell对象
  13. final Cell[] cells = result.rawCells();
  14. //遍历打印
  15. for (Cell cell : cells) {
  16. final String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
  17. final String f = Bytes.toString(CellUtil.cloneFamily(cell));
  18. final String column = Bytes.toString(CellUtil.cloneQualifier(cell));
  19. final String value = Bytes.toString(CellUtil.cloneValue(cell));
  20.  
  21. System.out.println("rowkey-->" + rowkey + "--;cf-->" + f + "---;column--->" + column + "--;value-->" + value);
  22. }
  23. worker.close();
  24. }

删除数据:

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

通过Scan全表扫描:

  1. /**
  2. * 全表扫描
  3. */
  4. @Test
  5. public void scanAllData() throws IOException {
  6. HTable teacher = (HTable) conn.getTable(TableName.valueOf("teacher"));
  7. Scan scan = new Scan();
  8. ResultScanner resultScanner = teacher.getScanner(scan);
  9. for (Result result : resultScanner) {
  10. Cell[] cells = result.rawCells();//获取改行的所有cell对象
  11. for (Cell cell : cells) {
  12. //通过cell获取rowkey,cf,column,value
  13. String cf = Bytes.toString(CellUtil.cloneFamily(cell));
  14. String column = Bytes.toString(CellUtil.cloneQualifier(cell));
  15. String value = Bytes.toString(CellUtil.cloneValue(cell));
  16. String rowkey = Bytes.toString(CellUtil.cloneRow(cell));
  17. System.out.println(rowkey + "----" + cf + "--" + column + "---"
  18. + value);
  19. }
  20. }
  21. teacher.close();
  22.  
  23. }

通过startRowKey和endRowKey进行扫描:

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

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

  1. 海量列式非关系数据库HBase 原理深入

    HBase读数据流程: 前置关键词描述: Block Cache :读缓存,缓存上一次读的数据,整个ReginServer只有一个 MemStore :写缓存,缓存上一次写的数据,每个Store有一个 ...

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

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

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

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

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

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

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

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

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

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

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

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

  8. Hbase架构与原理

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

  9. Hbase架构与原理(转)

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

随机推荐

  1. 凯撒密码(Caesar cipher) 详解

    ------------恢复内容开始------------ 最近训练CTF的时候,发现密码学这块的知识不太系统,所以自己接下来会陆陆续续整理出来 就先从古典密码中的凯撒密码说起吧 凯撒密码内容比较简 ...

  2. noip模拟35[第一次4题·裂了]

    noip模拟35 solutions 这是我第一次这么正式的考四个题,因为这四个题都出自同一个出题人,并不是拼盘拼出来的. 但是考得非常的不好,因为题非常难而且一直想睡觉.. 有好多我根本就不会的算法 ...

  3. ceph介绍和安装

    目录 1.Ceph简介 2.Ceph的特点 3.Ceph的缺点 4.架构与组件 4.1.组件介绍 4.2.存储过程 5.部署 5.1 设置主机名.配置时间同步 5.2 配置添加清华源 5.3 初始化c ...

  4. 跟我一起写 Makefile(五)

    六.多目标 Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似.于是我们就能把其合并起来.当然,多个目标的生成规则的执行命令是同 ...

  5. 痞子衡嵌入式:i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项. 最近痞子衡在支持一个印度客户,这个客户项目主芯片选择 ...

  6. 关于 phpstudy环境下在MySQL中执行into outfile无法导入导出文件解决方法

    之前在做sqli-labs练习,需要用到into outfile 出现以下问题: 执行SQL语句后在指定的路径下无文件生成. 例如: 执行 select into outfile "C:\\ ...

  7. 10BASE—T的主要技术特性

    1)数据传输速率10Mbps基带传输 2)每段双绞线最大长度100m 3)一条通路允许连接HUB数4个,最多5段传输介质 4)拓扑结构星型 5)访问控制方式CSMA/CD 6)帧长度可变,最大1518 ...

  8. noip10

    T1 直接暴力可拿60pts,不开 long long 会挂5pts,时间复杂度 \(\mathcal O(n^{4})\) , 然而这过不了400的数据,至少也要 \(\mathcal O(n^{3 ...

  9. 干货!4大实验项目,深度解析Tag在可观测性领域的最佳实践!

    Opentelemetry协议,是CNCF(Cloud Native Computing Foundation-云原生计算基金会)定义的最新一代的可观测规范(目前还在孵化中),该规范定义了可观测性的三 ...

  10. windows笔记-在可执行文件或DLL的多个实例之间共享静态数据

    全局数据和静态数据不能被同一个. exe或DLL文件的多个映像共享,这是个安全的默认设置.但是,在某些情况下,让一个. exe文件的多个映像共享一个变量的实例是非常有用和方便的. 每个. exe或DL ...