HBase,
HBase笔记
一:HBase简介
HBase是Big Table的开源版本,Java编写,是Hadoop的数据库,是建立在HDFS之上,被用来提供高可靠性,高性能,列存储,可伸缩,多版本的NoSQL的分布式数据存储系统,实现对大型数据的实时,随机的读写访问。
1).依赖于HDFS做底层的数据存储
2).依赖于MapReduce做数据计算
3).依赖于ZooKeeper做服务协调
4).HBase的NoSQL:介于NoSQL和RDBMS之间,仅能通过主键(rowkey)和主键的range来检索数据;不支持join等复杂操作;不支持复杂的事务,只支持行级事务;支持的数据类型byte[];
5).主要用来存储结构化和半结构化的松散数据
二:名词解释
Rowkey(行键):
HBase使用Rowkey来唯一区分某一行数据
Rowkey可以是任意字符串(最大长度64KB),最好是16个字节
在HBase内部,Rowkey保存为字节数组
HBase会对表中的数据按照Rowkey排序(字典排序)
设计原则:
长度原则
散列原则
唯一原则
ColumnFamily(列族):
HBase通过列族划分数据的存储,列族下面可以包含任意多个列,实现灵活存储
HBase创建表的时候必须指定列族
HBase的列族不是越多越好,官方推荐最好小于或等于3
设计原则:
在合理范围内能尽量减少列簇就尽量减少列簇
TimeStamp(时间戳):
HBase使用不同的TimeStamp标识相同RowKey行对应的不同版本
TimeStamp类型是64位整型
TimeStamp可以有HBase自动赋值(精确到毫秒的当前系统时间),或由客户显式赋值
Cell(单元格):
由{rowkey, column(= +), version}唯一确定的单元
Cell中的数据是没有类型的,全部是字节码形式存储
三:HBase过滤器
四:HBase原理
–HBase 有两张特殊表:
-ROOT-:记录了.META.表的Region 信息,-ROOT-只有一个Region,不会分裂
.META.:记录了用户所有表拆分出来的的 Region 映射信息,.META.可以有多个Regoin
–HBase架构图解
HBase组件包括Client、Zookeeper、HMaster、HRegionServer、HRegion、Store、MemStore、StoreFile、HFile、HLog等
(1).Client
Client访问用户数据前首先访问zookeeper,找到-ROOT-表获取meta表所在Region的位置,并将该位置信息写入Client Cache,接着读取.META.表,最后找到用户数据的位置去访问,中间会经过多次网络操作,不过Client端会做cache缓存
(2).Zookeeper
zookeeper为HBase提供Failover机制,选举Master,避免单点Master故障
存储所有Region的寻址入口:-ROOT-在哪台服务器上
实时监控RegionServer状态,将RegionServer的上下线信息实时通知给Master
存储HBase的Schema,包括哪些Table,每个Table上有哪些Column Family
(3).HMaster
为RegionServer分配Region
负责RegionServer的负载均衡
发现失效的RegionServer并重新分配其上的Region
HDFS上的垃圾文件(HBase)回收
处理Schema更新请求(表的创建,删除,修改,列簇增加等)
(4).HRegionServer
RegionServer维护Master分配给它的Region,处理对这些Region的IO请求
RegionServer负责Split在运行过程中变得过大的Region,负责Compact操作
(5).HRegion
Table在行的方向上分割为多个Region
Region是HBase中分布式存储和负载均衡的最小单元,即不同的region可以分别在不同的RegionServer上,但同一Region是不会拆分到多个RegionServer上
Region按大小分割,每个表一般只有一个Region,随数据不断插入表中,region不断增大,当region的某个列族达到一个阈值(默认256M)时就会分成两个新的region
(6).Store
每一个region由一个或多个store组成,至少一个store
HBase会把一起访问的数据放在一个store,即为每个ColumnFamily建一个store,如果有几个ColumnFamily也就有几个store
HBase以store的大小来判断是否需要切分region
(7).MemStore
MEMStore是放在内存中的,保存修改的数据即keyvalue
当MEMStore的大小达到一个阈值(默认128MB)时,MEMStore会被flush到文件,即生成一个快照,目前HBase会有一个线程来负责memStore的Flush操作
(8).StoreFile
MEMStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存
(9).HFile
HBase中的KeyValue存储格式,HFile时Hadoop的二进制格式文件
HFile文件不是定长的,长度固定的只有其中两块:Trailer和FileInfo。Trailer中有指向其他数据块的起始点,FileInfo记录了文件的一些meta信息
(10).HLog
HLog(WAL Log):WAL即write ahead log,用来做灾难恢复的,HLog记录数据的所有变更,一旦region server宕机,就可以从log中进行恢复
–Hfile结构
Data Block段用来保存表中的数据,这部分可以被压缩。
Meta Block段(可选的)用来保存用户自定义的kv段,可以被压缩。
FileInfo段用来保存HFile的元信息,不能被压缩
Trailer这一段是定长的,保存了每一段的偏移量
–region寻址
第一步:
client请求zookeeper获取.META.所在的RegionServer的地址
第二步:
client请求.META.所在的RegionServer获取访问数据所在的RegionServer地址,client会将.META.相关信息cache下来,以便下次访问
第三步:
client请求数据所在的RegionServer,获取所需数据
–读请求
1).client通过zookeeper以及-ROOT-表和.META.表找到目标数据所在的RegionServer
2).联系RegionServer查询目标数据
3).RegionServer定位到目标数据所在的Region,发出查询请求
4).Region先从MemStore读取数据,如未找到,再从StoreFile中读取
–写请求
1).client根据RowKey通过zookeeper以及-ROOT-表和.META.表找到对应Region所在的RegionServer
2).client向RegionServer提交写请求
3).RegionServer将操作和数据写入HLog(write ahead log,预写日志),再将数据写入MEMStore,并保持有序
4).当MEMStore数据量超过阈值时,将数据溢写到磁盘,生成一个StoreFile文件。
当Store中的StoreFile数量超过阈值时,将若干小StoreFile合并(minor compact(部分StoreFile),major compact(所有StoreFile))为一个大StoreFile
当Region中单个StoreFile超过阈值时,Region分裂(split),等分成两个子Region
–RegionServer工作机制
1).Region分配
一个Region只能分配给一个RegionServer
Master记录了当前有哪些可用的RegionServer,以及当前哪些Region分配给了哪些RegionServer,哪些Region还没有分配。当需要分配的新的 Region,并且有一个 RegionServer 上有可用空间时,Master 就给这个 RegionServer 发送一个装载请求,把 Region 分配给这个 RegionServer
2).RegionServer上线
Mater使用zookeeper跟踪RegionServer状态。当某个RegionServer启动时,会首先在zookeeper上的server目录下建立代表自己的znode。由于zookeeper订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,Master可以得到来自zookeeper的实时通知。因此一旦RegionServer上线,Master就能得到消息
3).RegionServer下线
当RegionServer下线时,它和zookeeper的会话断开,zookeeper会自动释放代表这台server的文件上的独占锁。Master就可以确定:RegionServer和zookeeper之间的网络断开了;RegionServer挂了。无论哪种情况,RegionServer都无法为Region提供服务了,此时Master会删除server目录下代表这台RegionServer的znode数据,并将这台RegionServer分配给其他还活着的同志
–Master工作机制
1).Master上线
从 ZooKeeper 上获取唯一一个代表 Active Master 的锁,用来阻止其它 Master 成为 Master。
扫描 ZooKeeper 上的 server 父节点,获得当前可用的 RegionServer 列表。
和每个 RegionServer 通信,获得当前已分配的 Region 和 RegionServer 的对应关系。
扫描.META. Region 的集合,计算得到当前还未分配的 Region,将他们放入待分配 Region 列表
2).Master下线
由于 Master 只维护表和 Region 的元数据,而不参与表数据 IO 的过程,Master 下线仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的 schema,无法进行 Region 的负载均衡,无法处理 Region 上下线,无法进行 Region 的合并,唯一例外的是 Region 的 split 可以正常进行,因为只有 RegionServer 参与),表的数据读写还可以正常进行。因此 Master 下线短时间内对整个 hbase 集群没有影响。
五:数据热点
–产生原因
HBase 中的行是按照 rowkey 的字典顺序排序的,这种设计优化了 scan 操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于 scan。然而糟糕的 rowkey 设计是热点的源头。
热点发生在大量的client 直接访问集群的一个或极少数个节点。大量访问会使热点 region 所在的单个机器超出自身承受能力,引起性能 下降甚至 region不可用,这也会影响同一个 RegionServer上的其他 region,由于主机无法服务其他 region 的请求。 设计良好的数据访问模式以使集群被充分,均衡的利用。 为了避免写热点,设计 rowkey 使得不同行在同一个 region,但是在更多数据情况下,数据应该被写入集群的多个 region,而不是一个。
–有效措施
1).加盐
在 rowkey 的前面增加随机数,具体就是给 rowkey 分配一个随机前缀以使得它和之前的 rowkey 的开头不同
2).哈希
哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的
3).反转
反转固定长度或者数字格式的 rowkey。这样可以有效的随机 rowkey,但是牺牲了 rowkey 的有序性
4).时间戳反转
一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 rowkey 的一部分对这个问题十分有用
六:hbase安装
–下载hbase-1.2.0-bin.tar.gz,解压
tar -zxvf hbase-1.2.0-bin.tar.gz
–创建软连接(root)
ln -s hbase-1.2.0-bin.tar.gz /usr/local/hbase
chown -R hadoop:hadoop /usr/local/hbase
–添加环境变量
vi /etc/profile
export HBASE_HOME=/usr/local/hbase
PATH=$PATH:${HBASE_HOME}/bin
–使环境变量生效
source /etc/profile
–修改配置文件(hbase/conf/)
vi hbase-env.sh
export JAVA_HOME=/usr/local/jdk
export HBASE_MANAGES_ZK=false #不使用自带的zk
vi hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://node01/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>node01:2181,node02:2181,node03:2181</value>
</property>
</configuration>
vi regionservers
node01
node02
node03
touch backup-masters # 创建backup-masters文件
vi backup-masters
node03
–将Hadoop下的hdfs-site.xml和core-site.xml拷贝到conf下
cp hdfs-site.xml core-site.xml ~/apps/hbase-1.2.0/conf
–将hbase分发到其他节点,创建软连接,修改属主,添加环境变量
scp -r hbase-1.2.0 node02:$PWD
scp -r hbase-1.2.0 node03:$PWD
–先启动zookeeper,然后启动Hadoop,再启动hbase
a.启动zookeeper(node01,node02,node03)
bin/zkServer.sh start
b.启动Hadoop
sbin/start-dfs.sh # node01
sbin/start-yarn.sh # node02
sbin/yarn-daemon.sh start resourcemanager # node01
./mr-jobhistory-daemon.sh start historyserver # node02
检查namenode状态
hdfs haadmin -getServiceState nn1
hdfs haadmin -getServiceState nn2
c.启动hbase
bin/start-hbase.sh #主节点
七:HBase使用
–hbase命令
hbase
–hbase shell客户端
hbase shell
–获取帮助
help
help ‘dml’ #获取一组命令的提示
help ‘create’ #获取某个命令的提示
–查看表列表
list
–创建表
create ‘test’, {NAME => ‘mySelf’, VERSIONS => 5, COMPRESSION=>‘SNAPPY’} #创建了一个名为’test’的表
NAME:列簇名,表中有1个列簇,
VERSIONS :版本号,保留5个版本(默认1)
COMPRESSION:是否压缩,(默认None)。若想要加入压缩算法,可以通过 alter 修改 schema
–查看表
desc ‘test’ #一个{}代表一个列簇(或describe ‘test’)
–新增列簇
alter ‘test’, NAME => ‘mySchool’
–删除一个列簇
方法一:
alter ‘test’, NAME => ‘mySchool’, METHOD => ‘delete’
方法二:
alter ‘test’, ‘delete’ => ‘mySchool’
–添加一个列簇,同时删除一个列簇
alter ‘test’, {NAME => ‘myInfo’}, {NAME => ‘mySelf’, METHOD => ‘delete’}
– 清空表
truncate ‘test’
–删除表
disable ‘test’ #先停用表
drop ‘test’ #再删除表
–disable_all/enable_all
disable_all ‘test.*’ #支持正则表达式,并列出当前匹配的表
–drop_all
同disable_all
四:HBase表中数据操作
–查询表中所有信息
scan ‘test’
–插入信息
help ‘put’ #需要传入表名,rowkey,列簇名、值等
put ‘test’, ‘user0001’, ‘myInfo:name’, ‘zhangsan’
put ‘test’, ‘user0001’, ‘myInfo:age’, ‘18’
–获取信息
help ‘get’ #需要传入表名,rowkey,[列簇名]
get ‘test’, ‘user0001’[, ‘myInfo:name’]
–查询表中某一列簇信息
scan ‘test’, {COLUMN => ‘myInfo’}
–删除某一行数据
delete ‘test’, ‘user0001’
–删除某rowkey中某列簇数据
delete ‘test’, ‘user0001’, ‘myInfo:name’