HBASE
hbase的来源
1、hdfs的数据读写延迟高 2、不能进行实时删除局部数据 3、hive的数据必须要指定的列或者字段,必须要格式化的数据 4、hbase来源于google的bigtable
hbase的定义
hbase是一个基于hadoop开源的,分布式的,多版本的,可扩展的,非关系型数据库,能够处理海量数据,(数十亿行,数百万列),面向列存储,面向稀疏存储(mysql面向行存储)
HBase特性
hbase类似于:redis,clickhouse,mongodb,canssdra等 uid <name:zs,age:18,score:22>
hbase的表模型与关系型数据库的表模型不同
hbase的表中没有固定字段定义
hbase的表中存储的是kv键值对
hbase的表中有列簇的划分,用户可以指定哪些kv插入哪个列簇
hbase的表在物理存储上是按照列簇来分隔的,不同的列簇的数据一定存在不同的文件中
hbase的表中每一行都有固定的一个行键,而且每一行的行键在表中不能重复
hbase的数据包含行键,包含key,包含value 都是byte[]类型,hbase不负责用户维护数据类型
hbase对事务的支持很差
hbase 支持稀疏存储
hbase与rdbms和nosql区别
hbase的表存在hdfs文件系统中
从而hbase存储容量可以线性扩展,数据存储安全性可靠性极高
hbase的表模型跟mysql之类的关系型数据库的表模型差别巨大
hbase的白哦模型有:行的概念,但是没有字段概念
行中存的都是kv键值对每行中kv对中的k可以是各种各样每行的kv对数量也是各种各样
hbase应用场景
1服务器从app采集数据
2通过日志采集工具做数据采集
3经过etl
4数据分析后的结果可以存在hbase中
hbase表模型
hbase表模型的要点
1一个表有表名
2一个表可以有多个列簇(不同的列簇会存储在不同的文件中) 列簇一般1-2个即可
3表中的每一行有一个键行(rowkey)而且行键在表中不能重复(重复之后会覆盖,比如更新数据行键一定会重复) 类似于mysql中的主键
4表中每一对kv称为一个cell
5hbase可以对数据存储多个历史版本,(历史版本的数量可以配置)
6整张表由于数据量大,会被横向切成若干个region(用rowkey范围标识),不同的region的数据也存储在不同文件中
7hbase会对插入的数据按顺序存储(rowkey排序)
7.1要点1首先会按行键排序
7.2要点2同一行里面的kv会按列簇排序,再按k排序
hbase的表中能存储数据类型
hbase中值支持byte[]
byte[]包括了rowkey,key,value,列簇名,表名
hbase基于hadoop:base的存储依赖于hdfs
hbase的表结构
传统的rdbms会按照行存储数据我们添加字段时对整个表结构产生了影响,导致该列没有添加数据值是也会使用null
hbase:数据在rowkey上是按照字典顺序排序的,如果rowkey相同,就按照列簇进行字典顺序排序,如果列簇相同就按照列名的字典顺序排序
我们一般采取通过列簇查询数据,因为这种效率是最高的,通过字段也可以查,不过效率就会低下很多
hbase会自动维护rowkey 相当于主键,hbase_info和extra_info 叫做列簇,每一个列簇里面的保存数据不可以一样,每一个键值对称为cell
hbase工作机制
组件说明
client :hbase客户端,包含hbase的接口,如linux shell,java api 除此之外,他还会维护缓存来加速hbase的速度如region的位置信息
zookeeper:
监控hmaster的状态,保证有且仅有一个活跃的hmaster达到高可用,
它可以存储所有region的寻址入口,如:root表在那一台服务器上
实时监控Hregionserver的状态,感知HRegionServer的上下线信息,并实时的通知给hmaster
存储hbase的部分元数据
HMaster:
为hregionserver分配region(新建表等)
负责hregionserver的负载均衡
负责region的重新分配(hregionserver宕机之后的region分配,hregion裂变:当region过大之后的拆分)
hdfs上的垃圾回收
处理schema的更新请求
HRegionServer:
维护HMaster分配给的region(管理本机的region)
处理client对这些region的读写请求,并和hdfs进行交互
负责切分在运行过程中组件变大的region
Hlog:
对hbase的操作进行记录使用wal写数据,优先写入log(put操作,先写日志在写memstore这样可以防止数据丢失,即使丢失也可以回滚)
Hregion:
hbase中分布之存储和负载均衡的最小单元,他是表或表的一部分
Store;
相当于一个列簇
Memstore
内存缓冲区,用于将数据批量书信到hdfs中,默认为128M
hstorefile
是一个逻辑概念,hbase中的数据是以hfile存储在hdfs上
组件之间的关系
hmaster:hregionserver=1:*
hregionserver:hregion=1:*
hregionserver:hlog=1:1
hregion:hstore=1:*
store:memstore=1:1
store:storefile=1:*
storefile:hfile=1:1
小结
rowkey:行键,和mysql的主键同理,不允许重复
columnfamily:列簇,列的集合
column列
timestamp:时间戳,默认显示最新的时间戳,可用于控制k对应的多个版本值,默认查最新的数据
version:版本号表示记录数据的版本
cell:单元格,kv就是cell
模式:无
数据类型:只存储byte[]
多版本:每个值都可以有多个版本
列式存储:一个列簇存储到一个目录
稀疏存储:如果一个kv为null不占用空间
hbase的安装配置
系统版本:centOS7.7
hbase版本:apache-hbase-1.3.6
hadoop版本:apache-hadoop-2.7.6
jdk版本:jdk-1.8.
单机安装/伪分布式:一台服务器
全分布式:3台及以上的服务器
hbase单机安装
解压
tar -zxvf hbase-1.3.6-bin.tar.gz -C /usr/local/
配置环境
vi /etc/profile export HBASE_HOME=/usr/local/hbase-1.3.6 export PATH=$PATH:$HBASE_HOME/bin source /etc/profile vi /usr/local/hbase-1.3.6/conf/hbase-env.sh export JAVA_HOME=/opt/soft/jdk/jdk1.8.0_60 export HBASE_MANAGES_ZK=true
hbase-site.xml
vi /usr/local/hbase-1.3.6/conf/hbase-site.xml <configuration> <property> <name>hbase.rootdir</name> <value>file:///usr/local/hbase-1.2.1/hbasedata</value> <description>配置hbase的数据存放目录</description> </property> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/usr/local/hbase-1.2.1/zkdata</value> <description>配置zookeeper的数据存放目录</description> </property> </configuration>
启动hbase服务
start-hbase.sh starting master, logging to /usr/local/hbase-1.3.6/logs/hbase-root-master-leetom01.out Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0 Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=128m; support was removed in 8.0 jps 2611 NameNode 4548 RunJar 2824 DataNode 106265 Jps 3309 ResourceManager 3453 NodeManager 105884 HMaster
全分布式安装
hbase是一个分布式系统
其中有一个管理角色 HMaster(一般两台,一台active,一台backup)
其他的数据节点角色 HRegionServer(多台,看数据容量)
实际上需要一个完全分布式的配置类全面测试hbase在并在实际场景中使用它,在分布式配置中,集群包含多个节点,每个节点运行一个或多个hbase守护进程,这些包括主实例和备份主实例,多个zookeeper节点和多个regionserver节点
角色分配
leetom01:namenode hmaster
leetom02:datanode regionserver zookeeper backup master
leetom03:datanode regionserver zookeeper
准备工作
安装zookeeper
hbase-env.sh
配置jdk路径
export JAVA_HOME=/usr/local/java/jdk1.8+
配置关闭HBase管理zookeeper
安装
hbase-site.xml
<configuration> <!-- 指定hbase在HDFS上存储的路径 --> <property> <name>hbase.rootdir</name> <value>hdfs://leetom01:8020/hbase</value> <description>配置hbase的数据存放在hdfs的目录</description> </property> <!-- 指定hbase是分布式的 --> <property> <name>hbase.cluster.distributed</name> <value>true</value> <description>开启hbase的分布式模式</description> </property> <!-- 指定zk的地址,多个用“,”分割 --> <property> <name>hbase.zookeeper.quorum</name> <value>leetom02,leetom03,leetom04</value> <description>配置hbase使用真实的zookeeper的目录</description> </property> </configuration>
regionservers
leetom02 leetom03 leetom04
在hbase的conf创建back-masters并在其中添加主机名leetom02
决定你的其他备份的hmaster启动在什么服务器上,可以写多个,换行即可
leetom02
分发
scp -r hbase-1.3.6/ leetom02:/usr/local scp -r hbase-1.3.6/ leetom03:/usr/local scp /etc/profile leetom02:/etc/ scp /etc/profile leetom03:/etc/
启动hbase
先启动hadoop和zookeeper start-hbase.sh 查看每台服务器的jps 查看hbase的hmaster的web端口16010 http://leetom01:16010 出错在hbase的安装目录下的logs查看日志 备份的master会自动启动
解决时间差
yum -y install ntpdate ntpdate ntp1.aliyun.com
hbase启动
hbase shell
regionserver上下线
master使用zookeeper跟踪regionserver状态,当某个regionserver启动时,会首先在zookeeper上的server目录下建立代表自己的文件并获得该文件的独占锁,由于master订阅了server目录上的变更信息,当server目录下的文件出现新增或者删除操作时master可以得到来自zookeeper的实时通知,因此一旦regionserver上线master能马上得到消息
当RegionServer下线时,它和zookeeper的会话断开,zookeeper自动释放代表这台Server的文件的独占锁。而Master不断轮询Server目录下文件的锁状态。如果Master发现某个RegionServer丢失自己的的独占锁,或者Master连续几次和RegionServer通信都无法成功,Master就尝试去获取代表这个RegionServer的读写锁。一旦获取成功,就可以确定RegionServer和zookeeper之间的网络断开或RegionServer挂了。无论哪种情况发生,RegionServer都无法继续为它的Region提供服务,此时Master会删除Server目录下代表这台RegionServer的文件,并将这台RegionServer的Region分配给其他还活着的节点。 如果网络短暂出现问题导致RegionServer丢失它的锁,RegionServer重新连接到Zookeeper之后,只要代表它的文件还在,它就会不断尝试这个文件上的锁,一旦获取到,就可以继续提供服务。 命令:hbase-daemons.sh stop regionserver tip:停止所有regionserver
加入hbase机器出现问题,需要对hbase的regionserver进行下线,如何平滑下线,且不影响服务正常的运行
cat ${HBASE_HOME}/conf/regionservers文件 找到要下线的regionserver host
cd ${HBASE_HOME}/bin
./gracefun_stop.sh ${hostname}
会逐渐将region迁移到其他机器的regionserver上,迁移完最后关闭regionserver
HBASE读写数据的工作流程
1写数据流程
1.hbase使用memstore和storefile存储对表的更新,数据在更新时首先写入hlog和memstore,memstore中的数据是排序的,当啊memstore累计到一定阀值的时候就会创建一个新的memstore冰晶老的memstore添加到flush队列,有单独的线程flush到磁盘上,称为一个filestore,与此同时,系统会在zookeeper中记录一个checkpoint,表示这个时刻之前的数据变更已经持久化了,当系统出现意外时,可能导致memstore中的数据丢失,此时食用hlog来恢复checkpoint之前的数据 2.storefile是只读的,一旦创建之后就不可修改,,因此hbase的更新就是不断追加的操作,当一个store的storefile达到一定的阀值后,就会进行一次合并操作,将同一个key的修改合并到一起,同时进行版本合并和数据删除,形成一个大的storefile,当storefile的大小达到一定的阀值后,又会对stroefile进行切分操作,等分成两个storefile 3.hbase中的只有增添数据,所有的更新和删除操作都是在后续的合并中进行的,使得用户的写操作只要进入内存就可以立刻返回,实现了hbase的高速存储 1.client通过zookeeper的调度,向regionserver发去写数据请求,在region中写数据 2.数据被写入region的memstore,知道memstore达到预设阈值 3.memstore中的数据被flush成一个storefile 4.随着storefile文件的不断增多,当期数量增长到一定阈值后,出发compact合并操作,将多个storefile合并成一个storefile,同时进行版本合并和数据删除, 5storefile通过不断的compact合并操作,逐步形成越来越大的storefile 6.单个storefile大小超过一定阈值后,出发split操作,把当前的region split成2个新的region,父region会下线,新split出的2个region会被Hmaster分配到对应的regionserver上,使得原先1个region的压力得到分流到2个region上
读数据流程
hbase的所有region元数据被存储在.mate表中,,随着region的增多,.mate表中的数据也会增大,并分裂成多个新的region,为了定位,.meta表中的各个region的位置,把.mate表中的左右region的元数据保存在-root-表中,(1.0之后转移到zk的master目录),最后由zookeeper记录-root-表位置信息,所有的客户端访问数据之前,需要首先访问zookeeper获取-root-表获得.meta表的位置,最后根据.mate表中的信息,确定用户数据存放的位置 -root-表永远不会被分割,他只有一个region,这样可以保证最多需要三次跳转就可以定位任意一个region。为了加快访问速度,.meta表的所有region全部保存在内存中,客户端会将查询过的位置信息缓存起来,且缓存不会主动失效,如果客户端根据缓存信息还访问不到数据,则询问相关.meta表中的region服务器,视图获取数据的位置,如果还是失败,则询问-root-表相关的.meta表在哪里,最后如果前面的信息全部失效,则通过zookeeper重新定位region的信息,如果客户端上的缓存全部失效,需要六次网络定位,才能定位到正确的region client--->zookeeper-->root表(master)-->meta表--->regionserver-->region-->client 1.client访问zookeeper查找-root表,获取.meta表信息 2.从.meta表查找,获取存放目标数据的region信息,从而找到对应的regionserver 3.通过regionserver获取需要查找的数据 4.regionserver的内存为memstore和blockcache两部分memstroe主要用于写数据,blockchache主要用于读数据,读请求先到memstore中查数据,查不到就blockcache中查,在查不到就到stroefile上读,并把读的结果放入blockcache
模型存储
1.数据的存储是每个region所承担的工作 1我们知道每个region代表的是一张hbase表中特定的rowkey范围内的数据 2而hbase是面向列存储的数据库,所以在一个region中,有多个文件来存储这些列 3hbase中数据列是有列簇来组织的,所以每一个列簇都会有一个对应的数据结构 hbase将列祖的存储数据结构抽象为store,一个store代表一个列簇 总结:所以在这里也可以看出为什么在我们插叙你的时候要尽量减少不必要的列,而经常一起查询的列要组织到一个列簇里:因为需要查询的列簇越多,意味着要扫描越多的store文件,这就需要跟多的时间 2.store中存储数据的方式:hbase采用的是lsm树的机构,这种结构的关键是: 1每一次操作都会先写入memstore(内存缓冲区) 2当memstore达到上线的时候,hbase会将内存中的数据输出为有序的storefile文件数据(根据rowkey,版本,列名排序,这里已经和列簇无关了,因为store里都属于同一个列簇)。 3这样会在store中形成很对个小的storefile,把这些小的file数量打到一个阀值的时候,hbase会用一个线程来吧这些小的file合并成一个打的file 这样,hbase就把效率低下的文件中的插入移动操作,变成了单纯的文件输出,合并操作 由上可知,在hbase底层的store数据结构中 1 每个storefile内的数据是有序的 2 但是storefile之间不一定是有序的 3 store只需要管理storefile的索引就可以了 这里也可以看出为什么指定版本和rowkey可以加强查询的效率,因为指定版本和rowkey的查询可以利用storefile的索引跳过一些肯定不包含没有表数据的数据
hbaseshell
namespace操作
list_namespace:查询所有命名空间
list_namespace
list_namespace_tables:查询指定的命名空间的表
list_namespace_tables 'hbase'
create_namespace:创建指定的命名空间
create_namespace 'le1'
describe_namespace:查询指定命名空间的结构
describe_namespace 'le1'
alter_namespace:修改命名空间的结构
alter_namespace 'le1',{METHOD => 'set',