HBase 基本入门
无论是 NoSQL,还是大数据领域,HBase 都是非常"炙热"的一门数据库。
本文将对 HBase 做一些基础性的介绍,旨在入门。
一、简介
HBase 是一个开源的、面向列的非关系型分布式数据库,目前是Hadoop体系中非常关键的一部分。
在最初,HBase是基于谷歌的 BigTable 原型实现的,许多技术来自于Fay Chang在2006年所撰写的Google论文"BigTable"。与 BigTable基于Google文件系统(File System)一样,HBase则是基于HDFS(Hadoop的分布式文件系统)之上而开发的。
HBase 采用 Java 语言实现,在其内部实现了BigTable论文提到的一些压缩算法、内存操作和布隆过滤器等,这些能力使得HBase 在海量数据存储、高性能读写场景中得到了大量应用,如 Facebook 在 2010年11 月开始便一直选用 HBase来作为消息平台的存储层技术。
HBase 以 Apache License Version 2.0开源,这是一种对商业应用友好的协议,同时该项目当前也是Apache软件基金会的顶级项目之一。
有什么特性
- 基于列式存储模型,对于数据实现了高度压缩,节省存储成本
- 采用 LSM 机制而不是B(+)树,这使得HBase非常适合海量数据实时写入的场景
- 高可靠,一个数据会包含多个副本(默认是3副本),这得益于HDFS的复制能力,由RegionServer提供自动故障转移的功能
- 高扩展,支持分片扩展能力(基于Region),可实现自动、数据均衡
- 强一致性读写,数据的读写都针对主Region上进行,属于CP型的系统
- 易操作,HBase提供了Java API、RestAPI/Thrift API等接口
- 查询优化,采用Block Cache 和 布隆过滤器来支持海量数据的快速查找
与RDBMS的区别
对于传统 RDBMS 来说,支持 ACID 事务是数据库的基本能力,而 HBase 则使用行级锁来保证写操作的原子性,但是不支持多行写操作的事务性,这主要是从灵活性和扩展性上做出的权衡。
ACID 要素包含 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)以及持久性(Durability)
总体来说, HBase 与传统关系数据库的区别,如下表所示:
特性 | HBase | RDBMS |
---|---|---|
硬件架构 | 类似于 Hadoop 的分布式集群,硬件成本低廉 | 传统的多核系统,硬件成本昂贵 |
容错性 | 由软件架构实现,由于由多个节点组成,所以不担心一点或几点宕机 | 一般需要额外硬件设备实现 HA 机制 |
数据库大小 | PB | GB、TB |
数据排布方式 | 稀疏的、分布的多维的 Map | 以行和列组织 |
数据类型 | Bytes | 丰富的数据类型 |
事物支持 | ACID 只支持单个 Row 级别 | 全面的 ACID 支持,对 Row 和表 |
查询语言 | 只支持 Java API (除非与其他框架一起使用,如 Phoenix、Hive) | SQL |
索引 | 只支持 Row-key,除非与其他技术一起应用,如 Phoenix、Hive | 支持 |
吞吐量 | 百万查询/每秒 | 数千查询/每秒 |
二、数据模型
下面,我们以关系型数据库的一个数据表来演示 HBase 的不同之处。 先来看下面这张表:
ID | 设备名 | 状态 | 时间戳 |
---|---|---|---|
1 | 空调 | 打开 | 20190712 10:05:01 |
2 | 电视机 | 关闭 | 20190712 10:05:08 |
这里记录的是一些家庭设备上报的状态数据(DeviceState),其中包括设备名、状态、时间戳这些字段。
在 HBase 中,数据是按照列族(Column Family,简称CF)来存储的,也就是说对于不同的列会被分开存储到不同的文件。
那么对于上面的状态数据表来说,在HBase中会被存储为两份:
列族1. 设备名
Row-Key | CF:Column-Key | Timestamp | Cell Value |
---|---|---|---|
1 | DeviceState:设备名 | 20190712 10:05:01 | 空调 |
2 | DeviceState:设备名 | 20190712 10:05:08 | 电视机 |
列族2. 状态
Row-Key | CF:Column-Key | Timestamp | Cell Value |
---|---|---|---|
1 | DeviceState:状态 | 20190712 10:05:01 | 打开 |
2 | DeviceState:状态 | 20190712 10:05:08 | 关闭 |
这里Row-key是唯一定位数据行的ID字段,而Row-key 加上 CF、Column-Key,再加上一个时间戳才可以定位到一个单元格数据。
其中时间戳用来表示数据行的版本, 在HBase中默认会有 3 个时间戳的版本数据,这意味着对同一条数据(同一个Rowkey关联的数据)进行写入时,最多可以保存3个版本。
在查询某一行的数据时,HBase需要同时从两个列族(文件)中进行查找,最终将结果合并后返回给客户端。 由此可见如果列族太多,则会影响读取的性能,在设计时就需要做一些权衡。
由此可见,HBase的使用方式与关系型数据库是大不相同的,在使用 HBase 时需要抛弃许多关系型数据库的思维及做法,比如强类型、二级索引、表连接、触发器等等。
然而 HBase 的灵活性及高度可伸缩性却是传统 RDBMS 无法比拟的。
三、安装HBase
单机环境安装
- 准备JDK环境
确保环境上JDK已经装好,可执行java -version确认:
host:/home/hbase # java -version
openjdk version "1.8.0_201"
OpenJDK Runtime Environment (build 1.8.0_201-Huawei_JDK_V100R001C00SPC060B003-b10)
OpenJDK 64-Bit Server VM (build 25.201-b10, mixed mode)
- 下载软件
官网的下载地址页面:
http://archive.apache.org/dist/hbase/
选择合适的版本,比如1.4.10。 下载后解压:
wget http://archive.apache.org/dist/hbase/2.1.5/hbase-2.1.5-bin.tar.gz
tar -xzvf hbase-2.1.5-bin.tar.gz
mkdir -p /opt/local
mv hbase-2.1.5 /opt/local/hbase
配置HBase执行命令路径:
export HBASE_HOME=/opt/local/hbase
export PATH=$PATH:$HBASE_HOME/bin
- 配置软件
vim conf/hbase-env.sh
#JDK安装目录
export JAVA_HOME=/usr/local/jre1.8.0_201
#配置hbase自己管理zookeeper
export HBASE_MANAGES_ZK=true
vim conf/hbase-site.xml
<configuration>
<!-- zookeeper端口 -->
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2182</value>
</property>
<!-- HBase 数据存储目录 -->
<property>
<name>hbase.rootdir</name>
<value>file:///opt/local/hbase/data</value>
</property>
<!-- 用于指定 ZooKeeper 数据存储目录 -->
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/local/hbase/data/zookeeper</value>
</property>
<!-- 用于指定临时数据存储目录 -->
<property>
<name>hbase.tmp.dir</name>
<value>/opt/local/hbase/temp/hbase-${user.name}</value>
</property>
</configuration>
其中 hbase.rootdir 和 hbase.zookeeper.property.dataDir 都用来指定数据存放的目录,默认情况下hbase会使用/tmp目录,这显然是不合适的。
配置了这两个路径之后,hbase会自动创建相应的目录。
关于更多的参数设定可参考这里
- 启动软件
start-hbase.sh
此时查看 logs/hbase-root-master-host-xxx.log,如下:
2019-07-11 07:37:23,654 INFO [localhost:33539.activeMasterManager] hbase.MetaMigrationConvertingToPB: hbase:meta doesn't have any entries to update.
2019-07-11 07:37:23,654 INFO [localhost:33539.activeMasterManager] hbase.MetaMigrationConvertingToPB: META already up-to date with PB serialization
2019-07-11 07:37:23,664 INFO [localhost:33539.activeMasterManager] master.AssignmentManager: Clean cluster startup. Assigning user regions
2019-07-11 07:37:23,665 INFO [localhost:33539.activeMasterManager] master.AssignmentManager: Joined the cluster in 11ms, failover=false
2019-07-11 07:37:23,672 INFO [localhost:33539.activeMasterManager] master.TableNamespaceManager: Namespace table not found. Creating...
检查进程情况,发现进程已经启动
ps -ef |grep hadoop
root 11049 11032 2 07:37 pts/1 00:00:20 /usr/local/jre1.8.0_201/bin/java -Dproc_master -XX:OnOutOfMemoryError=kill -9 %p -XX:+UseConcMarkSweepGC -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m -Dhbase.log.dir=/opt/local/hbase/logs -Dhbase.log.file=hbase-root-master-host-192-168-138-148.log -Dhbase.home.dir=/opt/local/hbase -Dhbase.id.str=root -Dhbase.root.logger=INFO,RFA -Dhbase.security.logger=INFO,RFAS org.apache.hadoop.hbase.master.HMaster start
root 18907 30747 0 07:50 pts/1 00:00:00 grep --color=auto hadoop
通过JPS(JDK自带的检查工具) 可以看到当前启动的Java进程:
# jps
5701 Jps
4826 HMaster
1311 jar
查看 data目录,发现生成了对应的文件:
host:/opt/local/hbase/data # ls -lh .
total 36K
drwx------. 4 root root 4.0K Jul 11 08:08 data
drwx------. 4 root root 4.0K Jul 11 08:08 hbase
-rw-r--r--. 1 root root 42 Jul 11 08:08 hbase.id
-rw-r--r--. 1 root root 7 Jul 11 08:08 hbase.version
drwx------. 2 root root 4.0K Jul 11 08:08 MasterProcWALs
drwx------. 2 root root 4.0K Jul 11 08:08 oldWALs
drwx------. 3 root root 4.0K Jul 11 08:08 .tmp
drwx------. 3 root root 4.0K Jul 11 08:08 WALs
drwx------. 3 root root 4.0K Jul 11 08:08 zookeeper
关于运行模式
HBase启动时默认会使用单机模式,此时 Zookeeper和 HMaster/RegionServer 会运行在同一个JVM中。
以standalone模式启动的HBase会包含一个HMaster、RegionServer、Zookeeper实例,此时 HBase 会直接使用本地文件系统而不是HDFS。
通过将 conf/hbase-site.xml中的 hbase.cluster.distributed 配置为true,就是集群模式了。
在这个模式下,你可以使用分布式环境进行部署,或者是"伪分布式"的多进程环境。
<configuration>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
</configuration>
需要注意的是,如果以standalone启动的话,HMaster、RegionServer端口都是随机的,无法通过配置文件指定。
四、基本使用
打开HBase Shell
hbase shell
执行status命令
Version 2.1.5, r76ab087819fe82ccf6f531096e18ad1bed079651, Wed Jun 5 16:48:11 PDT 2019
hbase(main):001:0> status
1 active master, 0 backup masters, 1 servers, 0 dead, 2.0000 average load
这表示有一个Master在运行,一个RegionServer,每个RegionServer包含2个Region。
表操作
- 创建DeviceState表
hbase(main):002:0> create "DeviceState", "name:c1", "state:c2"
=> Hbase::Table - DeviceState
此时,已经创建了一个DeviceState表,包含name(设备名称)、state(状态)两个列。
查看表信息:
hbase(main):003:0> list
TABLE
DeviceState
1 row(s) in 0.0090 seconds
=> ["DeviceState"]
hbase(main):003:0> describe "DeviceState"
Table DeviceState is ENABLED
DeviceState
COLUMN FAMILIES DESCRIPTION
{NAME => 'name', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSIO
N => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}
{NAME => 'state', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSI
ON => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}
2 row(s) in 0.0870 seconds
- 写入数据
通过下面的命令,向DeviceState写入两条记录,由于有两个列族,因此需要写入四个单元格数据:
put "DeviceState", "row1", "name", "空调"
put "DeviceState", "row1", "state", "打开"
put "DeviceState", "row2", "name", "电视机"
put "DeviceState", "row2", "state", "关闭"
- 查询数据
查询某行、某列
hbase(main):012:0> get "DeviceState","row1"
COLUMN CELL
name: timestamp=1562834473008, value=\xE7\x94\xB5\xE8\xA7\x86\xE6\x9C\xBA
state: timestamp=1562834474630, value=\xE5\x85\xB3\xE9\x97\xAD
1 row(s) in 0.0230 seconds
hbase(main):013:0> get "DeviceState","row1", "name"
COLUMN CELL
name: timestamp=1562834473008, value=\xE7\x94\xB5\xE8\xA7\x86\xE6\x9C\xBA
1 row(s) in 0.0200 seconds
扫描表
hbase(main):026:0> scan "DeviceState"
ROW COLUMN+CELL
row1 column=name:, timestamp=1562834999374, value=\xE7\xA9\xBA\xE8\xB0\x83
row1 column=state:, timestamp=1562834999421, value=\xE6\x89\x93\xE5\xBC\x80
row2 column=name:, timestamp=1562834999452, value=\xE7\x94\xB5\xE8\xA7\x86\xE6\x9C\xBA
row2 column=state:, timestamp=1562835001064, value=\xE5\x85\xB3\xE9\x97\xAD
2 row(s) in 0.0250 seconds
查询数量
hbase(main):014:0> count "DeviceState"
2 row(s) in 0.0370 seconds
=> 1
- 清除数据
删除某列、某行
delete "DeviceState", "row1", "name"
0 row(s) in 0.0080 seconds
hbase(main):003:0> deleteall "DeviceState", "row2"
0 row(s) in 0.1290 seconds
清空整个表数据
hbase(main):021:0> truncate "DeviceState"
Truncating 'DeviceState' table (it may take a while):
- Disabling table...
- Truncating table...
0 row(s) in 3.5060 seconds
删除表(需要先disable)
hbase(main):006:0> disable "DeviceState"
0 row(s) in 2.2690 seconds
hbase(main):007:0> drop "DeviceState"
0 row(s) in 1.2880 seconds
五、FAQ
- 启动时提示 ZK 端口监听失败:
Could not start ZK at requested port of 2181. ZK was started at port: 2182. Aborting as clients (e.g. shell) will not be able to find this ZK quorum
原因
HBase需要启动Zookeeper,而本地的2181端口已经被启用(可能有其他Zookeeper实例)
解决办法
conf/hbase-site.xml中修改hbase.zookeeper.property.clientPort的值,将其修改为2182,:
<configuration>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2182</value>
</property>
</configuration>
- 启动HBase Shell时提示java.lang.UnsatisfiedLinkError
原因
在执行hbase shell期间,JRuby会在“java.io.tmpdir”路径下创建一个临时文件,该路径的默认值为“/tmp”。如果为“/tmp”目录设置NOEXEC权限,然后hbase shell会启动失败并抛出“java.lang.UnsatisfiedLinkError”错误。
解决办法
- 取消/tmp的noexec权限(不推荐)
- 设置java.io.tmpdir变量,指向可用的路径,编辑conf/hbase-env.sh文件:
export HBASE_TMP_DIR=/opt/local/hbase/temp
export HBASE_OPTS="-XX:+UseConcMarkSweepGC -Djava.io.tmpdir=$HBASE_TMP_DIR"
参考文档
HBase 官方权威指南
https://hbase.apache.org/book.html#quickstart
HBase 单机模式搭建
https://my.oschina.net/jackieyeah/blog/712019
HBase 深入浅出
较详细介绍了HBase的由来以及特性,文中提供了HBase集群、存储机制的一些简介,非常适合入门阅读
https://www.ibm.com/developerworks/cn/analytics/library/ba-cn-bigdata-hbase/index.html
HBase 基本入门的更多相关文章
- HBase轻松入门之HBase架构图解析
2018-12-13 2018-12-20 本篇文章旨在针对初学者以我本人现阶段所掌握的知识就HBase的架构图中各模块作一个概念科普.不对文章内容的“绝对.完全正确性”负责. 1.开胃小菜 关于HB ...
- HBase 基本入门篇
无论是 NoSQL,还是大数据领域,HBase 都是非常”炙热”的一门数据库.本文将对 HBase 做一些基础性的介绍,旨在入门. 一.简介 HBase 是一个开源的.面向列的非关系型分布式数据库,目 ...
- hadoop中HBase子项目入门讲解
HBase 是Hadoop的一个子项目,HBase采用了Google BigTable的稀疏的,面向列的数据库实现方式的理论,建立在hadoop的hdfs上,一方面里用了hdfs的高可靠性和可伸缩行, ...
- HBase系统入门--整体介绍
转自:http://www.aboutyun.com/thread-8957-1-2.html 问题导读:1.HBase查询与写入哪个更好一些?2.HBase面对复杂操作能否实现?3.Region服务 ...
- hbase快速入门
hbase 是什么? Apache HBase is an open-source, distributed, versioned, non-relational database modeled a ...
- HBase从入门到精通系列:误删数据如何抢救?
云栖君导读:有时候我们操作数据库的时候不小心误删数据,这时候如何找回?mysql里有binlog可以帮助我们恢复数据,但是没有开binlog也没有备份就尴尬了.如果是HBase,你没有做备份误删了又如 ...
- HBase概念入门
HBase简介 HBase基于Google的BigTable论文而来,是一个分布式海量列式非关系型数据库系统,可以提供大规模数据集的实时随机读写. 下面通过一个小场景认识HBase存储.同样的一个数据 ...
- HBase框架学习之路
1 背景知识 1.1 解决问题 解决HDFS不支持单条记录的快速查找和更新的问题. 1.2 适用情况 存在亿万条记录的数据库,只有千万或者百万条记录使用RDBMS更加合适 确保你的应用不需要使用RDB ...
- HBase、Redis、MongoDB、Couchbase、LevelDB主流 NoSQL 数据库的对比
最近小组准备启动一个 node 开源项目,从前端亲和力.大数据下的IO性能.可扩展性几点入手挑选了 NoSql 数据库,但具体使用哪一款产品还需要做一次选型. 我们最终把选项范围缩窄在 HBase.R ...
随机推荐
- CMMS系统中工单派案&调度
系统为客户经理提供一个有效的调度控制台,由客户经理负责将需要外派现场处理的工单进行统一的分配调度,系统显示每个技术人员的时间表,根据专业技能.可用性.距离或其他资格标准筛选技术服务人员,并向调度人员提 ...
- 优化 .net core 应用的 dockerfile
优化 .net core 应用的 dockerfile Intro 在给 .net core 应用的写 dockerfile 的时候一直有个苦恼,就是如果有很多个项目,在 dockerfile 里写起 ...
- IDEA配置tomcat报错
昨晚想Eclipse转IDEA,谁知道在tomcat就卡住了,难受.今天一下就解决了,记录一下(没有保存错误信息的截图[/敲打]). 问题描述: 运行的时候tomcat卡在Deployment of ...
- 数据结构(四十四)交换排序(1.冒泡排序(O(n²))2.快速排序(O(nlogn))))
一.交换排序的定义 利用交换数据元素的位置进行排序的方法称为交换排序.常用的交换排序方法有冒泡排序和快速排序算法.快速排序算法是一种分区交换排序算法. 二.冒泡排序 1.冒泡排序的定义 冒泡排序(Bu ...
- Python 用科学的方法判断函数/方法
from types import MethodType,FunctionType def check(arg): """ 检查arg是方法还是函数? :param ar ...
- 微信授权就是这个原理,Spring Cloud OAuth2 授权码模式
上一篇文章Spring Cloud OAuth2 实现单点登录介绍了使用 password 模式进行身份认证和单点登录.本篇介绍 Spring Cloud OAuth2 的另外一种授权模式-授权码模式 ...
- 图片瀑布流,so easy!
什么是图片瀑布流 用一张花瓣网页的图片布局可以很清楚看出图片瀑布流的样子: 简单来说,就是有很多图片平铺在页面上,每张图片的宽度相同,但是高度不同,这样错落有致的排列出 n 列的样子很像瀑布,于是就有 ...
- firefox浏览器播放音频
之前做的系统,在firefox浏览器下有更好的使用体验.因此要求客户统一使用firefox浏览器,前段时间客户要求在系统中加入音频效果. 在网上查了下,主要用到的标签有<bgsound>, ...
- java核心编程书上的一个错误
书上说这段代码说明了java对对象不是采用的按引用调用 这明显错了,java还是引用传递,只是把引用对象的变量复制了,互换了x,y所指的对象,对a,b没有影响
- MySQL8.0 redo日志系统优化
背景 现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复.redo日志是物理日志,一般采用WAL(Write-Ahead-Loggin ...