HBASE知识点
Posted 海边的杂货铺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HBASE知识点相关的知识,希望对你有一定的参考价值。
1.简介
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
百度百科:https://baike.baidu.com/item/HBase/7670213?fr=aladdin
2.HBase特点
特点 | 解释 |
---|---|
海量存储 | Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正式因为Hbase良好的扩展性,才为海量数据的存储提供了便利。 |
列式存储 | 列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。 |
极易扩展 | Hbase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)。 通过横向添加RegionSever的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbsae服务更多Region的能力。 |
高并发 | 由于目前大部分使用Hbase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。 |
稀疏 | 稀疏主要是针对Hbase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。 |
3.HBase和传统数据库对比
对比项 | HBase | RDBMS |
---|---|---|
硬件架构 | 类似于 Hadoop 的分布式集群,硬件成本低廉 | 传统的多核系统,硬件成本昂贵 |
容错性 | 由软件架构实现,由于由多个节点组成,所以不担心一点或几点宕机 | 一般需要额外硬件设备实现 HA 机制 |
数据库大小 | PB | GB、TB |
数据排布方式 | 稀疏的、分布的多维的 Map | 以行和列组织 |
数据类型 | Bytes | 丰富的数据类型 |
事物支持 | ACID 只支持单个 Row 级别 | 全面的 ACID 支持,对 Row 和表 |
查询语言 | 只支持 Java API (除非与其他框架一起使用,如 Phoenix、Hive) | SQL |
索引 | 只支持 Row-key,除非与其他技术一起应用,如 Phoenix、Hive | 支持 |
吞吐量 | 百万查询/每秒 | 数千查询/每秒 |
4.使用场景
场景 | 描述 |
---|---|
对象存储 | 我们知道不少的头条类、新闻类的的新闻、网页、图片存储在HBase之中,一些病毒公司的病毒库也是存储在HBase之中 |
时序数据 | HBase之上有OpenTSDB模块,可以满足时序类场景的需求 |
推荐画像 | 特别是用户的画像,是一个比较大的稀疏矩阵,蚂蚁的风控就是构建在HBase之上 |
时空数据 | 主要是轨迹、气象网格之类,滴滴打车的轨迹数据主要存在HBase之中,另外在技术所有大一点的数据量的车联网企业,数据都是存在HBase之中 |
CubeDB OLAP | Kylin一个cube分析工具,底层的数据就是存储在HBase之中,不少客户自己基于离线计算构建cube存储在hbase之中,满足在线报表查询的需求 |
消息/订单 | 在电信领域、银行领域,不少的订单查询底层的存储,另外不少通信、消息同步的应用构建在HBase之上 |
Feeds流 | 典型的应用就是xx朋友圈类似的应用 |
NewSQL | 之上有Phoenix的插件,可以满足二级索引、SQL的需求,对接传统数据需要SQL非事务的需求 |
5.HBase逻辑视图
逻辑结构例子:
RowKey |
ColumnFamily : CF1 |
ColumnFamily : CF2 |
TimeStamp |
||
Column: C11 |
Column: C12 |
Column: C21 |
Column: C22 |
||
“com.google” |
“C11 good” |
“C12 good” |
“C12 bad” |
“C12 bad” |
T1 |
Map格式化后结构:
{ "com.google": { CF1: { C11:{ T1: good }, C12:{ T1: good }, CF2: { C21:{ T1: bad }, C22:{ T1: bad } } } } |
概念 | 描述 |
---|---|
RowKey | 行键,可理解成mysql中的主键列
|
Column | 列,可理解成MySQL列 |
ColumnFamily | 列族, HBase引入的概念:
|
TimeStamp | 在每次跟新数据时,用以标识一行数据的不同版本(事实上,TimeStamp是与列绑定的)
|
Cell | 单元格
|
Region |
|
6.HBase物理存储
从上图我们看到 Row1 到 Row5 的数据分布在两个 CF 中,并且每个 CF 对应一个 HFile。并且逻辑上每一行中的一个单元格数据,对应于 HFile 中的一行,然后当用户按照 Row-key 查询数据的时候,HBase 会遍历两个 HFile,通过相同的 Row-Key 标识,将相关的单元格组织成行返回,这样便有了逻辑上的行数据。讲解到这,我们就大致了解 HBase 中的数据排布格式,以及与 RDBMS 的一些区别。
HFile会存储多个版本的rowkey, rowkey+version+列族+列 为一行文件记录
Table中的所有行都按照row key的字典序排列
Table 在行的方向上分割为多个Region
Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region
Region是HBase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上
Region虽然是分布式存储的最小单元,但并不是存储的最小单元
Region由一个或者多个Store组成,每个store保存一个columns family
每个Strore又由一个memStore和0至多个StoreFile组成
memStore存储在内存中,StoreFile存储在HDFS上
数据会先写在内存memStore中,达到阈值或者触发条件才会持久化到StoreFile中
|
行式存储 |
列式存储 |
---|---|---|
优点 |
Ø 数据被保存在一起 Ø INSERT/UPDATE容易 |
Ø 查询时只有涉及到的列会被读取 Ø 投影(projection)很高效 Ø 任何列都能作为索引 |
缺点 |
Ø 选择(Selection)时即使只涉及某几列,所有数据也都会被读取 |
Ø 选择完成时,被选择的列要重新组装 Ø INSERT/UPDATE比较麻烦 |
7.HBase架构
组件 | 职责 |
---|---|
Client |
|
Zookeeper |
|
Master |
|
Region Server |
|
8.HBase限制条件
数据量达到上亿以上时可以使用Hbase,如果只有上千或上百万行,则用传统的RDBMS。
不依赖所有RDBMS的额外特性(列数据类型, 第二索引, 事物,高级查询语言等.)
一个建立在RDBMS上应用,需要考虑在Hbase上重新构建。
要想Hbase起到比RDBMS还好的性能和充分的利用,Hbase必须在5个节点以上
Hbase原生只支持3中查询方式:基于Rowkey的单行查询、基于Rowkey的范围扫描、全表扫描
Hbase原生查询严重依赖rowkey的设计,不支持二级索引
9.rowkey设计
原则 | 说明 |
---|---|
长度原则 | RowKey是一个二进制码流,可以是任意字符串,最大长度为64KB,实际应用中一般为10~100bytes,存为byte[]字节数组,一般设计成定长。建议是越短越好,不要超过16个字节。原因一是数据的持久化文件HFile中是按照KeyValue存储的,如果RowKey过长比如100字节,1000万列数据光RowKey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;原因二是memstore将缓存部分数据到内存,如果RowKey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此RowKey的字节长度越短越好原因三是目前操作系统大都是64位,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。 |
散列原则 | 如果RowKey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将RowKey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个RegionServer实现负载均衡的几率,如果没有散列字段,首字段直接是时间信息,将产生所有数据都在一个RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。 |
唯一原则 | 必须在设计上保证其唯一性。 RowKey是按照字典排序存储的,因此,设计RowKey时候,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。 举个例子:如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为RowKey的一部分,由于是字段排序,所以可以使用Long.MAX_VALUE-timeStamp作为RowKey,这样能保证新写入的数据在读取时可以别快速命中。 |
10.二级索引
对于HBase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询。如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄。对于较大的表,全表扫描的代价是不可接受的。但是,很多情况下,需要从多个角度查询数据。例如,在定位某个人的时候,可以通过姓名、身份证号、学籍号等不同的角度来查询,要想把这么多角度的数据都放到rowkey中几乎不可能(业务的灵活性不允许,对rowkey长度的要求也不允许)。所以,需要secondary index(二级索引)来完成这件事。secondary index的原理很简单,但是如果自己维护的话则会麻烦一些。
方案 | 说明 |
---|---|
外置索引 | 例如:elasticsearch、solr 将倒排索引存储到es、solr中,先根据二级索引找到rowkey集合,再根据rowkey在hbase中查询 |
Phonenix内置索引方案 | 存储rowkey数据的时候,将索引和rowkey的对应关系在另外的地方存储起来 查询的时候先根据索引找到rowkey,再根据rowkey查找数据 |
11.Apache-Phoenix
Phoenix中文翻译为凤凰
, 其最早是Salesforce的一个开源项目,Salesforce背景是一个搞ERP的,ERP软件一个很大的特点就是数据库操作,所以能搞出一个数据库中间件也是很正常的。而后,Phoenix成为Apache基金的顶级项目。
Phoenix具体是什么呢,其本质是用Java写的基于JDBC API操作HBase的开源SQL引擎。它有如下几个功能特性:
Salted Table:
Phoenix Salted Table是phoenix为了防止hbase表rowkey设计为自增序列而引发热点region读和热点region写而采取的一种表设计手段。通过在创建表的时候指定SALT_BUCKETS来实现pre-split(预分割)。
二级索引:
类型 | 说明 |
---|---|
Covered Indexes |
即索引表中就包含你想要的全部字段数据,这样就只需要通过访问索引表而无需访问主表就能得到数据; |
Global Indexes |
全局索引适用于读多写少的场景。全局索引在写数据时会消耗大量资源,所有对数据的增删改操作都会更新索引表,而索引表是分布在各个结点上的,性能会受到影响。好处就是,在读多的场景下如果查询的字段用到索引,效率会很快,因为可以很快定位到数据所在具体结点region上,对于写性能就很慢了,因为每写一次,需要更新所有结点上的索引表数据 |
Local Indexes |
局部索引适用于写多读少场景,和全局索引类似,Phoenix会在查询时自动选择是否使用索引。如果定义为局部索引,索引表数据和主表数据会放在同一regionserver上,避免写操作时跨节点写索引表带来的额外开销(如Global Indexes)。当使用局部索引查询时,即使查询字段不是索引字段,索引表也会正常使用,这和Global Indexes是有区别的。在4.8版本之前,所有局部索引数据存放在一个单独的共享表中,4.8之后是存储在主表的一个独立的列族中。因为是局部索引,所以在client端查询使用索引时,需要扫描每个结点上的索引表以得到数据所在具体region位置,当region多时,查询时耗会很高,所以查询性能比较低,适合读少写多场景 |
IMMutable Indexing |
不可变索引主要创建在不可变表上,适用于数据只写一次不会有Update等操作,在什么场景下会用到不可变索引呢,很经典的时序数据:write once read many times 。在这种场景下,所有索引数据(primary和index)要么全部写成功,要么一个失败全都失败返回错误给客户端。不可变索引用到场景比较少 |
Mutable Indexing |
可变索引意思是在修改数据如Insert、Update或Delete数据时会同时更新索引。这里的索引更新涉及WAL,即主表数据更新时,会把索引数据也同步更新到WAL,只有当WAL同步到磁盘时才会去更新实际的primary/index数据,以保证当中间任何一个环节异常时可通过WAL来恢复主表和索引表数据。 |
性能:
总的来说,目前并没有一种很完美的方案来解决SQL查询、二级索引问题,都或多或少存在各种问题。不过HBase的Coprocessor是个好东西,很多功能可以基于此特性进行二次开发,后续可以深入研究一下。
11.参考资料:
阿里云Hbase api : https://help.aliyun.com/document_detail/52051.html?spm=a2c4g.11186623.6.557.KlTbOv
使用场景:https://blog.csdn.net/xiangxizhishi/article/details/75388971 http://www.thebigdata.cn/HBase/35830.html
滴滴hbase实践: http://www.iteye.com/news/32496 http://geek.csdn.net/news/detail/202994
二级索引/rowkey: https://www.cnblogs.com/kxdblog/p/4328699.html
hbase查询数据过程: https://www.cnblogs.com/seaspring/p/5949248.html
hbase查询块:https://blog.csdn.net/dreamershi/article/details/53321712
LSM树: https://www.cnblogs.com/yanghuahui/p/3483754.html
Phoenix : https://segmentfault.com/a/1190000002936080
hbase高性能复杂条件查询引擎: https://blog.csdn.net/bluishglc/article/details/31799255
Phoenix创建二级索引:https://blog.csdn.net/u011491148/article/details/45749807
Phoenix二级索引浅谈:http://zy19982004.iteye.com/blog/2086605
PhoenixFAQ: https://help.aliyun.com/knowledge_detail/61126.html?spm=a2c4g.11186623.4.8.ecBRxh
Phoenix系列入门(六)二级索引之Global Indexing: https://bbs.aliyun.com/detail/333001.html?spm=5176.11065265.1996646101.searchclickresult.b6851029Qe6SID
Phoenix/hbase中的salted table: https://blog.csdn.net/u011491148/article/details/45690913
浅谈Phoenix在Hbase中的应用: http://www.cnblogs.com/ballwql/p/8371234.html
Phoenix主页:http://phoenix.apache.org
Phoenix api: https://help.aliyun.com/document_detail/53716.html?spm=a2c4g.11186623.6.577.2R48eN
Phoenix 语法:http://phoenix.apache.org/language/index.html?spm=a2c4g.11186623.2.4.QtEJ8d
hbase二级索引: https://yq.aliyun.com/articles/231737
hbase技术笔记: https://cloud.tencent.com/developer/article/1006043 https://cloud.tencent.com/developer/article/1006044
hbase核心知识点: https://www.cnblogs.com/caiyisen/p/7424177.html
以上是关于HBASE知识点的主要内容,如果未能解决你的问题,请参考以下文章
Hbase框架原理及相关的知识点理解Hbase访问MapReduceHbase访问Java APIHbase shell及Hbase性能优化总结