0. 背景: 关系型数据库的极限和CAP理论
传统的关系型数据库,当用户表的数据大道几千万甚至几亿级别的时候,对单挑数据的检索将花费数秒甚至分钟级别。我们通常的解决方案为给表增加索引,或者在程序中优化。
后来人们尝试将关系型数据库做成分布式,将压力分摊到多个服务器上。
但是,随之而来的问题是很难保证原子性(ACID)。
然后,又增加了一些必要的操作,原子性保证了,性能却下降了。
20世纪90年代初期Berkerley大学的Eric Brewer提出了CAP(Consistency Availability and Partition tolerance)理论, 如下:
- Consistency(一致性): 数据一致更新,所有的数据变动都是同步的
- Availability(可用性): 良好的响应性能
- Partition tolerance(分区容错性): 可靠性
得到的定理是: 任何分布式系统只可同事满足2个条件,没法3者兼顾。
NoSQL的产生
NoSQL并不是没有SQL,而是Not Only SQL。
NoSQL和传统的关系型数据库相比,它对事务性的要求并不严格,甚至可以说是马虎。
在Web2.0的时代,海量信息能造成网站的宕机。
为了保证在部分机器宕机的情况下依然可以正常运行,我们可以把一份数据复制成好几份放在好几个地方。
老话说的好: 不要把鸡蛋放在一个篮子里。
HBase正是NoSQL数据库家族中的一员。
数据库百花齐放的时候到来了!
2. HBase简介
2007年Powerset公司的开发人员研发了HBase,刚开始它只是Hadoop的一部分。
2008年HBase成为了Apache的顶级项目,成为一个开源的非关系型分布式数据库。
2010年HBase更换logo为海豚,从hadoop版本号独立开来。
- HBase的存储是基于Hadoop的HDFS
- HBase采用Key/Value的存储方式,随着数据量增大,几乎不会导致查询性能的下降
- HBase是一个列式数据库,当表字段很多的时候,可以把字段分机器存储
- HBase总和上述的存储特性,代价是: 存储少量数据也不会很快
(HBase并不快,但数据量很大的时候它慢得不明显)
什么场景下该使用HBase?
- 单表数据量超千万
- 单标并发量高
- 数据分析需求较弱
什么场景下不适合使用HBase?
- 数据分析,例如报表
- 单表数据量不高,没过千万
3. HBase的一些基本概念
HBase的服务器分为2种:
Master和ResionServer,它们之间是一对多关系,一个集群中一个Master对应多个RegionServer
Master: 负责维护表结构信息
RegionServer: 负责存储实际的数据
这样就会导致的结果是: Master挂掉之后你依然可以查询数据,只是不能新建表了
RegionServer保存的表数据直接存储在Hadoop HDFS上。
image.png关于ZooKeeper
HBase非常依赖ZooKeeper, ZooKeeper管理了所有HBase的RegionServer的信息。
image.png什么是Region?
Region就是一段数据的集合。
一个表一般有一个或者多个Region。
- Region不能跨服务器
- 数据量小的时候,一个region存储所有数据; 数据量大的时候, HBase会拆分region。
- Region的所有操作基于HDFS
什么是RegionServer?
RegionServer是存放Region的容器。
你可以认为它是服务器上的一个服务。
一般来说,一台服务器只能安装一个RegionServer。
什么是Master?
Master更像是一个打杂的。
它负责各种协调工作,比如建表,删表,移动和合并Region等操作。
它们的共同点就是都需要跨RegionServer, 所以这些操作由那个RegionServer来执行都是不合适的。
4. 理解HBase的存储结构
列(column)
HBase最基本的存储单位是列(column)。
行(row)
一个或多个列形成一行(row)。
传统的关系型数据库是严格的行列对齐。
例如有3列a,b,c, 每一行必然都有a,b,c这3列。
HBase不是这样的。
一行有a,b,c三列,下一行可能就是不同的4列a,e,f,g。
同一行的数据可能存储在不同的机器上。
同一行的列也可以存储在不同的机器上。
行键(row key)
每一行都有唯一的行键(row key)。
行键(row key)用来标识这个行的唯一性。
行键(row key)是由用户指定的一串不重复的字符串,它会决定这个row的存储位置,系统会根据它来进行排序。
eg:
row-1
row-11
row-2
如果你插入数据的时候,不小心用了之前已经存在的rowkey, 那就会把之前存在的row更新掉。
之前已经存在的值会被放到单元格(cell)-后面介绍的历史记录里,并不会丢掉。
你需要带上版本参数才可以找到这个值。
单元格(cell)
每个列都有多个版本,多个版本的值存储在单元格(cell)中。
列族(column family)
若干个列可以组成列族。
建表的时候需要一开始指定好列族,但不需要指定列。
HBase完整的列的表示方法: 列族:列名
eg:
employee:name
employee:age
网友评论