在 HBase 中存储数据和从 HBase 访问数据
HBase可以被认为是NoSQL的旗手。
虽然键/值存储和非关系型替代方案(如对象数据库)已经存在了一段时间,但HBase及其相关的HHadoop工具是第一个将大规模Google型NoSQL成功催化剂的相关性带到大众手中的软件。
HBase并不是唯一的Google Bigtable克隆。超级表是另一个。
HBase 也不是适用于所有情况的理想表格数据存储。最终有一致的数据存储,如Apache Cassandra等,具有HBase提供的其他功能。在探讨 HBase 在哪些方面相关,在哪些方面不相关之前,让我们首先熟悉 HBase 中数据存储和查询的基本要素。
与前面的两个 NoSQL 数据存储一样,我借助一个示例解释了 HBase 基础知识,这里的重点是数据存储和访问。
在本文中,我制作了一个Blog post的假设示例,您可以在其中提取并保存以下信息:
Blog post title Blog post author
Blog post content or body
Blog post header multimedia (for example, an image)
Blog post body multimedia (for example, an image, a video, or an audio file)
为了存储这些数据,我打算创建一个名为blogposts的集合,并将信息分为两类,帖子和多媒体。因此,类似 JSON 格式的可能条目可能如下所示:
{"post":
{ "title": "an interesting blog post",
"author": "a blogger",
"body": "interesting content", },
"multimedia":{
"header":header.png,
"body":body.mpeg,
}
}
或者可能是这样:
{
"post" :{
"title": "yet an interesting blog post",
"author": "another blogger",
"body": "interesting content", },
"multimedia":{
"body-image": body_image.png,
"body-video": body_video.mpeg,
}
}
现在,如果您仔细查看这两个示例数据集,您会注意到它们都共享帖子和多媒体类别,但不一定具有相同的字段集。换句话说,它们的列不同。在HBase行话中,这意味着它们具有相同的列-系列-帖子和多媒体-但没有相同的列集。实际上,多媒体列系列中有四列,即标题,正文,身体图像和正文视频,在某些数据点中,这些列没有值(null)。
在传统的关系数据库中,您必须创建所有四列,并根据需要将一些值设置为 null。在 HBase 和列数据库中,数据按列存储,当值为 null 时不需要存储值。因此,这些非常适合稀疏数据集。
要创建此数据集并保存两个数据点,请先启动 HBase 实例并使用 HBase shell连接到该实例。HBase 在分布式环境中运行,它使用特殊的文件系统抽象来跨多台计算机保存数据。不过,在这个简单的情况下,我在独立和单实例环境中运行 HBase。如果您已下载并提取最新的 HBase 发行版,请通过运行 bin/start-hbase.sh 来启动默认单实例服务器。
服务器启动并运行后,通过启动 shell 连接到 HBase 本地服务器,如下所示:
bin/hbase she11
连接后,创建 HBase 集合博客文章及其两个列系列(帖子和多媒体),如下所示:
$ bin/hbase shel1
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shel1
Version 0.90.1,r1070708, Mon Feb 14 16:56:17 PST 2011
hbase(main) :001:0> create 'blogposts', 'post', 'multimedia'
0 row(s) in 1.7880 seconds
按如下所示填充两个数据点:
hbase(main) :001:0> put 'blogposts', 'post1', 'post:title',
hbase(main):002:0* 'an interesting blog post'
0 row(s) in 0.5570 seconds
hbase(main) :003:0> put 'blogposts', 'post1', 'post:author', 'a blogger' 0 row(s) in 0.0400 seconds
hbase(main):004:0> put 'blogposts', 'post1', 'post:body', 'interesting content' 0 row(s) in 0.0240 seconds
hbase(main) :005:0> put 'blogposts', 'post1', 'multimedia:header', 'header.png' 0 row(s) in 0.0250 seconds
hbase(main) :006:0> put 'blogposts', 'post1', 'multimedia:body','body.png' 0 row(s) in 0.0310 seconds
hbase(main):012:0> put 'blogposts', 'post2', 'post:title', hbase(main) :013:0* 'yet an interesting blog post'
0 row(s) in 0.0320 seconds
hbase(main):014:0> put 'blogposts', 'post2', 'post:title', hbase(main):015:0* 'yet another blog post'
0 row(s) in 0.0350 seconds
hbase(main):016:0> put 'blogposts', 'post2', 'post:author','another blogger' 0 row(s) in 0.0250 seconds
hbase(main):017:0> put 'blogposts', 'post2', 'post:author', 'another blogger' 0 row(s) in 0.0290 seconds
hbase(main):018:0> put 'blogposts', 'post2', 'post:author', 'another blogger' 0 row(s) in 0.0400 seconds
hbase(main) :019:0> put 'blogposts', 'post2', 'multimedia:body-image', hbase(main):020:0*'body_image.png'
0 row(s) in 0.0440 seconds
hbase(main) :021:0> put 'blogposts', 'post2', 'post:body','interesting content' 0 row(s) in 0.0300 seconds
hbase(main):022:0> put 'blogposts', 'post2', 'multimedia:body-video', hbase(main):023:0*'body_video.mpeg'
0 row(s) in 0.0380 seconds
两个示例数据点的 ID 分别为 post1 和 post2。
如果您注意到,我在输入 post2 的标题时犯了一个错误,所以我重新输入了它。
我还为 post2 重新输入了相同的作者信息三个项目。
在关系世界中,这意味着数据更新。但是,在 HBase 中,记录是不可变的。重新输入数据会导致创建较新版本的数据集。
这有两个好处:避免了数据更新的原子性冲突,并且数据存储中提供了隐式内置版本控制系统。
存储数据后,可以编写几个基本查询来检索数据了。
查询 HBase
查询 HBase 存储的最简单方法是通过其shell 。
如果您已经登录到 shell(这意味着您已使用 bin/hbase shell 启动它并连接到您刚刚输入一些数据的同一本地存储),您可能已准备好查询该数据。
要获取与 post1 相关的所有数据,只需像这样查询:
这显示了所有 post1 属性及其值。要获取与 post2 相关的所有数据,只需像这样查询:
要获取仅包含 post1 标题列的过滤列表,请像这样查询:
您可能还记得我为 post2 标题重新输入了数据,因此您可以像这样查询两个版本:
默认情况下,HBase 仅返回最新版本,但您可以随时请求多个版本或获取明确的旧版本(如果您愿意)。
有了这些简单的查询,让我们继续最后一个示例数据存储 Apache Cassandra。
本文正在参加「金石计划 . 瓜分6万现金大奖」