HBase 学习分享

作者:陈云龙

MySql的性能瓶颈

虽说关系型数据库,如MySql已经足够满足我们大部分活动开发的需求,然而有些时候你可曾面对产品看似普通且合理的需求,例如:1、能否让网页活动拉取用户的游戏好友关系链从而更精准的推送Tips?2、判断用户是否在所有大区都没有角色这类需求时却感到了深深的蛋疼,Why?

在现有条件下,我们处理需求1时的方法通常是用DC从tlog中拉取用户好友信息并以如下可能的两种方式建库存储:

左边的表结构是将每个用户的一个好友作为一条记录插入库中,通常我们也就是这么做的。然而如果有百万、千万级的用户,每个用户又有着多个好友。且不考虑单台服务器能否承载如此大的数据,从如此庞大的数据中检索出单个用户好友的sql语句的效率可以想象。右边的表结构虽然每个用户只有一条记录,查询效率不错,但是不可行。因为关系型数据库的表结构是固定的,我们无从得知一个用户会有多少个好友,因此无法确定字段数。肿么办?

需求2的通常处理方法同需求1,不仅效率低tlog拉数据还有着一天的数据延迟,用户体验极差。什么?你说可以通过IDIP接口来实时查询用户是否有角色?如果你觉得炫舞39个大区发39条IDIP指令可以不超时的话可以那么做….

HBase简介

为了解决上述问题,我们决定引入HBase,HBase是一个稀疏的,长期存储的,多维度的,排序的映射表,采用Key-Value方式存储数据。这张表的索引是行关键字,列关键字和时间戳。每个值是一个不解释的字符数组,数据都是字符串,没类型,属于非关系型的分布式数据库。

如果采用HBase,存储用户各大区注册时间信息的表结构可以变成这样:

row key:是用来检索记录的主键,其作用类似于Mysql中的主键。访问hbase table中的行,只有三种方式:

1 、通过单个row key访问

2 、通过row key的range

3、 全表扫描

Row key行键 (Row key)可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在hbase内部,row key保存为字节数组。

列族

Column Family: HBase表中的每个列,都归属与某个列族。列族是表的chema的一部分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。

TimeStamp:HBase中通过row和columns确定的一个数据存贮单元称为cell。每个 cell都保存着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64位整型。时间戳可以由hbase(在数据写入时自动 )赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个 cell中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。

Cell:由{row key, column( =<family> + <label>), version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。

由于HBase采用Key-Value的存储格式,将用户QQ号作为rowkey就能高效的查询到所对应的信息字符串,加以解析即可得到我们所需要的结果。由于HBase是非关系型数据库,Table在水平方向有一个或者多个Column Family组成,一个Column Family中可以由任意多个Column组成,即Column Family支持动态扩展,无需预先定义Column的数量以及类型。在HBase中,表结构还可以是这样的:

需要注意的是,HBase中所有的行都按照字典序进行排列,字典序对int排序的结果是1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,如下图:

行的一次读写是原子操作 (不论一次读写多少列)。这个设计决策能够使用户很容易的理解程序在对同一个行进行并发更新操作时的行为。

HBase不支持条件查询和Order by等查询,读取记录只能按Row key(及其range)或全表扫描,因此Row key需要根据业务来设计以利用其存储排序特性(Table按Row key字典序排序如1,10,100,11,2)提高性能,如果我们希望将行按自然顺序排列,可以在最左边补0。

上述看起来似乎还是没解决问题,如果存放海量用户的关系链数据,单台服务器还是难以负载,HBase又是如何解决数据的存储与检索问题的呢?

HBase的数据存储与检索原理

HBase在行的方向上可以分为多个region,一个region类似于一张mysql中的表.HRegion与表的不同之处在于随着数据不断插入表,region不断增大,当增大到一个阀值的时,Hregion就会等分会两个新的Hregion。当table中的行不断增多,就会有越来越多的Hregion。

Region是HBase分布式存储的最小单位,数据存放在不同服务器上的的region中,而一个region只可能存放于一台服务器上,那么当我们需要从HBase中查询数据的时候,它又是怎样从分布在不同机器上的region中检索数据的呢?

这是由于每个region都记录了Row的Start和Endkey,并由Master交给相应的RegionServer进行管理存储,如下图所示:

那么是如何得知所要查询的数据存放在哪个RegionServer上呢?在HBase中.META.表记录了每个RS上存放数据的Start key和End Key以及RegionServer地址等信息。

现在假设我们要从Table里面查询一条RowKey是100的数据。那么我们应该遵循以下步骤:

  1. 从.META.表里面查询哪个Region包含这条数据。
  2. 获取管理这个Region的RegionServer地址。

  1. 连接这个RegionServer, 查到这条数据。

然而问题也随之而来,.META.自己也是一张表,虽然它记录了数据在RS中的位置信息,如果表的region实在太多导致META表中的数据也多到让其自身分割为多个region存放于不同机器上我们该如何寻址?因此在.META.表之上还有一层-ROOT-表,它用来存放所有.META.表的信息且只有一个region,再由ZooKeeper记录ROOT表的位置。因此假设要检索某条数据,大致流程如下:

HBase存储系统的架构:

HBase分布式数据库,只是分布式存储系统中的一部分,其系统组成包含HDFS、Region Server、Master节点、ZooKeeper集群等四大部分。各部分的具体功能如下描述:

HDFS:

HBase底层存储上依赖于HDFS,HDFS保证了HBase的高可靠性。HDFS为Region Server和Master节点提供分布式存储服务,同时保证数据的可靠性,主要功能如下:

1、提供元数据和表数据的存储

2、数据多副本保存,保证数据的高可靠性和高可用性

Master节点主要负责:

1、为Region Server(在hbase中称之为Region Server)分配region。

2、负责整个集群的负载均衡

3、维护集群中的元数据

4、负责监控整个集群,发现失效的Region Server,并重新分配其上的Region

RegionServer节点主要负责:

  1、管理Master分配的Region,处理来自客户端对Region的读取工作。

  2、切分在运行过程中变的过大的Region。

  3、负责和底层的HDFS交互,存储数据。

Zookeeper节点功能:

  1、保证集群中仅仅存在一个Master能够运行。

  2、监控Region Server的状态,通过回调的形式通知Master RegionServer的上下线的信息。

  3、存储寻址的入口地址。

Hbase存储系统基本上按照google bigtable的论文来实现,基本上的架构如下:

HBase——不仅仅是存储性能的提升

由上图可知,HBase存储系统的底层存储依赖于HDFS(分布式文件系统),分布式的存储方式决定了它优于普通数据库的海量数据存储能力,可是它优秀的仅仅只是存储性能吗?NO!

假如有一个活动,产品想提出所有于某日之后新玩家(所有大区均无角色)名单,并为他们发放新手礼包。按照我们运营开发的传统思想,只可能通过DC从tlog里拉取注册玩家信息,并通过定时脚本遍历该玩家所有大区的角色信息。且不谈这数据量之大mysql是否能够承受,即使能承受,从如此海量的数据找出我们所需要的答案,仅凭脚本所在的一台机器,这个脚本要跑到猴年马月?

既然一台机器的运算能力不够,那多台机器又如何呢?考虑到HBase中的数据存储于多台服务器中,如果能在每台服务器中执行脚本得出结果,再将结果进行合并岂不是能大幅度提高运算效率?

谷歌的MapReduce 编程模型为我们提供了解决方法,它通常把一个问题分成两个子步骤:Map 函数被用来采用大输出并将其分为若干个更小的块,然后将此数据交给其它空闲并且能够用它做一些事情的进程。而Reduce 函数的功能则

是将单一答案从Map所产生的若干个中间输出中化简并带给最终输出。对于上述假设活动,如果运用HBase+MapReduce处理该需求的过程如下:

HBase对于活动开发来说不仅仅是提供了大数据的存储能力,还提供了高效的离线并行计算、数据分析能力,对于将来的活动开发有着极大的意义。

上述就是我总结的一些HBase知识小结,希望大家积极分享、拍砖共同学习。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据派THU

独家 | 一文读懂Hadoop(三):Mapreduce

随着全球经济的不断发展,大数据时代早已悄悄到来,而Hadoop又是大数据环境的基础,想入门大数据行业首先需要了解Hadoop的知识。2017年年初apache发...

2168
来自专栏CSDN技术头条

像Apache Storm一样简单的分布式图计算

介绍 计算可能很复杂。对我们来说,这种复杂主要就是软件世界的人类驱动力。甚至有一个学科整个都围绕着问题解决和计算——计算机科学。 当一个人开始学习计算机科学时,...

2166
来自专栏Spark学习技巧

flink和spark Streaming中的Back Pressure

在讲flink的back pressure之前,我们先讲讲Spark Streaming的back pressure。Spark Streaming的back ...

1062
来自专栏韩伟的专栏

你真的理解数码技术吗?(二)

1.2 文字是如何用数字来记录的 在人类创造的各种信息当中,文字信息一直被我们认为是知识和智慧的重要载体,古代无数僧侣和学者,终身都献身于书籍文字的保存和传达...

3348
来自专栏java初学

作业调度算法

3586
来自专栏CSDN技术头条

使用hadoop进行大规模数据的全局排序

1. Hellow hadoop~~! Hadoop(某人儿子的一只虚拟大象的名字)是一个复杂到极致,又简单到极致的东西。 说它复杂,是因为一个hadoop...

2535
来自专栏点滴积累

geotrellis使用(二十六)实现海量空间数据的搜索处理查看

目录 前言 前台实现 后台实现 总结 一、前言        看到这个题目有人肯定会说这有什么可写的,最简单的我只要用文件系统一个个查找、打开就可以实现,再高级...

3426
来自专栏CSDN技术头条

基于HBase的大数据存储的应用场景分析

本文结合两个实战场景就基于 HBase 的大数据存储做了简单的分析,并对 HBase 的原理做了简单的阐述。

3856
来自专栏Spark学习技巧

大数据查询——HBase读写设计与实践

作者 | 汪婷编辑 | Vincent导语:本文介绍的项目主要解决 check 和 opinion2 张历史数据表(历史数据是指当业务发生过程中的完整中间流程和...

2399
来自专栏ImportSource

必懂的NoSQL理论-Map-Reduce(下)

本文主要内容:一开始我们会讨论把map-reduce切分成个两个阶段的内容,然后会说有关如何处理增量的基础理论。 上一文:必懂的NoSQL理论-Map-Redu...

3557

扫码关注云+社区