通过了解hbase的基础概念、架构特点,底层原理等,可以了解hbase读写的特点。通过从底层理解这些特点,我们能够将hbase应用到合适的场景。
本文主要了解hbase的:
- hbase的概念、架构
- hbase的特点细节:存储拓展性、列存储、定义数据版本、查询快吗
- 应用场景、生产注意事项。
apache hbase 是 hadoop 数据库,一个分布式、可伸缩的大数据存储。hbase是一个nosql数据库,它把数据存在hdfs上。
hbase在hdfs之上提供了高并发的随机写和支持实时查询,这是hdfs不具备的。
hbase特点:
一. hbase 数据模型
1. 行存储与列式存储
1.1. 行存储
行存储系统以行的方式来组织数据。行存储将数据一行一行的写入,写入一条数据记录时,只需要将数据追加到已有数据记录后面即可。
行模式存储适合 oltp(online transaction processing)系统。因为数据基于行存储,所以数据的写入会更快。对按记录查询数据也更简单。
场景:统计整个系统今天的博客点赞数。对于行存储系统,需要将所有行数据读入内存,然后对 like_num 列做 sum 操作,从而得到结果。
我们假设磁盘一次可以读取图中 3 个方框的数据,那么这个聚合计算需要 n(n/3=数据量)次磁盘访问。
1.2. 列存储
同样是上面的示例数据,我们来看列式存储是怎样组织数据的。
列式存储将每一列的数据组织在一起。
利于对于列的操作,如上面我们说到的统计所有 like_num 之和。其过程将如下:
依然假设磁盘一次可以读取 3 个方框的数据(实际按 byte 读取)。可以看出按列存储组织数据的方式,只需要 1 次磁盘操作就可以完成。
列式存储也有不利的一面。首先就表现在数据写入上。
hbase是怎么存储的?我们下面讨论。
对比:
2. hbase 数据模型
2.1. 模型概览
概念 | 解释 |
---|---|
name space | 1. 命名空间,类似于关系型数据库的 database 概念,每个命名空间下有多个表。 2. hbase有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 hbase 内置的表,default 表是用户默认使用的命名空间。 |
region | 1. 类似于关系型数据库的表概念。 2. 不同的是,hbase 定义表时只需要声明列族即可,不需要声明具体的列。这意味着,往 hbase 写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,hbase 能够轻松应对字段变更的场景。 |
row | 1. hbase 表中的每行数据都由一个 rowkey 和多个 column(列)组成。 2. 数据是按照 rowkey的字典顺序存储的,并且查询数据时只能根据 rowkey 进行检索,所以 rowkey 的设计十分重要(热点数据,同类数据下的实时需求)。 |
rowkey | rowkey又叫行键,它是有序的(字典顺序) |
column | 1. hbase 中的每个列都由 column family(列族)和 column qualifier(列限定符)进行限定,例如 info:name,info:age。 2. 建表时,只需指明列族,而列限定符无需预先定义。 |
time stamp | 用于标识数据的不同版本,每条数据写入(新增、更新、删除等操作都是写入)时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 hbase 的时间。 |
cell | 由{rowkey, column family:column qualifier, time stamp} 确定一条数据的单元。 |
接下来重点讲解几个和关系型数据库不同的概念。
2.2. 列与列族
hbase的列不是我们在关系型数据库所想象中的列。
hbase的列(column)都得归属到列族(column family)中。在hbase中用列修饰符(column qualifier)来标识每个列。在hbase里,先有列族,后有列。
什么是列族?可以简单理解为:列的属性类别
什么是列修饰符?在列族下用列修饰符来标识一列。
看一个的例子:
hbase表的每一行中,列的组成都是灵活的,行与行之间的列不需要相同。换句话说:一个列族下可以任意添加列,不受任何限制。
2.3. 时间戳:定义数据版本
数据写到hbase的时候都会被记录一个时间戳,这个时间戳被我们当做一个版本。比如说,我们修改或者删除某一条的时候,本质上是往里边新增一条数据,新增了记录的版本。
2.4. hbase的key-value
hbase本质上其实就是key-value
的数据库,那在hbase里边,key是什么?value是什么?
每个keyvalue都由4个部分构成,分别为key length,value length,key和value。其中
- value就是一串纯粹的二进制数据。
要准确定位一条数据,那就需要知道:rowkey+column+时间戳。
二. hbase架构
1. hbase读写流程简述
1、client客户端,它提供了访问hbase的接口,并且维护了对应的cache来加速hbase的访问。
2、zookeeper不存储meta表,meta表还是放到regionserver里的region存储的,和其他表没啥太大区别,相当于其他表的索引,而zookeeper放的是meta表的索引,相当于索引的索引。
查找快的原因:
3、hregionserver它是处理客户端的读写请求,负责与hdfs底层交互,是真正干活的节点。
总结大致的流程就是:
2. hregionserver内部
先来思考一个问题:
hbase一张表的数据会分到多台机器上的。那hbase是怎么切割一张表的数据的呢?用的就是rowkey来切分,其实就是表的横向切割。
内部数据流转:hregion <- store(hfile) <- memstore <- hlog
名字 | 说明 |
---|---|
region | 一个region存储hbase表的一部分数据,多个store组成一个region。 |
storefile(hfile) | 1. 物理结构:保存实际数据的物理文件,storefile 以 hfile 的形式存储在 hdfs 上。每个 store 会有一个或多个 storefile(hfile),数据在每个 storefile 中都是有序的。 2. 用于存储列族:一个列族的数据是存储在一起的,即存储到一个hfile中。所以我们可以认为hbase是基于列族存储的。 3. hfile 以keyvalue 形式存储数据。 |
memstore | 写缓存,由于 hfile 中的数据要求是有序的,所以数据是先存储在 memstore 中,排好序后,等到达刷写时机才会刷写到 hfile,每次刷写都会形成一个新的 hfile。 |
hlog | 1. 为了防止数据丢失:由于数据要经 memstore 排序后才能刷写到 hfile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写到hlog中,然后再写入 memstore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。 2. 顺序写: hlog 是顺序写到磁盘的,所以速度还是挺快的(类似于kafka的感觉) |
小结:
3. hmaster
上面我们知道regionserver管理所有region,负责dml操作,接下来我们看hmaster。
hmaster负责ddl操作、管理所有regionserver:
三. 特性讨论
1. 大数据存储与拓展
- 数据高可靠性:hbase本身高可靠性特性以及hdfs的高可靠性。
2. hbase速度真的很快?
2.1. 为何hbase速度很快?
hbase能提供实时计算服务主要原因是由其架构和底层的数据结构决定的, 即由
2.1.1. 写入快的原因
hbase的写入速度快是因为
2.1.2.查询快的原因
a. region定位
通过rowkey定位数据所在region
b. lsm树型结构
读取速度快是因为它使用了 lsm树型结构(ing),而不是b或b+树。磁盘的顺序读取速度要比寻找磁道速度快很多。
hbase的存储结构使得磁盘寻道时间在可预测范围内,并且rowkey任意连续数量的记录都不会引发额外的寻道开销。
c. lru cache算法 + memstore内存
hbase首先会在 缓存(blockcache)中查找,它采用了 lru(最近最少使用算法),如果缓存中没找到,会从内存中的memstore中查找,只有这两个地方都找不到时,才会加载hfile中的内容,而上文也提到了读取hfile速度也会很快,因为节省了寻道开销。
小结:
2.1.3. 举例说明
hbase是根据rowkey查询的,我们看下如何快速定位rowkey
hbase适合存储pb级别的海量数据(百亿千亿量级条记录),如果根据记录主键rowkey来查询,能在几十毫秒返回数据。
2.2. 查询效率什么情况下会降低
hbase适合大数据量的查询,但并不适合大范围的查询,本质上hbase是put、get kv对,海量数据下跑类似select一样的检索scan一遍全表,且因为分布式的原因查询效率会随着查询范围的增大导致查询效率降低。
3. 有限的查询方式
3.1.不适合复杂查询
hbase作为一种kv数据库,数据访问模式以主键为核心,当面对非主键查询时,其原生解决方案无法满足大多数联机应用的性能需求。
3.2. 不支持sql查询
与传统的关系型数据库不同,hbase不支持sql查询,也没有标准的关系型数据库中所定义的表关系,也不支持多表联合查询。
其次,由于hbase是面向列(column)的数据存储模型,它可以存储大量稀疏的数据,而这种数据在关系型数据库中一般是难以处理的,需要对数据进行多表关联才能实现。因此,在hbase中使用sql查询的效率和灵活性都是相对较低的。
实际使用过程中,可以使用hbase提供的api或者其他工具来实现数据的读写操作。
public class hbasemanager {
public static void main(string[] args) throws ioexception {
//创建hbase配置对象
configuration config = hbaseconfiguration.create();
//设置zookeeper地址,zookeeper是hbase的元数据存储位置
config.set("hbase.zookeeper.quorum", "localhost");
//创建hbase连接
connection conn = connectionfactory.createconnection(config);
//获取hbase表对象
table table = conn.gettable(tablename.valueof("test_table"));
//创建hbase行键对象
byte[] rowkey = bytes.tobytes("rowkey1");
//创建hbase查询对象
get get = new get(rowkey);
//获取hbase行数据
result result = table.get(get);
//读取hbase列数据
byte[] value = result.getvalue(bytes.tobytes("cf"), bytes.tobytes("col1"));
4. 列存储的特点
四、适合的业务场景
针对某些特点的数据可以使用 hbase 高效地解决,如以下的应用场景。
1. 写密集型但相对读数量较小的应用
京东用hbase存储卖家操作日志,即几十万商家时时刻刻进行的各种操作。以便进行分析,并且可以保证商家可以精确查询自己的各种操作。卖家操作日志的特点是:数据量大、实时性强、增多查少。
因此,hbase适合做海量数据(亿万条记录)的最底层数据源。
2. 搜索引擎
hbase 是 google bigtable 的开源实现,而 google 公司开发 bigtable 是为了它的搜索引擎应用。
这里举例:基于 elasticsearch 存储的hbase二级索引方案
一级索引的限制
添加二级索引
采用elasticsearch存储hbase的索引信息,以支持复杂高效的查询功能。
优点:各取所长,发挥两个组件各自的优势
成效
3. 车联网数据的收集
车联网系统是利用车载设备收集车辆运行时产生的各项数据,通过网络实时上传,在平台进行动态分析和利用。
hbase采用lsm存储模型,可以从容应对高并发写入的场景,同时也能保证读时延在可接受的范围内。同时hbase具有良好的水平扩展能力。通过增减regionserver来实现对存储容量动态调整,满足对使用成本的要求。
4. 标签数据(稀疏矩阵)的存储
标签数据是稀疏矩阵的代表,描述了实体的各类属性,主要应用于智能推荐、商务智能或营销引擎等领域。
使用hbase存储时,未指定value的列不会占用任何的存储空间,且hbase对于column的增删极为容易,有利于应对未来属性的扩张。
5. 用户交互数据
例如,facebook 里的 like 按钮,每次用户 like —个特定主题,计数器增加一次。facebook 使用 hbase 的计数器来计量人们 like 特定网页的次数。博主可以得到近乎实时的、用户 like 他们网页的数据信息。他们可以据此更敏捷地判断应该提供什么内容。
6. 广告效果和点击流
五. 用在生产环境前的注意事项
hbase从本身原理和特性上保证了其高可用、高可靠性,以及分布式全内存异步的高写入性能,那么最终用在生产前需要注意以下几个方面?
1. 查询条件
hbase查询条件简单,只支持基于主键rowkey索引,即只能通过rowkey进行查询,不能像其他数据库一样使用多条件复杂查询,不支持二级索引,因此选型前,需确认是否能满足业务需求。
2. rowkey设计要求较高
2.1. rowkey设计
设计rowkey时要保证rowkey是唯一的,毕竟它是行键,其次为了带来更好的满足业务需求,我们可以使用时间戳、自增数据、组合键(例如:userid_regionid_timestamp)等方式。
2.2. 根据rowkey查询
在hbase里边提供了:全局扫描、根据一个rowkey进行查询、根据rowkey过滤的范围查询等三种方式。
a. 根据rowkey进行单条查询
从0.96版本之后,hbase为二层查询架构。
rowkey是会按字典序排序的,hbase表会用rowkey来横向切分表。
hregion有start-key
和end-key
两个属性,用于标识rowkey的范围。当读写时,我们通过rowkey
+[start-key,end-key)
定位到hregion,也就定位到hregionserver。
b. 根据rowkey范围查询的场景
2.3. 热点问题处理
由于我们的rowkey是以字典序排序的,如果我们对rowkey没有做任何处理,那就有可能存在热点数据(某类数据会出现很集中的现象)的问题。
- 方式2 : 只知道rowkey的组成大致的范围时:
- 方式3:生成rowkey时,进行加盐或者哈希的处理,可以缓解数据热点问题。
hbase是key/vale数据库,也只能通过key(即rowkey)来查询数据,rowkey的设计非常重要,一个优秀的rowkey设计,即可以满足查询业务需求,同时也能让数据均衡分布在集群中的节点上。提升读写性能。
3. 不太适合大范围key查询
从hbase的存储原理可知,其根据rowkey字节范围进行分区分文件存储,大范围的数据查询会使查询落到多个不同的regionserver上,所以大范围的rokey查询,查询效率会比较低下。
4. hbase部署相对复杂,运维成本高
部署hbase集群之前,首先要部署hadoop集群,这包括hdfs、yarn、mapredue等一系列组件,其次还要部署zookeeper集群。
在这两块的服务都正常部署启动后,才能部署hbase集群,此外还包括监控运维等服务组件。
发表评论