无论是 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

单机环境安装

1. 准备JDK环境

确保环境上JDK已经装好,可执行java -version确认:

host:/home/hbase # java -versionopenjdk version "1.8.0_201"OpenJDKRuntimeEnvironment(build 1.8.0_201-Huawei_JDK_V100R001C00SPC060B003-b10)OpenJDK64-BitServer VM (build 25.201-b10, mixed mode)

2. 下载软件

官网的下载地址页面:

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.gztar -xzvf hbase-2.1.5-bin.tar.gzmkdir -p /opt/localmv hbase-2.1.5/opt/local/hbase

配置HBase执行命令路径:

export HBASE_HOME=/opt/local/hbaseexport PATH=$PATH:$HBASE_HOME/bin

3. 配置软件

vim conf/hbase-env.sh

#JDK安装目录export JAVA_HOME=/usr/local/jre1.8.0_201#配置hbase自己管理zookeeperexport 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会自动创建相应的目录。

关于更多的参数设定可参考这里

4. 启动软件

start-hbase.sh

此时查看 logs/hbase-root-master-host-xxx.log,如下:

2019-07-1107: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 serialization2019-07-11 07:37:23,664 INFO  [localhost:33539.activeMasterManager] master.AssignmentManager: Clean cluster startup. Assigning user regions2019-07-11 07:37:23,665 INFO  [localhost:33539.activeMasterManager] master.AssignmentManager: Joined the cluster in 11ms, failover=false2019-07-11 07:37:23,672 INFO  [localhost:33539.activeMasterManager] master.TableNamespaceManager: Namespace table not found. Creating...

检查进程情况,发现进程已经启动

ps -ef |grep hadooproot     1104911032207:37 pts/100: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 startroot     1890730747007:50 pts/100:00:00 grep --color=auto hadoop

通过JPS(JDK自带的检查工具) 可以看到当前启动的Java进程:

# jps5701Jps4826HMaster1311 jar

查看 data目录,发现生成了对应的文件:

host:/opt/local/hbase/data # ls -lh .total 36Kdrwx------. 4 root root 4.0KJul1108:08 datadrwx------. 4 root root 4.0KJul1108:08 hbase-rw-r--r--. 1 root root   42Jul1108:08 hbase.id-rw-r--r--. 1 root root    7Jul1108:08 hbase.versiondrwx------. 2 root root 4.0KJul1108:08MasterProcWALsdrwx------. 2 root root 4.0KJul1108:08 oldWALsdrwx------. 3 root root 4.0KJul1108:08.tmpdrwx------. 3 root root 4.0KJul1108:08WALsdrwx------. 3 root root 4.0KJul1108: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命令

Version2.1.5, r76ab087819fe82ccf6f531096e18ad1bed079651, WedJun516:48:11 PDT 2019
hbase(main):001:0> status1 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> listTABLEDeviceState1 row(s) in0.0090 seconds
=> ["DeviceState"]
hbase(main):003:0> describe "DeviceState"TableDeviceStateis ENABLEDDeviceStateCOLUMN FAMILIES DESCRIPTION{NAME => 'name', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => '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', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}2 row(s) in0.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\xAD1 row(s) in0.0230 seconds
hbase(main):013:0> get"DeviceState","row1", "name"COLUMN                                      CELL name:                                      timestamp=1562834473008, value=\xE7\x94\xB5\xE8\xA7\x86\xE6\x9C\xBA1 row(s) in0.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\xAD2 row(s) in0.0250 seconds

查询数量

hbase(main):014:0> count "DeviceState"2 row(s) in0.0370 seconds
=> 1
  • 清除数据

删除某列、某行

delete"DeviceState", "row1", "name"0 row(s) in0.0080 seconds
hbase(main):003:0> deleteall "DeviceState", "row2"0 row(s) in0.1290 seconds

清空整个表数据

hbase(main):021:0> truncate "DeviceState"Truncating'DeviceState' table (it may take a while):- Disabling table...- Truncating table...0 row(s) in3.5060 seconds

删除表(需要先disable)

hbase(main):006:0> disable "DeviceState"0 row(s) in2.2690 seconds
hbase(main):007:0> drop "DeviceState"0 row(s) in1.2880 seconds

五、FAQ

  • A. 启动时提示 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>
  • B. 启动HBase Shell 时提示java.lang.UnsatisfiedLinkError

原因

在执行hbase shell期间,JRuby会在“java.io.tmpdir”路径下创建一个临时文件,该路径的默认值为“/tmp”。如果为“/tmp”目录设置NOEXEC权限,然后hbase shell会启动失败并抛出“java.lang.UnsatisfiedLinkError”错误。

解决办法

  1. 取消/tmp的noexec权限(不推荐)
  2. 设置java.io.tmpdir变量,指向可用的路径,编辑conf/hbase-env.sh文件:
export HBASE_TMP_DIR=/opt/local/hbase/tempexport HBASE_OPTS="-XX:+UseConcMarkSweepGC -Djava.io.tmpdir=$HBASE_TMP_DIR"

本文公众号来源:美码师
作者:美码师

连接:http://www.itpub.net/2019/12/02/4543/

HBase 基本入门篇的更多相关文章

  1. HBase入门篇

    目录: 1-HBase的安装 2-Java操作HBase例子 3-HBase简单的优化技巧 4–存储 5(集群) -压力分载与失效转发 6 -白话MySQL(RDBMS)与HBase之间 7 -安全& ...

  2. Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码

    Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文主要是记录一写我在学习MapReduce时的一些 ...

  3. Hadoop生态圈-大数据生态体系快速入门篇

    Hadoop生态圈-大数据生态体系快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.大数据概念 1>.什么是大数据 大数据(big data):是指无法在一定时间 ...

  4. Hadoop生态圈-Hive快速入门篇之Hive环境搭建

    Hadoop生态圈-Hive快速入门篇之Hive环境搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据仓库(理论性知识大多摘自百度百科) 1>.什么是数据仓库 数据 ...

  5. mongodb入门篇

    MongoDB 入门篇 分类: NoSQL, 故障解决 undefined 1.1 数据库管理系统 在了解MongoDB之前需要先了解先数据库管理系统 1.1.1 什么是数据? 数据(英语:data) ...

  6. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  7. spring boot(一):入门篇

    构建微服务:Spring boot 入门篇 什么是spring boot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...

  8. 1. web前端开发分享-css,js入门篇

    关注前端这么多年,没有大的成就,就入门期间积累了不少技巧与心得,跟大家分享一下,不一定都适合每个人,毕竟人与人的教育背景与成长环境心理活动都有差别,但就别人的心得再结合自己的特点,然后探索适合自己的学 ...

  9. 一个App完成入门篇(七)- 完成发现页面

    第七章是入门篇的倒数第二篇文章了,明天整个APP将进入收官. 本节教程主要要教会大家使用二维码扫描和用do_WebView组件加在html页面. 导入项目 do_WebView组件 扫描功能 自定义事 ...

随机推荐

  1. 0-python变量及基本数据类型

    目录 1.变量2.字符串3.布尔类型4.整数5.浮点数6.日期 1.变量 1.1.变量的定义 - 类似于标签 1.2.变量的命名规则 - (强制)变量名只能包含数字.字母.下划线 - (强制)不能以数 ...

  2. Python知识点总结篇(五)

    软件目录结构规范 目标: 提高可读性: 提高可维护性: 常见结构 Demo/ |-- bin/ #存放项目的一些可执行文件 | |-- demo #可执行程序,启动demo调main.py | |-- ...

  3. 解决kali安装成功后没有声音的问题

    Kali Linux系统默认状态下,root用户是无法使用声卡的,也就没有声音.启用的方法如下: (1)在终端执行命令:systemctl --user enable pulseaudio (2)在/ ...

  4. H5页面跳转与传值

    页面之间的跳转经常使用a标签,使用mvc框架的都是通过访问controller的请求方法,返回请求页面.但本次开发,前端与后台完全分离,前端APP使用HBuider来开发,后台数据就无法使用mvc框架 ...

  5. Spring概述学习笔记

    1.Spring概述 Spring致力于J2EE应用的各种解决方案,而不仅仅专注于某一层的方案. 可以说,Spring是企业应用开发的一站式选择,他贯穿于表现层.业务层.持久层. Spring并不想取 ...

  6. Eclipse创建ssm项目

    1.创建Maven项目 2.勾选上面的 3.打成war包的形式 4.配置webapp.xml  Project Facets——Dynamic Wed Module 2.5 ——然后点击下面的提示 5 ...

  7. C# vb .net实现宝丽来效果滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的宝丽来效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一 ...

  8. 易百教程人工智能python修正-人工智能NLTK性别发现器

    在这个问题陈述中,将通过提供名字来训练分类器以找到性别(男性或女性). 我们需要使用启发式构造特征向量并训练分类器.这里使用scikit-learn软件包中的标签数据. 以下是构建性别查找器的Pyth ...

  9. K9F1G08U0B K9F2G08U0A K9F2G08U0M

    *L must be set to "Low" Ax表示bit,分5个周期写,一次一个Byte 原理图 引脚定义 命令 Program Erase Read 实验程序 https: ...

  10. 图说jdk1.8新特性(4)--- stream

    总述 jdk1.8引入了Stream相关的API,通过该API.可以实现流式编程,使你写代码的时候行云流水 Stream使得集合的转换变得更加简单,原来可能需要写多个for循环或者多个if判断的,直接 ...