初接触hbase数据库

背景

背景说起来有点复杂,公司的项目旧平台已经弃用(相关人员都离职的七七八八),但是系统却还在运行(虽说是演示系统)。

在职人让找离职的,离职让找在职的,没办法,只好自己搞。

就平台跑在k8s集群上,其中一个服务作为大数据平台,数据存储在hbase数据库。

由于平台没有人运维,一直都有挂掉起不来的可能,之前存储了很多图片在里面,需要及早把图片拷贝出来。

看了一下历史文档,结合服务器信息,发现数据存储在hbase这个数据库中。既然是数据库,那么应该支持导出才对,但是发现其中存储的数据已经以tb计算了,我的电脑吃不消,于是考虑学习一下hbase,看是否有方法只导出部分数据。

先说结论:最终也没找到好方法,改为通过写代码导出了。。。

正文

关于hadoop和hbase

hbase是hadoop生态环境中的一环,hadoop以我目前的理解,是两个功能,大数据存储大数据处理

大数据存储基于hdfs(hadoop distributed filesystem),也就是存储在hdfs中。而hdfs有一些缺点,例如高延迟,不支持随机访问,于是在其之上,有了hbase数据库,优化了访问方式和速度。

hbase属于NOSQL数据库,与传统数据库区别比较大,其实在hbase之上,还有hiveimpala等将hbase数据库进行抽象成支持传统SQL的数据库。

我这里暂时还是聚焦于hbase本身。而且不涉及hadoop/hbase等的安装配置,以及命令行的使用,而是从概念的角度进行叙述。

hbase的特点

RDBMS可以被很直观的想象成为一张二维表格,每一行是一条数据,每一条数据有哪些数据项是指定好的,就是表的列。而一行中某一个或几个列又有可以被指定为列的Key,唯一标识这一行。

在网上可以看到的hbase相比于RDBMS的特点,hbase基于列,而非基于行。这句话个人觉得可能并不是那么准确,或者说不能很容易被理解。我想结合hbase的基本使用来说明,可能更容易理解

表创建

hbase也是由一张张表构成,而hbase的表也有所谓的schema,但是它并非像RDBMS那样定义column,而是定义column family`。

看一下hbase中如何创建一张表(通过hbase shell执行的命令,下同):

hbase(main):004:0> create ‘test‘,‘cf1‘,‘cf2‘

这里创建了一张很简单的表叫test,它包含两个column family,分别叫cf1, cf2,就这样了。

相比传统的RDBMS,可能突然会有很多问题:column family(以下简称cf)和传统的有什么区别?每个cf存储什么类型的数据?不需要指定Key吗?

有一个问题时可以预先得知的了,hbase的概念可能接近于redis,都是以二进制数据存储,以后命令中,操作数据,包括指定表名、列名时,也都加了引号,代表字符串。

数据存储

下面是来自这篇教程文章中,关于hbase表的一个概念图:

表中有一个一个的格子,每个格子代表了其中存储的一个数据项。与其说hbase基于列,可能也可以说hbase基于格子(cell)。hbase实际是通过键值对存储的,键可以认为就是格子的坐标,而值就是格子中存储的值。

格子的横坐标是row key,这个概念之前没有提到。格子的纵坐标是column family: column两个结合起来,其中column也是之前没提到的概念。

RDBMS中一行的Key是行中预定义好的某一列(或者某几列),而hbase中,row key是游离于表定义外的一个数据,是在数据插入时额外指定的一个参数。

同样,column(非column family)也是在插入时指定的,这里的column相当灵活,可以是已经存在的,可以是还不存在的,甚至可以不指定。

几个例子:

Example 1
hbase(main):007:0> put ‘test‘,‘r1‘,‘cf1:c1‘,‘data1‘
0 row(s) in 0.0600 seconds

hbase(main):008:0> scan ‘test‘
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570621985644, value=data1
1 row(s) in 0.0250 seconds

这里插入了一条数据,或者说一个键值对。插入的表是刚刚创建的表test,而row key是第二个参数r1

注意第三个参数cf1:c1:的前面代表column familycf1,后面部分c1就是column了。创建表时,需要指定cf,而cf中具体有哪些列,插入时动态添加,只要指定添加的列属于哪个cf就行。

最后一个参数data1是插入的数据。

最后通过scan命令,查看刚刚插入的数据,该数据位于ROW r1COLUMN cf1:c1,数值value是data1,还有一个参数timestamp后面介绍。

Example 2

再添加一条记录

hbase(main):009:0> put ‘test‘,‘r1‘,‘cf1:c1‘,‘data2‘
0 row(s) in 0.0290 seconds

hbase(main):010:0> scan ‘test‘
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
1 row(s) in 0.0140 seconds

这里,我们仍然向r1, cf1:c1中添加数据,然后查询,发现只能查到新添加的数据data2,之前的data1看不到了。

SQL数据库中,添加数据时使用insert,而更改数据时,需要用update。而hbase在同一个行列代表的格子中存储数据,都是通过put指令来操作的。加入的数据,会覆盖``先加入的数据。

不过这里的先、后、覆盖都要打上引号。

Example 3

还是接着上面的操作,这里增加一些选项进行查询

hbase(main):011:0> scan ‘test‘,{RAW=>true,VERSIONS=>2}
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
 r1                                         column=cf1:c1, timestamp=1570621985644, value=data1
1 row(s) in 0.0170 seconds

这次又能查询出来两个数据了?

其实数据并没有真的被覆盖,而是查询时,默认只查询出最后一个加入在这个坐标的数据。不过可以通过VERSION=>2,来设置查询历史最近的两个记录(这里记录和键值对都是指一个意思)。

而记录的远近,是通过记录插入时生成的timestamp来确定的,这个timestamp默认是数据写入hbase时根据服务器时间生成的,不过我们也可以在插入时自己指定:

hbase(main):013:0> put ‘test‘,‘r1‘,‘cf1:c1‘,‘data3‘,20
0 row(s) in 0.0220 seconds

hbase(main):014:0> scan ‘test‘
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
1 row(s) in 0.0130 seconds

hbase(main):015:0> scan ‘test‘,{RAW=>true,VERSIONS=>3}
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
 r1                                         column=cf1:c1, timestamp=1570621985644, value=data1
 r1                                         column=cf1:c1, timestamp=20, value=data3
1 row(s) in 0.0370 seconds

第一条命令,最后增加了一个数字参数20,就代表了我们手动指定timestamp,而不是使用系统默认。

于是接下来一条普通的scan命令,不能查询到我们新插入的data3了。

但是如果指定VERSIONS=>3查询最近的3条,那么就可以看到新插入的数据可以被查出来,只是timestamp太小,放在了最后。

Example 4
hbase(main):016:0> put ‘test‘,‘r2‘,‘cf2‘,‘data4‘
0 row(s) in 0.0340 seconds

hbase(main):017:0> scan ‘test‘
ROW                                         COLUMN+CELL
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
 r2                                         column=cf2:, timestamp=1570623180768, value=data4
2 row(s) in 0.0200 seconds

这里终于使用了不同的row key=>r2了,而且这次也没有指定column,可以看到scan的结果,新添加的数据,默认的column为空,这就是系统默认的column

数据读取

hbase我没有看到比较方便的、类似SQL的查询语句,简单的通过row key来查询。这里之前预先插入了以下数据

hbase(main):020:0> scan ‘test‘
ROW                                         COLUMN+CELL
 r1                                         column=cf1:, timestamp=1570623351436, value=data5
 r1                                         column=cf1:c1, timestamp=1570622432243, value=data2
 r2                                         column=cf2:, timestamp=1570623180768, value=data4
 r2                                         column=cf2:c2, timestamp=1570623364613, value=data6
2 row(s) in 0.0220 seconds

hbase(main):021:0> get ‘test‘,‘r2‘
COLUMN                                      CELL
 cf2:                                       timestamp=1570623180768, value=data4
 cf2:c2                                     timestamp=1570623364613, value=data6
1 row(s) in 0.0210 seconds

首先是通过scan扫描全表看看有哪些数据。然后通过get,只查询r2这一个row key所包含的数据。

这里也能看出hbase的键值对存储特性,每行数据显示的并非一行(一个row key对应的数据),而是row key结合column对应的数据。

虽说如此,但是查询的时候,似乎不能不指定row key,而只指定column,这样来说这也不像传统意义的坐标,因为横坐标row key和纵坐标column地位并非对等的。。。

原文地址:https://www.cnblogs.com/mosakashaka/p/12609023.html

时间: 2024-10-04 09:18:50

初接触hbase数据库的相关文章

MyBatis初接触

参考MyBatis官方文档. 基本开发步骤: 一.导包,mybatis-3.2.7.jar: 二.编写实体类Customer.java(与数据库表对应): 三.编写实体类对应的mapper接口CustomerMapper.java(定义实体类的操作): 四.编写实体类对应的mapper,Customer.xml(接口中的方法名与mapper中的操作的id名要一致): 五.编写mybatis-config.xml: 六.在mybatis-config.xml中注册mapper: 七.从xml获取S

Derby初接触

Derby是个java数据库. 第一次接触,用了下druid的连接池. 还是maven下的,下面上代码: pom: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://mav

初接触Linux,LAMP的构架

今天给大家带来的是LAMP的构架 一.LAMP简介 LAMP(Linux- Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框架包括:Linux操作系统,Apache网络服务器,MySQL数据库,Perl.PHP或者Python编程语言,所有组成产品均是开源软件,是国际上成熟的架构框架,很多流行的商业应用都是采取这个架构.LAMP具有通用.跨平台.高性能.低价格的 优势,因此LAMP无论是性能.质量还是价格都是企业搭建网站的首选平台. 二.相关说明 1.本篇(LAMP系列

初接触Linux,使用Xtrabackuo给Mysql(MariaDB)备份

今天给大家带来的是Xtrabackup给mysql(mariaDB)备份 一.Xtrabackup 1.Xtrabackup介绍 Percona XtraBackup是开源免费的MySQL数据库热备份软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具 2.Xtrabackup的特点 (1)在线热备整个库的InnoDB.XtraDB表 (2)备份过程不会打断正在执行的事务: (3)在xtra

初接触Linux,mysql备份

一.简介 mysqldump是mysql用于转存储数据库的实用程序.它主要产生一个SQL脚本,其中包含从头重新创建数据库所必需的命令CREATE TABLE INSERT等 它可以把整个数据库装载到一个单独的文本文件中.这个文件包含有所有重建你的数据库所需要的SQL命令.这个命令取得所有的模式并且将其转换成DDL语法(CREATE语句,即数据库定义语句),取得所有的数据,并且从这些数据中创建INSERT语句.这个工具将你的数据库中所有的设计倒转.因为所有的东西都被包含到了一个文本文件中.这个文本

初接触Linux,LVM的备份

今天给大家来的得失LVM相关的备份 一.LVM快照写时复制的特性(copy-on-write,COW) 写时复制快照在快照时间点之后,没有物理数据复制发生,仅仅复制了原始数据物理位置的元数据.因此,快照创建非常快,可以瞬间完成.然后,快照副本跟踪原始卷的数据变化(即原始卷写操作),一旦原始卷数据块发生写操作,则先将原始卷数据块读出并写入快照卷,然后用新数据块覆盖原始卷.这样我们访问快照卷上的数据仍旧是写操作前的,可以保证我们备份数据的一致性.它是一个接近于热备的工具 1.逻辑卷快照事实上是一个逻

【瞎折腾系列】mysql存储过程初接触

开始[瞎折腾系列],这个系列纯属瞎折腾,可能没有什么实际意义. mysql存储过程生成表: 新建一张user表,包含id, username , password , usertable字段. 然后创建存储过程: create PROCEDURE create_table() BEGIN DECLARE n int DEFAULT 0; DECLARE t_error INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET

cglib初接触

直接上代码吧. pom添加依赖: <dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.ow2.asm</groupId

linux的初接触

最初衷:当自己的才能不能支配起内心的梦想时,便需要静下心来读读书.知道linux算一个巧合,但既然选择,那便努力一把.这是我的第一篇博文,也是我正式接触linux的所学.愿与大家共勉. ---Aolens 一,Linux比较常见的几个版本以及他们包含的常见的分支: 1,  Debian:ubuntu 2,  Slackware:s.u.S.E 3,  Redhat:CentOS,Fedora,HREL(centos的社区版,由centos调试一些软件是否成功来添加到HREL中         )