hbase简介
hbase 是非关系型数据库
hadoop database 是一个高可用,高性能,面向列的kv键值对,可伸缩,实时读写的分布式数据库
利用hadoop hdfs 作为其文件存储系统,系统hadoop mapreduce 来处理hbase中海量数据,利用zookeeper作为其分布式协同服务
主要用来存储非结构化和半结构化的松散数据(列存 nosql数据库)
与传统数据库的对比:
1、传统数据库遇到的问题:
1)数据量很大的时候无法存储;
2)没有很好的备份机制;
3)数据达到一定数量开始缓慢,很大的话基本无法支撑;
2、HBASE优势:
1)线性扩展,随着数据量增多可以通过节点扩展进行支撑;
2)数据存储在hdfs上,备份机制健全;
3)通过zookeeper协调查找数据,访问速度快。
hbase 数据模型
HBase是一个面向列的数据库,在表中它由行排序。表模式定义只能列族,也就是键值对。一个表有多个列族以及每一个列族可以有任意数量的列。后续列的值连续存储在磁盘上。表中的每个单元格值都具有时间戳。总之,在一个HBase:
表是行的集合。
行是列族的集合。
列族是列的集合。
列是键值对的集合。
-
row key
决定一行数据,
按照字典数据排序的
rowkey 只能存储64k的字节数据
一般存10~100个字节 -
Column Family 列族 qualifier 列
HBase表中的每个列都归属于某个列族,列族必须作为表 模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需、动态加入;
权限控制、存储以及调优都是在列族层面进行的;
HBase把同一列族里面的数据存储在同一目录下,由几个文件保存
-
Timestamp时间戳
在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。时间戳的类型是 64位整型。
时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。
时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
-
Cell单元格
由行和列的坐标交叉决定;
单元格是有版本的;
单元格的内容是未解析的字节数组;
由{row key, column( = +), version} 唯一确定的单元。
cell中的数据是没有类型的,全部是字节数组形式存贮。 -
HLog(WAL log = write ahead log)
预写日志
HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,timestamp是” 写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。
HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue
hbase 架构
client 和 Hmaster 之间通过zk交互
写
clien -> zk , 获取元数据 -> HRegionServer -> HRegion -> 先往HLog 中写, 然后再往 Store中的MemStore中写,如果 MemStore 中满了,就生成StoreFile,然后继续写,
读
client -> zk ,获取元数据 -》 HRegionServer -> HRegion -》 先去 Store中的 MemStore中查询, 如果没找到 去BlockCache 中查询,再没找到采取 StoreFile中查找,并把结果缓存到BlockCache中(BlockCach内存满了后后面数据会把前面的数据挤掉,谁先进来谁先走)
-
client
包含访问hbase的接口并维护cache来加快对hbase的访问 -
zookeeper
保证任何时候,集群中只有一个活跃master
存储所有Region的寻址入口
实时监控RegionServer的上线和下线信息,并实时通知Master
存储Hbase的schema和 table元数据 -
Master
为RegionServer 分配region
负责RegionServer的负载均衡
发现失效的RegionServer并重新分配其上的region
管理 用户对table的增删改操作 -
RegionServer
RegionServer维护region, 处理对这些region的io请求
RegionServer 负责切分在运行过程中变的过大的region(等分) -
Region
HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region(裂变)
当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。
-
Memstore 与 storefile
一个region由多个store组成,一个store对应一个CF(列族)
store包括位于内存中的memstore和位于磁盘的storefile写操作先写入memstore,当memstore中的数据达到某个阈值,hregionserver会启动flashcache进程写入storefile,每次写入形成单独的一个storefile
当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction),在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile
当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
客户端检索数据,先在memstore找,找不到再找storefile
HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。
HRegion由一个或者多个Store组成,每个store保存一个columns family。
每个Strore又由一个memStore和0至多个StoreFile组成。如图:StoreFile以HFile格式保存在HDFS上。
- hbase中的排序存在于
memstore中写入的时候
多个storefiel合并的时候
Hbase 安装
单节点
伪分布式
1.hbase-env.sh中配置JAVA_HOME
2.配置hbase-site.xml如下
<property>
<name>hbase.rootdir</name>
<value>file:///home/testuser/hbase</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/testuser/zookeeper</value>
</property>
start-hbase.sh
分布式
-
准备工作
- 网络
- hosts
- ssh
- ssh-keygen
- ssh-copy-id -i .ssh/id_rsa.pub node1
- 时间同步:各个节点时间必须一致
- yum install ntpdate 安装时间服务器
- ntpdate ntp1.aliyun.com # 同步阿里云服务器时间
- 或者 data -s ‘2018-08-08 08:08:08’ 或者设定一个固定时间
- jdk 版本
-
解压配置
- 1 hbase-env.sh
设置 JAVA_HOME
修改 HBASE_MANAGES_ZK=false - 2 hbase_site.xml
<configuration> <property> <name>hbase.rootdir</name> <value>hdfs://mycluster:8020/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>node001,node002,node003</value> </property> </configuration>
- regionservers
node002 node003 node004
- backup-masters
node004
- 拷贝hdfs-site.xml到 hive/conf目录
- 复制hbase到其他机器
- start-hbase.sh
- 1 hbase-env.sh
hbase shell
通过 hbase shell进入
hbase的优化问题
表的创建
-
region
创建多个region分区。这样就可以对大数据量是进行负载均衡处理。提高批量写入效率 -
rowkey
通过rowkey访问,可以使用 get, 或则scan 对 rowkey的range进行范围操作
rowkey 越小越好(节省空间)
经常查询的列作为rowkey
散列性:将数据存往不同的regionServer -
column Family
不要再一个表中设计过多的 的列族,尽可能的少
因为一个列族写满后溢写,相邻的列族也开始溢写,会导致系统产生过多io. -
in Memeory,TTL, MaxVersion .设置列族属性
-
compact & split
compact : 关闭major自动合并,防止在访问峰值时请求延迟
设置minor合并 属性
写表
-
多 htable 并发写入
-
autoFlush: 关闭自动flush.防止有一条就写一条,
-
writer buffer: 设置写缓存的大小。
-
wal flag
可以设置关闭预写日志,但是不建议。如果regionServer宕机,put/delete的数据将无法通过wal恢复 -
批量写
-
多线程并发写
读表
- 多 htable 并发读
- Htable 参数设置
- Scanner Caching
hbase.client.scanner.caching配置项可以设置HBase scanner一次从服务端抓取的数据条数,默认情况下一次一条。通过将其设置成一个合理的值,可以减少scan过程中next()的时间开销,代价是scanner需要通过客户端的内存来维持这些被cache的行记录。 - Scan Attrubute Selection
scan 时 指定需要的列族,可以减少网络传输数据量,否则默认scan操作会返回 整行所有的Column Family的数据 - Close ResultScanner
通过scan 读取完数据后,记得关闭resultSanner.否则RegionServer可能会出现问题
- Scanner Caching
- 批量读
- 多线程并发读
- 缓存查询结果
在应用程序中做缓存(redis)
先查redis,再查hbase - Blockcache
HBase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写;另外一部分作为BlockCache,主要用于读。
写请求会先写入Memstore,Regionserver会给每个region提供一个Memstore,当Memstore满64MB以后,会启动 flush刷新到磁盘。当Memstore的总大小超过限制时(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),会强行启动flush进程,从最大的Memstore开始flush直到低于限制。
读请求先到Memstore中查数据,查不到就到BlockCache中查,再查不到就会到磁盘上读,并把读的结果放入BlockCache。由于BlockCache采用的是LRU策略,因此BlockCache达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。
一个Regionserver上有一个BlockCache和N个Memstore,它们的大小之和不能大于等于heapsize * 0.8,否则HBase不能启动。默认BlockCache为0.2,而Memstore为0.4。对于注重读响应时间的系统,可以将 BlockCache设大些,比如设置BlockCache=0.4,Memstore=0.39,以加大缓存的命中率。
HTable, HTablePool
HTable和HTablePool都是HBase客户端API的一部分,可以使用它们对HBase表进行CRUD操作。
HTable
- 规避Htabe对象的创建开销
- Htable对象不是线程安全
- Htable对象之间共享Configuration
HTablePool
- HTablePool可以解决HTable存在的线程不安全问题,同时通过维护固定数量的HTable对象,能够在程序运行期间复用这些HTable资源对象。
- HTablePool可以自动创建HTable对象,而且对客户端来说使用上是完全透明的,可以避免多线程间数据并发修改问题。
- HTablePool中的HTable对象之间是公用Configuration连接的,能够可以减少网络开销。
HTablePool的使用很简单:每次进行操作前,通过HTablePool的getTable方法取得一个HTable对象,然后进行put/get/scan/delete等操作,最后通过HTablePool的putTable方法将HTable对象放回到HTablePool中。
Hbase 和 DBMS比较
hbase有索引吗?
rowkey可以看成索引,但是效率低
所以可以创建hbase的二级索引
查询数据不灵活:
1、 不能使用column之间过滤查询
2、 不支持全文索引。使用ES和hbase整合完成全文搜索。
- 使用ES 创建hbase的索引
a) 使用MR批量读取hbase中的数据,在ES里面建立索引(no store)之保存rowkey的值。
b) 根据关键词从索引中搜索到rowkey(分页)
c) 根据rowkey从hbase查询所有数据