HBase
1.2.1、HMaster
功能:
1) 监控RegionServer
2) 处理RegionServer故障转移
3) 处理元数据的变更
4) 处理region的分配或移除
5) 在空闲时间进行数据的负载均衡
6) 通过Zookeeper发布自己的位置给客户端
1.2.2、RegionServer(一个服务进程)
功能:
1) 负责存储HBase的实际数据
2) 处理分配给它的Region(相当于一个table)
3) 刷新缓存到HDFS
4) 维护HLog
5) 执行压缩
6) 负责处理Region分片组件:大表分小表 小合大
1) Write-Aheadlogs (HLog)
HBase的修改记录,当对HBase读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。
但把数据保存在内存中可能有更高的概率引起数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Aheadlogfile的文件中,然后再写
入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。
2) HFile
这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。
3) Store
HFile存储在Store中,一个Store对应HBase表中的一个列族。
4) MemStore
顾名思义,就是内存存储,位于内存中,用来保存当前的数据操作,所以当数据保存在WAL中之后,RegsionServer会在内存中存储键值对。
5) Region(一个table包含或拆分成若干个region(小表))
Hbase表的分片,HBase表会根据RowKey值被切分成不同的region存储在RegionServer中,在一个RegionServer中可以有多个不同的region。
Structure
对于HBase而言,客户端是往里面写数据和读数据的角色
客户端想去访问数据的话,必须找到数据的存放地址,存放地址被称为数据的元数据信息,它放在了zookeeper里面,zookeeper负责维护
regionserver中保存的数据的元数据信息
regionserver会开3台,一台开一个,regionserver里面结构:
1.HLog是预写入日志,它在本地磁盘里。(1个)
2.Region,regionserver里面可以维护管理多个region,region可以理解为一个table (多个)
1)store:一个region里面包含多个store,store是一个存储单元,它不是数据的落脚点,它是一个抽象概念,实际上不存在(多个store
①memstore是内存的一块区域 (一个store只能对应一个memstore)
②storefile是本地磁盘中的一个文件,实实在在的文件,物理上以HFile这样一个文件体现,storefile是一个逻辑概念,对应的实体
HFile,数据会最终落到HFile里面。 (一个store可以对应多个HFile)
读数据流程:
client从zookeeper拿到-ROOT-表的地址location,这张表在哪个regionserver上面放着,返回主机名端口号,client拿到端口号去
regionserver里面去找,这张-ROOT-表的体现形式是一个region,无论多大都不会切分,ROOT这张表实际存储的数据是.META.表的元数据信息,
META表可以有很多个region,META表的元数据信息是可能有很多条的,一个META表对应多条元数据信息存放在ROOT里面,在这里面找到了我要访问
的业务数据的那个region它的元数据信息是在哪一个META表的region里面存储。即它在ROOT表里找到了某一个META表的地址:META-region 1 ,
META的元数据信息就是它的地址,找到META表里的region 1,在region 1里面找业务表B表存放的region 2的存储地址,再到某一个regionserver
找到B表的region 2所在地,找到后就可以访问里面的业务数据。找到region后,尝试从这个store的内存memstore里面把数据读出来,memstore存
的是不是读取的数据,只负责缓存用户最近写入的数据,在memstore里面读到了,就直接返回给client,这样读到的数据是最近client往hbase里
面写的数据,有可能还有另一个线程在并行执行实时往里面写数据,读到memstore里面存的是最近写线程往里面写的数据,不包含读的。
如果memstore里面没有找到,接着会去blockcache内存区域里面找(这一系列内存逻辑控制在regionserver里面,某一个线程的某一个代码,
memstore和blockcache同属于一个JVM堆的,同一个堆内存的两块逻辑区域,两个内存读写分离),blockcache只负责读取数据的缓存。读数据会
先去写数据的缓存memstore找,一般认为想要访问的数据都是最新数据,最新写入的数据有没有你想要的,有直接返回,没有会去最近读的数据的
缓存blockcache里面找有没有缓存我想要的,有直接返回(blockcache里面的算法是LRUCache latest recently use 一个最近的最常使用算法,就
是最小使用的数据按先进先出,进入固定大小的缓存区域,即在缓存区内使用次数频率最低的相同的数据替换最早加入队列的那个),
如果在blockcache里面没有,紧接着去HFile里面找,HFile读的是HDFS,读完后会缓存HFile数据到blockcache内存里面,根据LRU算法缓存到里面
,然后再返回,如果下次client再请求相同的数据,到blockcache就找到了,不用再访问HDFS。经常访问的数据放在blockcache里面。(用到LRUC
ache算法)
写数据流程:
client想写数据,先找到zookeeper,zookeeper里面维护着regionserver的状态信息,要往哪个regionserver里写。zookeeper还存着HMaster
的元数据信息。和regionserverRPC通信,先找到往哪个region(相当于table)写,每个region会维护若干个rowkey(类似于主键id),要写的数
据符合region维护的rowkey范围,就往这个region里面写,先往HLog里面写,写完后在store里面找一个memstore,先写到内存里,假设分配到第
一个store里的memstore,写成功后,虽然还没写到HFile里面,就算这个数据完整写成功,返回成功。什么时候把数据写到HFile里面?达到
memstore的阈值16kb就提交到缓存队列,队列存放的memstore的实例对象memstore 1,随着写数据的增加,队列里面可能有一些没来得及处理的
memstore 2、3、4,队列先进先出把memstore 1往HFile里面溢写,产生一个HFile,每一个写满的memstore都会对应溢写成一个HFile,有一个
线程专门操作溢写,会不停读队列里面提交的memstore数据,往HFile里面溢写。每提交队列一个memstore,store里面都会产生一个新的memstore
用于后面数据的输入,一个store只有一个memstore,是单例的,用完产生一个新的,写完释放内存,为后续新产生的memstore提供资源。16kb会
和16kb合并,regionserver比较闲时才会合并。过小的HFile会合并成大的,过大的HFile拆分成小的,操作由regionserver来完成,调用HDFS
的API,regionserver进程里面有若干个线程,线程里面跑的是代码块,利用代码逻辑实现文件拆分和合并。
这个机制能保证数据不会丢失,HLog存的是本次写数据的操作,数据本身是张3,还有是什么操作:put,delete等,即HLog里面有数据完整的
操作和数据本身,恢复HLog里面的数据即可,先恢复到memstore里面,后续流程一样,当确定memstore数据成功溢写到HDFS时,HLog的刚才这条数
据就删掉,当确定HLog里面所有的数据都已经成功持久化存储到HDFS时候,会把HLog文件标记为Old hlog,在闲暇时删掉这个文件。为什么不直接
写到HFile里面?为了提升效率,批处理比一条数据处理效率多。
regionserver会把达到阈值的memstore里面的数据溢写到HFile里面,HFile现在在本地磁盘,之后regionserver会调用api:HDFSclient,
目的是把生成的HFile文件写到HDFS上面,通过HDFSclient写。HBase会无感知地调用HDFSAPI把文件保存到HDFS上面,保存完之后删除HFile,但是
会保留这个HFile的元数据信息(也就是我这个HFile上传到哪一个DataNode上面了),访问时还是要去那个DN找(HBase而言,操作HDFS是不可见
的,自动操作,无感知的,会造成HDFS支持随机读写的错觉,但其实HDFS不支持)。
regionserver包含多个region的目的是什么?region里包含多个store的原因是什么?当HBase有多个客户端,有两个不同部门,做两个不同业
务,用同一个集群,自己维护自己的表,跟使用关系型数据库一样。这样情况下,可能出现两个客户端同时往里面写数据,同时往里面读数据,同
时操作不同的表,这就意味着一个regionserver要维护多个region。如果只维护一个region意味着,两个业务的表结构一样。regionserver维护的
若干个region,它的表结构可能不一样,可能针对不同业务设计的表。不同业务的表是可以交给同一个regionserver管理的。
HBase 一种是作为存储的分布式文件系统,另一种是作为数据处理模型的 MR 框架。因为日常开发人员比较熟练的是结构化的数据进行处理,
但是在 HDFS 直接存储的文件往往不具有结构化,所以催生出了 HBase 在 HDFS 上的操作。如果需要查询数据,只需要通过键值便可以成功访问
HBase内置有Zookeeper,但一般我们会有其他的Zookeeper集群来监管master和regionserver,Zookeeper通过选举,保证任何时候,集群中只
有一个活跃的HMaster,HMaster与RegionServer启动时会向ZooKeeper注册,存储所有Region的寻址入口,实时监控Regionserver的上线和下线信
息。并实时通知给HMaster,存储HBase的schema和table元数据,默认情况下,HBase管理ZooKeeper实例,Zookeeper引入使得HMaster不再是单点
故障。一般情况下会启动两个HMaster,非Active的HMaster会定期的和ActiveHMaster通信以获取其最新状态,从而保证它是实时更新的,因而如
果启动了多个HMaster反而增加了ActiveHMaster的负担。
一个RegionServer可包含多个Region,每个RegionServer维护一个HLog,和多个HFiles及其对应的MemStore。RegionServer运行于DataNode上
,数量可以与DatNode数量一致。
/opt/module/zookeeper-3.4.10/bin/zkServer.sh start
/opt/module/zookeeper-3.4.10/bin/zkServer.sh stop
1) 创建表
hbase(main) > create 'student','info'
2) 插入数据到表
hbase(main) > put 'student','1001','info:name','Thomas'
hbase(main) > put 'student','1001','info:sex','male'
hbase(main) > put 'student','1001','info:age','18'
hbase(main) > put 'student','1002','info:name','Janna'
hbase(main) > put 'student','1002','info:sex','female'
hbase(main) > put 'student','1002','info:age','20'
3) 扫描查看表数据
hbase(main) > scan 'student' ======会扫描整张表
hbase(main) > scan 'student',{STARTROW => '1001', STOPROW => '1001'} (效率途径)
hbase(main) > scan 'student',{STARTROW => '1001'}
4) 查看表结构 hbase(main)> describe 'student'
5) 更新指定字段的数据 覆盖操作
hbase(main) > put 'student','1001','info:name','Nick'
hbase(main) > put 'student','1001','info:age','100'
6) 查看 “指定行”或“指定列族:列”的数据 ======会扫描整张表
hbase(main) > get 'student','1001'
hbase(main) > get 'student','aa101','info'
hbase(main) > get 'student','1001','info:name'
7) 删除数据
删除某rowkey 的全部数据:
hbase(main) > deleteall 'student','1001'
删除某rowkey 的某一列数据:
hbase(main) > delete 'student','1002','info:sex'
8) 清空表数据
hbase(main) > truncate 'student'
尖叫提示:清空表的操作顺序为先disable,然后再truncating 。
9) 删除表
首先需要先让该表为disable 状态:
hbase(main) > disable 'student'
然后才能drop 这个表:
hbase(main) > drop 'student'
尖叫提示:如果直接drop 表,会报错:Drop the named table. Table must first be disabled
ERROR: Table student is enabled. Disable it first.
10) 统计表数据行数 (一个rowkey就是一行)
hbase(main) > count 'student'
11) 变更表信息
将info 列族中的数据存放3 个版本:
hbase(main) > alter 'student',{NAME=>'info',VERSIONS=>3}
HBase作业(一):
1、画出HBase Client访问HBase读数据的流程图。
2、画出HBase Client访问HBase写数据的流程图。
HBase作业(二):
1、封装一个公用的HBaseUtil.java
* 创建表
* 删除表
* 批量创建表
* 批量删除表
* 添加单row数据
* 批量添加数据
* 删除单row数据
* 批量删除数据
* 得到所有数据
* 得到指定列的数据
NameNode 1G内存,大概可以存储100万条元数据
如果存储的是日志信息,一次成功的访问,大概产生5条左右的日志信息
每条日志信息大概100~500字节
数据一般冗余2~3份
企业中,中小型规模的集群,NN节点一般是128G左右
磁盘剩余空间要超过20%