初识Hbase
1.1海量数据与NoSQL
1.1.1 关系型数据库的极限
- 表会被并发地进行插入、编辑以及删除操作。一个大中型网站的并发操作一般能达到几十乃至几百并发,此时单条数据查询的延时将轻而易举地达到分钟级别。
- 查询语句通常都不是简单地对一个表的查询,而有可能是多个表关联后的复杂查询,甚至有可能有group by或者order by操作,此时,性能下降随之而来。
1.1.2 CAP理论
- Consistency(一致性):数据一致更新,所有数据变动都是同步的。
- Availability(可用性):良好的响应性能。
- Partition tolerance(分区容错性):可靠性。
任何分布式系统只可同时满足二点,没法三者兼顾。架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍
1.1.3 NoSQL
很多人以为NoSQL是非SQL的意思,其实它是Not Only SQL的缩写,意思是不只是SQL.
1.2 HBase是怎么来的
- 2006年Google技术人员Fay Chang发布了一篇文章Bigtable:A Distributed Storage System for Structured Data。该文章向世人介绍了一种分布式的数据库,这种数据库可以在局部几台服务器崩溃的情况下继续提供高性能的服务。
- 2007年Powerset公司的工作人员基于此文研发了BigTable的Java开源版本,即HBase。刚开始它只是Hadoop的一部分。
- 2008年HBase成为了Apache的顶级项目。HBase几乎实现了BigTable的所有特性。它被称为一个开源的非关系型分布式数据库。
- 2010年HBase的开发速度打破了一直以来跟Hadoop版本一致的惯例,因为HBase的版本发布速度已经超越了Hadoop。它的版本号一下从0.20.x跳跃到了0.89.x。
1.3 为什么要用HBase
- HBase的存储是基于Hadoop的,采用的是Key/Value的存储方式.
- 单表数据量超千万,而且并发还挺高。
- 数据分析需求较弱,或者不需要那么灵活或者实时。
- HBase并不快,只是当数据量很大的时候它慢的不明显
凡事都不可能只有优点而没有缺点。数据分析是HBase的弱项.
1.4 你必须懂的基本概念
1.4.1 部署架构
- 部署架构:HBase有两种服务器:Master服务器和RegionServer服务器.
- HBase有一点很特殊:客户端获取数据由客户端直连RegionServer的,所以你会发现Master挂掉之后你依然可以查询数据,但就是不能新建表了.
Master服务器负责维护表结构信息,实际的数据都存储在RegionServer服务器上. RegionServer是直接负责存储数据的服务器。RegionServer保存的表数据直接存储在Hadoop的HDFS上.RegionServer非常依赖ZooKeeper服务,可以说没有ZooKeeper就没有HBase。
ZooKeeper在HBase中扮演的角色类似一个管家。ZooKeeper管理了HBase所有RegionServer的信息,包括具体的数据段存放在哪个RegionServer上.客户端每次与HBase连接,其实都是先与ZooKeeper通信,查询出哪个RegionServer需要连接,然后再连接RegionServer。
1.4.1.1 Region是什么
Region就是一段数据的集合。HBase中的表一般拥有一个到多个Region。Region有以下特性:
- Region不能跨服务器,一个RegionServer上有一个或者多个Region。
- 数据量小的时候,一个Region足以存储所有数据;但是,当数据量大的时候,HBase会拆分Region。
- 当HBase在进行负载均衡的时候,也有可能会从一台RegionServer上把Region移动到另一台RegionServer上。
- Region是基于HDFS的,它的所有数据存取操作都是调用了HDFS的客户端接口来实现的。
1.4.1.2 RegionServer是什么
RegionServer就是存放Region的容器,直观上说就是服务器上的一个服务。一般来说,一个服务器只会安装一个RegionServer服务,不过你实在想在一个服务器上装多个RegionServer服务也不是不可以。
当客户端从ZooKeeper获取RegionServer的地址后,它会直接从RegionServer获取数据。
1.4.1.3 Master是什么
可能你们会想当然地觉得Master是HBase的领导,所有的数据、所有的操作都会经过它。错!其实在HBase中Master的角色不像领导,更像是打杂的。
我们之前说过,客户端从 ZooKeeper获取了RegionServer的地址后,会直接从RegionServer获取数据。
其实不光是获取数据,包括插入、删除等所有的数据操作都是直接操作RegionServer,而不需要经过Master。
Master只负责各种协调工作(其实就是打杂),比如建表、删表、移动Region、合并等操作。它们的共性就是需要跨RegionServer,这些操作由哪个RegionServer来执行都不合适,所以HBase就将这些操作放到了Master上了。
这种结构的好处是大大降低了集群对Master的依赖。而Master节点一般只有一个到两个,一旦宕机,如果集群对Master的依赖度很大,那么就会产生单点故障问题。在HBase中,即使Master宕机了,集群依然可以正常地运行,依然可以存储和删除数据。
1.4.2 存储架构
最基本的存储单位是列(column),一个列或者多个列形成一行(row)。传统数据库是严格的行列对齐。比如这行有三个列a、b、c,下一行肯定也有三个列a、b、c。
而在HBase中,这一行有三个列a、b、c,下一个行也许是有4个列a、e、f、g。
在HBase中,行跟行的列可以完全不一样,这个行的数据跟另外一个行的数据也可以存储在不同的机器上,甚至同一行内的列也可以存储在完全不同的机器上!
每个行(row)都拥有唯一的行键(row key)来标定这个行的唯一性。每个列都有多个版本,多个版本的值存储在单元格(cell)中。若干个列又可以被归类为一个列族。
1.4.2.1 行键是什么
rowkey和MySQL、Oracle中的主键比起来简单多了。这个rowkey完全是由用户指定的一串不重复的字符串,规则随你定!不过,话虽如此,你定的rowkey可是会直接决定这个row的存储位置的。HBase中无法
根据某个column来排序,系统永远是根据rowkey来排序的。因此,rowkey就是决定row存储顺序的唯一凭证。而这个排序也很简单:根据字典排序。
1.4.2.2 列族
在HBase中,若干列可以组成列族(column family)。
建表的时候是不需要制定列的,因为列是可变的,它非常灵活,唯一需要确定的就是列族。这就是为什么说一个表有几个列族是一开始就定好的。
此外,表的很多属性,比如过期时间、数据块缓存以及是否压缩等都是定义在列族上,而不是定义在表上或者列上。
这一点做法跟以往的数据库有很大的区别。同一个表里的不同列族可以有完全不同的属性配置,但是同一个列族内的所有列都会有相同的属性,因为他们都在一个列族里面,而属性都是定义在列族上的。
一个没有列族的表是没有意义的,因为列必须依赖列族而存在.
列族存在的意义是:HBase会把相同列族的列尽量放在同一台机器上,所以说,如果想让某几个列被放到一起,你就给他们定义相同的列族。
1.4.2.3 单元格
你以为行键:列族:列就能唯一地确定一个值了吗?错!虽然列已经是HBase的最基本单位了,但是,一个列上可以存储多个版本的值,多个版本的值被存储在多个单元格里面,多个版本之间用版本号(Version)来区分。
所以,唯一确定一条结果的表达式应该是行键:列族:列:版本号(rowkey:column family:column:version)。
不过,版本号是可以省略的。如果你不写版本号,HBase默认获取最后一个版本的数据返 回给你。每个列或者单元格的值都被赋予一个时间戳。这个时间戳默认是由系统制定的,也可以由用户显示指定。
1.4.2.4 Region跟行的关系
之前提到了Region的概念,后来我们又提到了行的概念,那么他们之间的关系是什么呢?其实很简单,一个Region就是多个行的集合。在Region中行的排序按照行键(rowkey)字典排序。
1.4.3 跟关系型数据库的对比
HBase中的每一个行都是离散的。因为有列族的存在,所以一个行里面的不同列甚至被分 配到了不同的服务器上。行的概念被减弱到只有一个抽象的存在。
在实体上,把多个列标定为一个行的关键词是rowkey,这也是行这个概念在HBase中的唯一体现。
在HBase中,每一个存储语句都必须精确地写出数据是要被存储到哪个单元格,而单元格是由表:列族:行:列来定义的。
翻译过来就是你要精确地写出数据要被存储到哪个表的哪个列族的哪个行的哪个列。
如果一行有10列,那存储一行的数据得写10行的语句;而在传统数据库中存储语句(insert语句)可以把整个行的数据一次性写在行语句里面。