进击大数据系列(九)Hadoop 架构数据库 Hbase
点击下方名片,设为星标!回复“1024”获取2TB学习资源!前面介绍了Hadoop 架构基石 HDFS、统一资源管理和调度平台 YARN、分布式计算框架 MapReduce、数据仓库 Hive、计算引擎 Spark、实时计算流计算引擎 Flink 等相关的知识点,今天我将详细的为大家介绍 大数据 Hadoop 数据库 Hbase 相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一.
点击下方名片,设为星标!
回复“1024”获取2TB学习资源!
前面介绍了 Hadoop 架构基石 HDFS、统一资源管理和调度平台 YARN、分布式计算框架 MapReduce、数据仓库 Hive、计算引擎 Spark、实时计算流计算引擎 Flink 等相关的知识点,今天我将详细的为大家介绍 大数据 Hadoop 数据库 Hbase 相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
HBase 简介
官网解释:HBase(Hadoop Database):Apache HBase™ is the Hadoop database, a distributed, scalable, big data store.HBase 是一个分布式的、面向列的开源数据库,该技术来源于Google三大论文之一“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。
-
适合于存储大表数据(表的规模可以达到数十亿行以及数百万列),并且对大表数据的读、写访问可以达到实时级别。
-
利用HDFS作为其文件存储系统,提供实时读写的分布式数据库系统

主要由以下几点
-
1.the Hadoop database:HBase是基于Hadoop的数据库,所以跟Hadoop是有强依赖关系的,而实际上,我们的HBase底层是要依赖于HDFS的,我们HBase上的数据,其实就是存放在HDFS上。
-
2.a distributed:是一个分布式的,HBase结构也是主从结构,类似于HDFS的主从结构,主从结构有利于对表、对数据进行处理。
-
3.scalable:可扩展的,自然而然,HBase的数据存储在HDFS上,HDFS可以部署在廉价的机器上,而且理论上可以无限扩展。所以,HBase其实是具有这个特点的。
-
4.big data store:大数据量的存储,说明HBase可以存储很大的数据量,一张表可以达到数百万列,数十亿行,而传统数据库,在达到上百万行的时候,就要考虑进行读写分离、分库分表等操作。
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
HBase 特点
-
强一致性读写。
-
面向列的存储。
-
块存储、布隆过滤器。
-
自动故障转移、自动sharding。
-
友好的API操作。Native Java API、Hbase Shell、Thrift GateWay、REST GateWay、Pig、Hive
HBase 应用场景
HBase 适合具有如下需求的应用:
-
海量数据(TB、PB)。
-
不需要完全拥有传统关系型数据库所具备的ACID特性(事物)。
-
高吞吐量。
-
需要在海量数据中实现高效的随机读取。
-
需要很好的性能伸缩能力。
-
能够同时处理结构化和非结构化的数据。
HBase 在大数据中的优势
Hadoop 可以很好地解决大规模数据的离线批量处理问题,但是,受限于 HadoopMapReduce 编程框架的高延迟数据处理机制,使得 Hadoop 无法满足大规模数据实时处理应用的需求。
HDFS 面向批量访问模式,不是随机访问模式。
传统的通用关系型数据库无法应对在数据规模剧增时导致的系统扩展性和性能问题(分库分表也不能很好解决)。
传统关系数据库在数据结构变化时一般需要停机维护;空列浪费存储空间。
因此,业界出现了一类面向半结构化数据存储和处理的高可扩展、低写入/查询延迟的系统,例如,键值数据库、文档数据库和列族数据库(如BigTable和HBase等)。
HBase 已经成功应用于互联网服务领域和传统行业的众多在线式数据分析处理系统中。
HBase 与传统的关系数据库的区别
数据类型
关系数据库采用关系模型,具有丰富的数据类型和存储方式,HBase则采用了更加简单的数据模型,它把数据存储为未经解释的字符串。
数据操作
关系数据库中包含了丰富的操作,其中会涉及复杂的多表连接。HBase操作则不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等,因为HBase在设计上就避免了复杂的表和表之间的关系。
存储模式
关系数据库是基于行模式存储的。HBase是基于列存储的,每个列族都由几个文件保存,不同列族的文件是分离的。
数据索引
关系数据库通常可以针对不同列构建复杂的多个索引,以提高数据访问性能。HBase只有一个索引——行键(RowKey),通过巧妙的设计,HBase中的所有访问方法,或者通过行键访问,或者通过行键扫描,从而使得整个系统不会慢下来。
数据维护
在关系数据库中,更新操作会用最新的当前值去替换记录中原来的旧值,旧值被覆盖后就不会存在。而在HBase中执行更新操作时,并不会删除数据旧的版本,而是生成一个新的版本,旧有的版本仍然保留。
可伸缩性
关系数据库很难实现横向扩展,纵向扩展的空间也比较有限。相反,HBase和BigTable这些分布式数据库就是为了实现灵活的水平扩展而开发的,能够轻易地通过在集群中增加或者减少硬件数量来实现性能的伸缩。
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
HBase 架构

Region概念解释
-
Region可以翻译为区域,在Hbase里面,一个表中的数据会按照行被横向划分为多个Region.
-
每个Region,是按照存储的rowkey的最小行键和最大行键指定的,使用区间
[startRowkey, endRowkey)
-
随着表中的数据越来越多,Region会越来越大,那么Region会自动分裂,目的保证每个Region不会太大
随着数据量增多Region就会自动分裂,产生多个Region 在这里面表示有三个Region。
HRegionServer详解
有了meta表信息就知道RegionServer的节点信息了。
-
HRegionServer由两部分组成:HLog和HRegion (Region就是HRegion的简写)
-
一个HRegionServer包含一个HLog和多个HRegion(Region)
-
Hlog负责记录日志,这对这个HRegionServer里面它接收的所有操作写操作(包括put, delete等操作)。只要是对数据产生变化的操作,都会记录到这个日志中,再把数据写入到对应的HRegion中。
-
HRegion就是负责存储实际数据了
HRegion详解

-
每个HRegion由多个Store组成,每个Store对应一个列族,所以一个HRegion里面可能有多个Store。
-
当我们向HRegionServer写数据的时候,会先写HLog,然后再往HRegion里面去写,在往HRegion里面写数据的时候会根据列族信息把数据写入到不同的Store中。
-
Store包括:MemStore和HFile
-
用户真正写数据的时候会先写入MemStore(基于内存),写满MemStore以后会把MemStore数据持久化到StoreFile里面,StoreFile底层对应的是一个HFile文件。这个HFile文件最终会通过DFS Client写入到HDFS。
Hbase 的存储结构
HBase【Hadoop Database】,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PCServer上搭建起大规模结构化存储集群。——来自百度百科
高可靠性、高性能、可伸缩我们此处不做叙述,主要开一下面向列这一特性。传统的数据库,比如说MySQL、Oracle,这些数据库都是按行存储的,而这里的HBase,是按列进行存储的。行存储是数据按行的方式存储在底层文件中,通常,每一行会自动的分配一个固定的空间。假如在上图:数据库里没有存储我的Phone和Address,只存储了我的ID和Name,那么没存的这两个字段Phone和Address也在占用空间。如果是Hbase的话,对于没有的信息,他是可以为空的,并且不占用空间。
-
优点:利于增加,修改,整行记录等操作,也有利于整行数据的读取。
-
缺点:单列查询时,会读取一些不必要的数据,例如:查找出数据库里面所有人的名字,则需要将所有数据都读取出来,然后将名字这一列检索出来。
再来看列存储
数据以列为单位,列是按照文件夹这样的方式存储的,所以此时如果要在读取Name这一列,就可以直接读取Name之一列就行,无关的数据不用读就行了。如果Address某一个人的信息不知道,就可以把它为空,并且也不占用空间。
列存储的优缺点
-
优点:有利于面向单列数据的读取、统计等操作。
-
缺点:整行读取时,可能需要多次I/O操作。
Hbase表的结构
HBase 逻辑结构

HBase 物理结构

数据模型
Name Space: 命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase 有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。
Region:类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往 HBase 写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase 能够轻松应对字段变更的场景。
Row:HBase 表中的每行数据都由一个 RowKey 和多个 Column(列)组成,数据是按照 RowKey 的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重要。
Column:HBase 中的每个列都由 Column Family (列族)和 Column Qualifier(列限定符)进行限定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。
Time Stamp:用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。
Cell:由{rowkey, column Family:column Qualifier, time Stamp}唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存储。
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
Hbase读写流程
hbase 的读操作
ZooKeeper---meta--regionserver--region--memstore--storefile
-
首先从zookerper找到meta表的region的位置,然后读取meta表中的数据。而meta中又存储了用户表的region信息
-
根据namespace、表名和rowkey根据meta表中的数据找到写入数据对于的region信息
-
然后找到对于的regionserver
-
查找对应的region
-
先从Memstore找数据,如果没有,再到StoreFile上读

hbase 的写操作:
ZooKeeper---meta--regionserver--1、Hlog 1、MemStore--storefile
-
首先从zookerper找到meta表的region的位置,然后读取meta表中的数据。而meta中又存储了用户表的region信息
-
根据namespace、表名和rowkey根据meta表中的数据找到写入数据对于的region信息
-
然后找到对于的regionserver
-
把数据分别写到Hlog和memstore各一份
-
当memstore达到阈值后把数据刷成一个storefile文件,当compact后,逐渐形成越来越大的storefile后触发spilt,把当前的StoreFile分成两个,这里相当于把一个大的region分割成两个region
-
若MemStore中的数据有丢失,则可以从HLog上恢复,当多个StoreFile文件达到一定的大小后,会触发Compact合并操作,合并为一个StoreFile,这里同时进行版本的合并和数据删除
-
HBase 查询快的原因
主要原因是由其架构和底层的数据结构决定的,即由 LSM-Tree(Log-Structured Merge-Tree) + HTable(region分区) + Cache 决定——客户端可以直接定位到要查数据所在的 HRegion server 服务器,然后直接在服务器的一个 region 上查找要匹配的数据,并且这些数据部分是经过 cache 缓存的。
由于 HBase 会将数据保存到内存中,在内存中的数据是有序的,如果内存空间满了,会刷写到 HFile 中,而在HFile中保存的内容也是有序的。当数据写入 HFile 后,内存中的数据会被丢弃。
HFile 文件为磁盘顺序读取做了优化,按页存储。下图展示了在内存中多个块存储并归并到磁盘的过程,合并写入会产生新的结果块,最终多个块被合并为更大块。多次刷写后会产生很多小文件,后台线程会合并小文件组成大文件,这样磁盘查找会限制在少数几个数据存储文件中。HBase 的写入速度快是因为它其实并不是真的立即写入文件中,而是先写入内存,随后异步刷入HFile。所以在客户端看来,写入速度很快。另外,写入时候将随机写入转换成顺序写,数据写入速度也很稳定。
而读取速度快是因为它使用了 LSM 树型结构,而不是B或B+树。磁盘的顺序读取速度很快,但是相比而言,寻找磁道的速度就要慢很多。HBase 的存储结构导致它需要磁盘寻道时间在可预测范围内,并且读取与所要查询的 rowkey 连续的任意数量的记录都不会引发额外的寻道开销。比如有5个存储文件,那么最多需要5次磁盘寻道就可以。而关系型数据库,即使有索引,也无法确定磁盘寻道次数。而且,HBase 读取首先会在缓存(BlockCache)中查找,它采用了 LRU(最近最少使用算法),如果缓存中没找到,会从内存中的 MemStore 中查找,只有这两个地方都找不到时,才会加载 HFile 中的内容,而上文也提到了读取 HFile 速度也会很快,因为节省了寻道开销。
部署 Hbase(伪分布式)
hbase依赖zookeeper,需要先安装zookeeper。
安装zookeeper
安装前准备
-
1)安装JDK
-
2)下载zookeeper
解压zookeeper安装包到/opt/module/目录下
tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
修改配置
将/opt/module/zookeeper-3.4.10/conf
这个路径下的zoo_sample.cfg
修改为zoo.cfg
vim zoo.cfg 修改dataDir路径
dataDir=/opt/module/zookeeper-3.4.10/zkData
mkdir zkData
将zookeeper添加到环境变量
vim /etc/profile
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10export PATH=$PATH:$ZOOKEEPER_HOME/bin
刷新配置
source /etc/profile
启动、查看状态、关闭zookeeper
bin/zkServer.sh start
bin/zkServer.sh status
bin/zkServer.sh stop
bin/zkCli.sh # 启动zookeeper客户端
quit # 退出zookeeper客户端
安装hbase(伪分布式)
hbase版本选择
由于安装的hadoop版本是2.7.2 ,因此hbase版本选择1.4.10
下载地址
https://archive.apache.org/dist/hbase/1.4.10/
解压hbase安装包到/opt/module/目录下
tar -zxvf hbase-1.4.10-bin.tar.gz -C /opt/module/
修改配置文件hbase-env.sh
添加配置
export JAVA_HOME=/opt/module/jdk1.8.0_144export HBASE_MANAGES_ZK=falseexport HADOOP_HOME=/opt/module/hadoop-2.7.2
修改配置文件hbase-site.xml
添加配置
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://linux01:9000/hbase</value>
<description>指定hbase在HDFS上存储的路径, 如果Hadoop为高可用版本请把域名改为自己配置的cluster name。比如hdfs://cluster/hbase</description>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
<description>此项用于配置HBase的部署模式,false表示单机或者伪分布式模式,true表完全分布式模式</description>
</property>
<property>
<name>hbase.master.port</name>
<value>16000</value>
<description>端口默认60000</description>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/module/zookeeper-3.4.10/zkData</value>
<description>此项用于设置存储ZooKeeper的元数据路径</description>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>linux01:2181</value>
<description>此项用于配置ZooKeeper集群所在的主机地址</description>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/opt/module/hbase-1.4.10/tmp</value>
<description>本地缓存目录</description>
</property>
</configuration>
修改配置regionservers
vim regionservers
linux01
将hbase添加到环境变量,启动、关闭hbase
start-hbase.sh # 启动hbase
stop-hbase.sh # 关闭hbase
web 页面
http://192.168.21.101:16010/master-status更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
HBase 常用shell操作
进入HBase客户端命令操作界面
$ bin/hbase shell
查看帮助命令
hbase(main):001:0> help
查看当前数据库中有哪些表
hbase(main):002:0> list
创建一张表
创建user表,包含info、data两个列族
hbase(main):010:0> create 'user', 'info', 'data'
或者
hbase(main):010:0> create 'user', {NAME => 'info', VERSIONS => '3'},{NAME => 'data'}
添加数据操作
向user表中插入信息,row key为rk0001,列族info中添加name列标示符,值为zhangsan。
hbase(main):011:0> put 'user', 'rk0001', 'info:name', 'zhangsan'
向user表中插入信息,row key为rk0001,列族info中添加gender列标示符,值为female。
hbase(main):012:0> put 'user', 'rk0001', 'info:gender', 'female'
向user表中插入信息,row key为rk0001,列族info中添加age列标示符,值为20。
hbase(main):013:0> put 'user', 'rk0001', 'info:age', 20
向user表中插入信息,row key为rk0001,列族data中添加pic列标示符,值为picture。
hbase(main):014:0> put 'user', 'rk0001', 'data:pic', 'picture'
查询数据操作
通过rowkey进行查询
获取user表中row key为rk0001的所有信息。
hbase(main):015:0> get 'user', 'rk0001'
查看rowkey下面的某个列族的信息
获取user表中row key为rk0001,info列族的所有信息。
hbase(main):016:0> get 'user', 'rk0001', 'info'
查看rowkey指定列族指定字段的值
获取user表中row key为rk0001,info列族的name、age列标示符的信息。
hbase(main):017:0> get 'user', 'rk0001', 'info:name', 'info:age'
查看rowkey指定多个列族的信息
获取user表中row key为rk0001,info、data列族的信息。
hbase(main):018:0> get 'user', 'rk0001', 'info', 'data'
或者你也可以这样写
hbase(main):019:0> get 'user', 'rk0001', {COLUMN => ['info', 'data']}
或者你也可以这样写,也行
hbase(main):020:0> get 'user', 'rk0001', {COLUMN => ['info:name', 'data:pic']}
指定rowkey与列值查询
获取user表中row key为rk0001,cell的值为zhangsan的信息。
hbase(main):030:0> get 'user', 'rk0001', {FILTER => "ValueFilter(=, 'binary:zhangsan')"}
指定rowkey与列值模糊查询
获取user表中row key为rk0001,列标示符中含有a的信息。
hbase(main):031:0> get 'user', 'rk0001', {FILTER => "(QualifierFilter(=,'substring:a'))"}
继续插入一批数据
hbase(main):032:0> put 'user', 'rk0002', 'info:name', 'zhangfei'
hbase(main):033:0> put 'user', 'rk0002', 'info:gender', 'female'
hbase(main):034:0> put 'user', 'rk0002', 'info:nationality', '中国'
hbase(main):035:0> get 'user', 'rk0002', {FILTER => "ValueFilter(=, 'binary:中国')"}
查询所有数据
查询user表中的所有信息
scan 'user'
列族查询
查询user表中列族为info的信息
scan 'user', {COLUMNS => 'info'}
scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 5}
scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 3}
多列族查询
查询user表中列族为info和data的信息
scan 'user', {COLUMNS => ['info', 'data']}
scan 'user', {COLUMNS => ['info:name', 'data:pic']}
指定列族与某个列名查询
查询user表中列族为info、列标示符为name的信息
scan 'user', {COLUMNS => 'info:name'}
指定列族与列名以及限定版本查询
查询user表中列族为info、列标示符为name的信息,并且版本最新的5个。
scan 'user', {COLUMNS => 'info:name', VERSIONS => 5}
指定多个列族与按照数据值模糊查询
查询user表中列族为info和data且列标示符中含有a字符的信息。
scan 'user', {COLUMNS => ['info', 'data'], FILTER => "(QualifierFilter(=,'substring:a'))"}
rowkey的范围值查询
查询user表中列族为info,rk范围是[rk0001, rk0003)
的数据。
scan 'user', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}
指定rowkey模糊查询
查询user表中row key以rk字符开头的
scan 'user',{FILTER=>"PrefixFilter('rk')"}
指定数据范围值查询
查询user表中指定范围的数据
scan 'user', {TIMERANGE => [1392368783980, 1392380169184]}
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
更新数据操作
更新数据值
更新操作同插入操作一模一样,只不过有数据就更新,没数据就添加
更新版本号
将user表的info列族版本号改为 5
hbase(main):050:0> alter 'user', NAME => 'info', VERSIONS => 5
删除数据以及删除表操作
指定rowkey以及列名进行删除
删除user表row key为rk0001,列标示符为info:name的数据
hbase(main):045:0> delete 'user', 'rk0001', 'info:name'
指定rowkey,列名以及字段值进行删除
删除user表row key为rk0001,列标示符为info:name,timestamp为1392383705316的数据。
delete 'user', 'rk0001', 'info:name', 1392383705316
删除一个列族
删除一个列族:
alter 'user', NAME => 'info', METHOD => 'delete'
或
alter 'user', 'delete' => 'info'
清空表数据
hbase(main):017:0> truncate 'user'
删除表
首先需要先让该表为disable状态,使用命令:
hbase(main):049:0> disable 'user'
然后才能drop这个表,使用命令:
hbase(main):050:0> drop 'user'
(注意:如果直接drop表,会报错:Drop the named table. Table must first be disabled)
统计一张表有多少行数据
hbase(main):053:0> count 'user'
查看表结构信息
hbase(main):053:0> describe 'user'
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
HBase 的 java 代码开发
熟练掌握通过使用java代码实现HBase数据库当中的数据增删改查的操作,特别是各种查询,熟练运用
创建maven工程,导入jar包
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>2.2.4</version>
</dependency>
开发javaAPI操作HBase表数据
创建表myuser
@Test
public void createTable() throws IOException {
//创建配置文件对象,并指定zookeeper的连接地址
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.property.clientPort", "2181");
configuration.set("hbase.zookeeper.quorum", "hadoop01,hadoop02,hadoop03");
//集群配置
//configuration.set("hbase.zookeeper.quorum", "101.236.39.141,101.236.46.114,101.236.46.113");
Connection connection = ConnectionFactory.createConnection(configuration);
Admin admin = connection.getAdmin();
//添加列族
ColumnFamilyDescriptor f1 = ColumnFamilyDescriptorBuilder.newBuilder("f1".getBytes()).build();
ColumnFamilyDescriptor f2 = ColumnFamilyDescriptorBuilder.newBuilder("f2".getBytes()).build();
//通过TableDescriptorBuilder来实现我们表的参数设置,包括表名,列族等等
TableDescriptor tb = TableDescriptorBuilder.newBuilder(TableName.valueOf("myuser"))
.setColumnFamily(f1)
.setColumnFamily(f2)
.build();
//创建表
boolean myuser = admin.tableExists(TableName.valueOf("myuser"));
if(!myuser){
admin.createTable(tb);
}
//关闭客户端连接
admin.close();
}
向表中添加数据
/**
* 插入数据
*/
@Test
public void addDatas() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
//获取表
Table myuser = connection.getTable(TableName.valueOf("myuser"));
//创建put对象,并指定rowkey
Put put = new Put("0001".getBytes());
put.addColumn("f1".getBytes(),"id".getBytes(), Bytes.toBytes(1));
put.addColumn("f1".getBytes(),"name".getBytes(), Bytes.toBytes("张三"));
put.addColumn("f1".getBytes(),"age".getBytes(), Bytes.toBytes(18));
put.addColumn("f2".getBytes(),"address".getBytes(), Bytes.toBytes("地球人"));
put.addColumn("f2".getBytes(),"phone".getBytes(), Bytes.toBytes("15874102589"));
//插入数据
myuser.put(put);
//关闭表
myuser.close();
}
查询数据
初始化一批数据到HBase当中用于查询
@Test
public void insertBatchData() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
//获取表
Table myuser = connection.getTable(TableName.valueOf("myuser"));
//创建put对象,并指定rowkey
Put put = new Put("0002".getBytes());
put.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(1));
put.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("曹操"));
put.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(30));
put.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("沛国谯县"));
put.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("16888888888"));
put.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("helloworld"));
Put put2 = new Put("0003".getBytes());
put2.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(2));
put2.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("刘备"));
put2.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(32));
put2.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put2.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("幽州涿郡涿县"));
put2.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("17888888888"));
put2.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("talk is cheap , show me the code"));
Put put3 = new Put("0004".getBytes());
put3.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(3));
put3.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("孙权"));
put3.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(35));
put3.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put3.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("下邳"));
put3.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("12888888888"));
put3.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("what are you 弄啥嘞!"));
Put put4 = new Put("0005".getBytes());
put4.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(4));
put4.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("诸葛亮"));
put4.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(28));
put4.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put4.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("四川隆中"));
put4.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("14888888888"));
put4.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("出师表你背了嘛"));
Put put5 = new Put("0006".getBytes());
put5.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(5));
put5.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("司马懿"));
put5.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(27));
put5.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put5.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("哪里人有待考究"));
put5.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("15888888888"));
put5.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("跟诸葛亮死掐"));
Put put6 = new Put("0007".getBytes());
put6.addColumn("f1".getBytes(),"id".getBytes(),Bytes.toBytes(5));
put6.addColumn("f1".getBytes(),"name".getBytes(),Bytes.toBytes("xiaobubu—吕布"));
put6.addColumn("f1".getBytes(),"age".getBytes(),Bytes.toBytes(28));
put6.addColumn("f2".getBytes(),"sex".getBytes(),Bytes.toBytes("1"));
put6.addColumn("f2".getBytes(),"address".getBytes(),Bytes.toBytes("内蒙人"));
put6.addColumn("f2".getBytes(),"phone".getBytes(),Bytes.toBytes("15788888888"));
put6.addColumn("f2".getBytes(),"say".getBytes(),Bytes.toBytes("貂蝉去哪了"));
List<Put> listPut = new ArrayList<Put>();
listPut.add(put);
listPut.add(put2);
listPut.add(put3);
listPut.add(put4);
listPut.add(put5);
listPut.add(put6);
myuser.put(listPut);
myuser.close();
}
按照rowkey进行查询获取所有列的所有值
查询主键rowkey为0003的人
/**
* 查询数据,按照主键id进行查询
*/
@Test
public void searchData() throws IOException {
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Table myuser = connection.getTable(TableName.valueOf("myuser"));
Get get = new Get(Bytes.toBytes("0003"));
Result result = myuser.get(get);
Cell[] cells = result.rawCells();
//获取所有的列名称以及列的值
for (Cell cell : cells) {
//注意,如果列属性是int类型,那么这里就不会显示
System.out.println(Bytes.toString(cell.getQualifierArray(),cell.getQualifierOffset(),cell.getQualifierLength()));
System.out.println(Bytes.toString(cell.getValueArray(),cell.getValueOffset(),cell.getValueLength()));
}
myuser.close();
}
按照rowkey查询指定列族下面的指定列的值
/**
* 通过rowkey查询指定列族下面的指定列的值
*/
@Test
public void searchData2() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Table myuser = connection.getTable(TableName.valueOf("myuser"));
//通过rowKey进行查询
Get get = new Get("0003".getBytes());
get.addColumn("f1".getBytes(),"id".getBytes());
Result result = myuser.get(get);
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "id".getBytes())));
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "age".getBytes())));
System.out.println(Bytes.toString(result.getValue("f1".getBytes(), "name".getBytes())));
myuser.close();
}
通过startRowKey和endRowKey进行扫描
/**
* 通过startRowKey和endRowKey进行扫描查询
*/
@Test
public void scanRowKey() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Table myuser = connection.getTable(TableName.valueOf("myuser"));
Scan scan = new Scan();
scan.setStartRow("0004".getBytes());
scan.setStopRow("0006".getBytes());
ResultScanner resultScanner = myuser.getScanner(scan);
for (Result result : resultScanner) {
//获取rowkey
System.out.println(Bytes.toString(result.getRow()));
//指定列族以及列打印列当中的数据出来
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "id".getBytes())));
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "age".getBytes())));
System.out.println(Bytes.toString(result.getValue("f1".getBytes(), "name".getBytes())));
}
myuser.close();
}
通过scan进行全表扫描
/**
* 全表扫描
*/
@Test
public void scanAllData() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Table myuser = connection.getTable(TableName.valueOf("myuser"));
Scan scan = new Scan();
ResultScanner resultScanner = myuser.getScanner(scan);
for (Result result : resultScanner) {
//获取rowkey
System.out.println(Bytes.toString(result.getRow()));
//指定列族以及列打印列当中的数据出来
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "id".getBytes())));
System.out.println(Bytes.toInt(result.getValue("f1".getBytes(), "age".getBytes())));
System.out.println(Bytes.toString(result.getValue("f1".getBytes(), "name".getBytes())));
}
myuser.close();
}
根据rowkey删除数据
/**
* 删除数据
*/
@Test
public void deleteByRowKey() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Table myuser = connection.getTable(TableName.valueOf("myuser"));
Delete delete = new Delete("0001".getBytes());
myuser.delete(delete);
myuser.close();
}
删除表操作
@Test
public void deleteTable() throws IOException {
//获取连接
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181");
Connection connection = ConnectionFactory.createConnection(configuration);
Admin admin = connection.getAdmin();
admin.disableTable(TableName.valueOf("myuser"));
admin.deleteTable(TableName.valueOf("myuser"));
admin.close();
}
更多关于大数据 Hadoop系列的学习文章,请参阅:进击大数据系列,本系列持续更新中。
参考来源:https://blog.csdn.net/anglemanyi/article/details
/127173621 https://blog.csdn.net/weixin_43593571/article
/details/128326332 https://blog.csdn.net/wzb1983/article
/details/125720484
读者专属技术群
构建高质量的技术交流社群,欢迎从事后端开发、运维技术进群(备注岗位),相互帮助,一起进步!请文明发言,主要以技术交流、内推、行业探讨为主。
广告人士勿入,切勿轻信私聊,防止被骗
推荐阅读 点击标题可跳转
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!
更多推荐
所有评论(0)