简介
1.1Hadoop
1970年开始,大多数公司数据存储和维护使用的关系型数据库
大数据技术出现后,拥有海量数据的公司选择像hadoop来出差农户海量数据
Hadoop使用分布式文件系统HDFS存储海量数据,并使用Mapreduce来处理,擅长存储各种格式的庞大的数据
1.2Hadoop局限
Hadoop主要实现批量数据处理,并通过顺序方式访问数据
要查找数据必须搜索整个数据集,如果要做随机读取,效率较低
1.3 HBase和NoSQL
NoSQL是一个通用术语,泛指不使用SQL的非关系型数据库
HBase是BigTable的开源Java版本。是建立在HDFS之上,提供高可靠性、高性能、列存储、可伸缩,实时读写NoSQL的数据库系统。
HBase仅能通过主键(row key)和主键range来检索数据,紧支持单行事务
用来存储结构化和半结构化的松散数据
查询功能简单,不支持join,不支持复杂事务,更像是一个数据存储,而不是数据库,缺少RDBMS中的许多特性,如列的类型、二级索引
与Hadoop一样,HBase主要依靠横向扩展增加存储和处理能力
HBase表的特点
大:可以有上十亿行、上百万列
面向列:面向列(簇)的存储和权限控制,列(簇)独立检索
洗漱:对于为null的列,并不占用存储空间,因此表可以设计的非常稀疏
1.4 应用场景
1.4.1 对象存储
头条类、新闻类的新闻、网页、图片存储在HBase中,一些杀毒软件公司,病毒库也村子HBase中
1.4.2 时序数据
HBase之上有OpenTSDB模块模块,可以满足时许场景的需要(还有一个时序数据存储的库Druid)
1.4.3 推荐画像
用户画像,是一个比较大的稀疏矩阵库,蚂蚁金服的风控就是构建在HBase之上
1.4.4 时空数据
轨迹、气象网格、嘀嘀打车、车联网
1.4.5 CubeDB OLAP
Kylin一个cube的分析工具,底层数据就是存储在Hbase中,不少客户自己基于离线计算cube存储在Hbase之中,满足在线报表查询分析。
1.4.6 消息/订单
电信、银行领域订单底层的存储
1.4.7 Feeds流
朋友圈类似的内容点赞、评论
1.4.8 NewSQL
Hbase之上有Phoenix的插件,可以满足二级索引、SQL的需求
1.4.9 其他
存储爬虫数据
海量数据备份
短网址
。。。
1.5发展历程
2006年11月 Google发布BigTable论文
2007年10月发布第一个可用的HBase版本,基于Hadoop0.15.0
2008年1月,HBase成为Hadoop的一个字形目
2010年5月,HBase成为Apache的顶级项目
1.6 HBase特点
强一致性读写
HBase不是最终一致的数据存储,非常适合计数器高速聚合等任务
自动分块
Hbase表通过Region分布在集群上,随着数据的增长,区域被自动拆分和重新分布
自动RegionServer故障转移
hadoop/HDFS继承
Mapreduce,可以使用HBase作为数据源
Java Client API
Thrit/Rest API
快缓存和布隆过滤器
运行管理
1.7 RDBMS 和HBase
关系数据库(RDBMS):以表的形式存在,支持FAT、NTFS、EXT、文件系统,使用主键(PK),外部中间件支持分库分表,使用行列、单元格、数据总量依赖于服务器配置,中心化,具有ACID,适合存储结构化数据、支持事务、支持jion
HBase:结构以表的形式存在,以表的形式存在,支持HDFS、使用行键,原生支持分布式存储使用,行列,列簇,使用API、Mapreduce,Spark访问,面向列簇,即每一个列簇都是一个连续的单元格,不支持ACID,不支持事务适合结构化和非结构化数据
1.8 HDFS和HBase
HDFS:存储大型文件、不是一个通用的文件系统,不支持快速查询
HBase:构建在HDFS之上,大型表提供快速积累查找和更新,数据存储放在HDFS中名为StoreFile的索引中,以便高速查找。
Hbase适合快速查询等需求,不适合做大规模的OLAP,因为不支持jion
1.9 Hive与HBase
Hive:数据仓库工具,Hive的本质是相当于将HDFS中已经存储的文件在mysql中做了一个双射关系,以便HQL去管理查询,用于数据分期、清洗,Hive适用于离线数据分析和清洗,延迟较高,基于HDFS、Mapreduce之上
HBase:Nosql数据库,存储结构化和非结构化数据,适用于单表非关系型数据存储,不适合关联查询
Hive和HBase是两种基于Hadoop的不同的技术
Hive是一种类SQL的引擎,并且运行Mapreduce任务
HBase是一种在Hadoop之上的NoSQL的Key-Value数据库
两种工具可以同时使用,一般用在场景非常复杂,数据量特别巨大的情况。
集群搭建
进入到软件包目录
cd /export/software/
#解压
tar -xvzf hbase-2.1.0.tar.gz -C ../server/
# 进入hbase
cd /export/server/hbase-2.1.0/
配置
# 进入conf
cd conf
#编辑
vim hbase-env.sh
#设置一下行号
: set nu
#编辑,添加下面内容
export JAVA_HOME=/export/server/jdk1.8.0_65/
export HBASE_MANAGES_ZK=false
# 编辑hbase-site.xml
vim hbase-site.xml
<configuration>
<!-- HBase数据在HDFS中的存放的路径 -->
<property>
<name>hbase.rootdir</name>
<value>hdfs://node1.btks.cn:8020/hbase</value>
</property>
<!-- Hbase的运行模式。false是单机模式,true是分布式模式。若为false,Hbase和Zookeeper会运行在同一个JVM里面 -->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- ZooKeeper的地址 -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>node1.btks.cn,node2.btks.cn,node3.btks.cn</value>
</property>
<!-- ZooKeeper快照的存储位置 -->
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/export/server/zookeeper/data</value>
</property>
<!-- V2.1版本,在分布式情况下, 设置为false -->
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
</configuration>
配置环境变量
vim /etc/profile
export HBASE_HOME=/export/server/hbase-2.1.0
export PATH=$PATH:${HBASE_HOME}/bin:${HBASE_HOME}/sbin
source /etc/profile
复制第三方库
cp $HBASE_HOME/lib/client-facing-thirdparty/htrace-core-3.1.0-incubating.jar $HBASE_HOME/lib/
修改regionservers文件
vim regionservers
#删除localhost
#添加以下内容
node1.btks.cn
node2.btks.cn
node3.btks.cn
文件分发
cd /export/server/
scp -r hbase-2.1.0/ root@node2:$PWD
scp -r hbase-2.1.0/ root@node3:$PWD
# 分发profile,并加载
cd /etc/
scp profile root@node2:$PWD
scp profile root@node3:$PWD
#在node2和node3上分别
source /etc/profile
启动
# 启动zookeeper
startZK.sh
# 启动hdfs
start-dfs.sh
#启动Hbase
验证
hbase shell
status
WebUI
http://node1:16010/master-status
安装目录介绍
目录名 | 说明 |
bin | 所有hbase相关的命令都在该目录存放 |
conf | 所有的hbase配置文件 |
hbase-webapps | hbase的web ui程序位置 |
lib | hbase依赖的java库 |
logs | hbase的日志文件 |
硬件配置参数参考
(本小节完全来源与黑马教程,作者没有实战,仅供参考)
针对大概800TB存储空间的集群中每个Java进程的典型内存配置:
进程 | 堆 | 描述 |
NameNode | 8 GB | 每100TB数据或每100W个文件大约占用NameNode堆1GB的内存 |
SecondaryNameNode | 8GB | 在内存中重做主NameNode的EditLog,因此配置需要与NameNode一样 |
DataNode | 1GB | 适度即可 |
ResourceManager | 4GB | 适度即可(注意此处是MapReduce的推荐配置) |
NodeManager | 2GB | 适当即可(注意此处是MapReduce的推荐配置) |
HBase HMaster | 4GB | 轻量级负载,适当即可 |
HBase RegionServer | 12GB | 大部分可用内存、同时为操作系统缓存、任务进程留下足够的空间 |
ZooKeeper | 1GB | 适度 |
推荐:
Master机器要运行NameNode、ResourceManager、以及HBase HMaster,推荐24GB左右
Slave机器需要运行DataNode、NodeManager和HBase RegionServer,推荐24GB(及以上)
根据CPU的核数来选择在某个节点上运行的进程数,例如:两个4核CPU=8核,每个Java进程都可以独立占有一个核(推荐:8核CPU)
内存不是越多越好,在使用过程中会产生较多碎片,Java堆内存越大, 会导致整理内存需要耗费的时间越大。例如:给RegionServer的堆内存设置为64GB就不是很好的选择,一旦FullGC就会造成较长时间的等待,而等待较长,Master可能就认为该节点已经挂了,然后移除掉该节点
3、HBase数据类型
3.1简介
在Hbase中,数据存储在行和列的表中。看起来和RDBMS一样,但将Hbase表看成一个多维度的map结构更容易理解。
ROWKEY | C1列簇 | C2列簇 | ||||
rowkey | 列1 | 列2 | 列3 | 列4 | 列5 | 列6 |
样例
rowkey | 0001 |
C1 | 列1=>值1 列2=>值2 列3=>值3 |
C2 | 列5=>值5 列6=>值6 列7=>值7 |
3.2 术语
3.2.1表
Hbase中的数据是用表来组织的(支持分布式)
HBase中表由多个行组成
3.2.1 行(row)
Hbase中的行由行键和多个列组成的
HBase中数据存储按行键字典序排列
行键设计非常重要,尽量相关的数据存储在一起,但是要防止数据倾斜,举例,存储网站的域,如果行键是域,则应该将将域名反转后存储(org.apache.base)
3.2.3列(column)
Hbase中的列包含列簇(Column Family)和列限定符(Column Qualifier)组成,列的表示方法:
列簇名:列限定符,例如:C1:USERID
3.2.4列簇(column Family)
数据都是以列存储的,也成为列式数据库,出于性能原因,列簇将一组列和值组织在一起,每个列族都有存储属性,是否应该缓存在内存中,数据如何被压缩,行键如何编码等
每一行都有相同的列族,但列族不存任何内容
Hbase建立所有列族保持一样的列,同一类的列放在同一个列族
3.2.5列限定符
列族中包含列限定符,这样可以为存储提供索引,类簇是创建表时固定的
不同的行可能会存在不同的列标识符
3.2.6 单元格(cell)
行、列簇、列限定符的组合
包含一个值和一个时间戳
单元格的内容都以二进制保存
3.3 概念模型
rowkey | timestamp | columnfamily contents | columnfamily ancher | columnfamily people |
com.btks.zkw | t1 | contents:内容 | anchor:cn="CNN" | |
com.btks.zkw | t2 | |||
com.btks.zkw | t3 | contents:内容2 |
上面的表,表示在Hbase的一行,三个列族
概念模型抽象
rowkey | 列簇1 | 列簇2 | ||||
列1 | 列2 | 列3 | 列4 | 列5 | 列6 |
按照个人理解,HBase存储结构可以简单理解为 List<Map<String,Object>>,下标索引相当于rowkey,string相当于列。