一、Hbase介绍
NoSQL概述:not only SQL,非关系型数据库
- 指不遵循传统RDBMS模型的数据库
- 数据是非关系的,且不使用SQL作为主要查询语言
- 解决数据库的可伸缩性和可用性问题
- 不针对原子性或一致性问题
NoSQL和关系型数据库对比
对比 | NoSQL | 关系型数据库 |
---|---|---|
常用数据库 | HBase、MongoDB、Redis | Oracle、DB2、MySQL |
存储格式 | 文档、键值对、图结构 | 表格式,行和列 |
存储规范 | 鼓励冗余 | 规范性,避免重复 |
存储扩展 | 横向扩展,分布式 | 纵向扩展(横向扩展有限) |
查询方式 | 结构化查询语言SQL | 非结构化查询 |
事务 | 不支持事务一致性 | 支持事务 |
性能 | 读写性能高 | 读写性能差 |
成本 | 简单易部署,开源,成本低 | 成本高 |
NoSQL和BI、大数据的关系
BI(Business Intelligence):商务智能
- 它是一套完整的解决方案
- BI应用涉及模型,模型依赖于模式
- BI主要支持标准SQL,对NoSQL支持弱于关系型数据库
NoSQL和大数据相关性较高,但是NoSQL != 大数据
- NoSQL产品是为了帮助解决大数据存储问题,但是大数据不仅仅包含数据存储的问题
- 通常大数据场景采用列存储数据库
Hbase概述
HBase是一个领先的NoSQL数据库
- 是一个面向列存储的NoSQL数据库
- 是一个分布式Hash Map,底层数据是Key-Value格式
- 基于Google Big Table论文
- 使用HDFS作为存储并利用其可靠性
HBase特点
- 数据访问速度快,响应时间约2-20毫秒
- 支持随机读写,每个节点20k~100k+ ops/s
- 可扩展性,可扩展到20,000+节点
- 高并发
hbase应用场景
增量数据-时间序列数据
- 高容量,高速写入
- HBase之上有OpenTSDB模块,可以满足时序类场景,比如传感器,系统监控,股票行情监控等
信息交换-消息传递
- 高容量,高速读写
- 通信、消息同步的应用构建在HBase之上,比如email,FaceBook等
内容服务-Web后端应用程序
- 高容量,高速读写
- 头条类、新闻类的的新闻、网页、图片存储在HBase中
二、HBase物理架构
看图说话
HMaster的作用
-
是HBase集群的主节点,可以配置多个,用来实现高可用。
-
处理元数据的变更
-
监控RegionServer
- 监控RegionServer,防止RegionServer宕机。
-
负责RegionServer的负载均衡
- 防止数据分配不均,造成资源浪费,可能会出现一台RegionServer很忙,另一台很闲。
-
处理RegionServer故障转移
- HMaster健康RegionServer,当其中一个RegionServer放生故障,HMaster会及时的将故障转移,启动另一台计算机的RegionServer。
-
通过ZooKeeper发布自己的位置给客户端
RegionServer负责管理维护Region,负责存储HBase实际数据
-
一个RegionServer包含一个WAL、一个BlockCache (读缓存)和多个Region
- WAL是日志溢写,会把日志写给HMaster,HMaster才能知道存进去了多少个数据。
-
一个Region包含多个存储区,每个存储区对应一个列族
-
一个存储区由多个StoreFile和MemStore组成
-
一个StoreFile对应于一个HFile和一个列族
-
HFile和WAL作为序列化文件保存在HDFS上
-
Client与RegionServer交互
功能
- 负责管理HBase的实际数据
- 处理分配给它的Region
- 刷新缓存到HDFS
- 维护HLog
- 执行Compaction
- 负责处理Region分片
BlockCache与MemStore
HBase在实现中提供了两种缓存结构:MemStore和BlockCache。其中MemStore称为写缓存,HBase执行写操作首先会将数据写入MemStore,并顺序写入HLog,等满足一定条件后统一将MemStore中数据刷新到磁盘,这种设计可以极大地提升HBase的写性能。不仅如此,MemStore对于读性能也至关重要,假如没有MemStore,读取刚写入的数据就需要从文件中通过IO查找,这种代价显然是昂贵的!BlockCache称为读缓存,HBase会将一次文件查找的Block块缓存到Cache中,以便后续同一请求或者邻近数据查找请求,可以直接从内存中获取,避免昂贵的IO操作。MemStore相关知识可以戳这里,本文将重点分析BlockCache。
三、HBase逻辑架构
- Rowkey(行键)是唯一的并已排序
- Schema可以定义何时插入记录
- 每个Row都可以定义自己的列,即使其他Row不使用
- 相关列定义为列族
- 使用唯一时间戳维护多个Row版本
- 在不同版本中值类型可以不同
- HBase数据全部以字节存储
四、如何优化Hbase的存储读取效率
Hbase优化,涉及到Rowkey行键的寻址问题。一般来说,行键会被转成计算机能识别的字节码,一般来说计算机一个字节有8个字位,字位也分高字位和低字位。计算机寻址是一个字节一个字节的寻址,如果说行键设计成8的倍数是最好寻找的,如果设置成一个字节有点少,最多只能有255个行键,不太方便,可以设置成2个字节是接16个字位,这样既满足了存储要求,也加快了寻址速率。
hbase常用命令
##基本命令
version
status
whoami
help
##操作命令
##创建表
create 'customer', {NAME=>'addr'}, {NAME=>'order'}
##列出所有表
list
##查看表信息
desc 'customer'
##判断表是否存在
exists 'customer'
##表中插入数据语法:put ’<table name>’,’row_key1’,’<colfamily:colname>’,’<value>’
put 'customer', 'jsmith', 'addr:city', 'montreal'
put 'customer', 'jsmith', 'addr:state', 'ON'
put 'customer', 'jsmith', 'order:numb', '123456'
put 'customer', 'jsmith', 'order:date', '2015-12-19'
##根据rowkey获取数据
get 'customer', 'jsmith'
##获取指定CF数据的两种方式
get 'customer', 'jsmith','addr'
get 'customer', 'jsmith',{COLUMNS=>['addr']}
##获取指定列的数据
get 'customer', 'jsmith',{COLUMNS=>['order:numb']}
##更新数据
put 'customer', 'jsmith', 'order:numb', '654321'
get 'customer', 'jsmith',{COLUMNS=>['order:numb']}
##修改多版本存储
alter 'customer',NAME=>'order', VERSIONS=>5
##插入多行数据
put 'customer', 'jsmith', 'order:numb', '1235'
put 'customer', 'jsmith', 'order:numb', '1236'
put 'customer', 'jsmith', 'order:numb', '1237'
put 'customer', 'jsmith', 'order:numb', '1238'
put 'customer', 'njones', 'addr:city', 'miami'
put 'customer', 'njones', 'addr:state', 'FL'
put 'customer', 'njones', 'order:numb', '5555'
put 'customer', 'tsimmons', 'addr:city', 'dallas'
put 'customer', 'tsimmons', 'addr:state', 'TX'
put 'customer', 'jsmith', 'addr:city', 'denver'
put 'customer', 'jsmith', 'addr:state', 'CO'
put 'customer', 'jsmith', 'order:numb', '6666'
put 'customer', 'njones', 'addr:state', 'TX'
put 'customer', 'amiller', 'addr:state', 'TX'
##多版本数据查询
get 'customer', 'jsmith', {COLUMNS=>['order:numb'], VERSIONS => 5}
##全扫描
scan 'customer', {COLUMNS=>['order:numb'], VERSIONS => 2}
##指定rowkey范围查询
scan 'customer', {STARTROW => 'j', STOPROW => 't'}
##统计表中数据格式
count 'customer'
##删除语法
##delete '<table_name>', '<row_key>', '<column_name >', <time_stamp_value>
##deleteall '<table_name>', '<row_key>'
##删除整行
deleteall 'customer','njones'
##删除一个单元格的值
delete 'personal','2','personal_data:age',1505286495492
##删除一列
delete 'customer','njones','addr:city'
##删除一个列族数据,下面的操作是不正确的
##delete 'customer', 'jsmith', 'addr'
##下面操作是正确的
alter 'customer','delete'=>'addr'
##启动表,禁用表
disable 'customer'
is_disabled 'customer' / enable 'customer'
##清空表
truncate 'customer'
##删除表,注意删除之前,如果表的状态不是disabled,需要先禁用表,才能删除,否则报错
drop 'customer'