HBase是实时的、分布式、高维的数据库。
实用于对大数据实时的查询,但前提是要利用Hbase的数据结构来存数据,才可以查询。
HBase是一个真正的数据库,是nosql数据库,主要用来存储非结构化和半结构化的松散数据。与Hive很不同,Hive不是数据库,数据存在HDFS上,只是建立一种表结构,最终使用mapreduce去操作。HBase是后台服务,数据存在HDFS上,但是数据结构是特有的数据结构,查询速度很快,也是利用mapreduce去计算。
HBase数据模型:
---HBase表中的每个列都属于对应的列族,列族下的列是可以动态定义的,如列族为course,则该列族
下的列为course:math, course:chinese;
---每个表都有ROW KEY,表示为一行,一行中对应很多的TimeStamp,也就是版本号;
---权限控制、存储以及调优都是在列族里进行的;
---HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。
---单元格是由表的行和列的交叉来决定,每个单元格会表示同一块数据的不同的版本号,由时间戳指
定。
---单元格的内容是为解析的字节数组,其存储的内容是{ROW KEY,列族以及列内容,版本号},单元格
是HBase基本的存储类型。cell存储的是没有类型的,都是字节数组。
---HLog,记录了对数据的操作日志,和关系型数据库的log相似。
这个是HBase的基本的架构:
HMaster是HBase的主节点,外界访问的时候,通过zookeeper去找主节点。干活的是主节点下面的从节点,主节点是管理的作用,从节点是干活的,也就是HRegionServer,其中有HLog来记录日志。
HRegionServer(是一台服务器)下有很多的HRegion,这个是每行的数据,这是对HBase的表进行横向切分的结果,每若干行数据代表了一个HRegion。
HRegion下有很多的store,一个store存储的就是一个列族的数据,这里就表示的列族,表里有很多的列族也就有很多的store。
store分为MenStore和StoreFile,刚写入时数据会先放在MemStore,溢写时生产文件StoreFIle和HFile,HFile就是数据文件,存在HDFS中,StoreFile是元数据文件。其文件的元数据就存在StoreFile里。storeFile里存放的是文件在HDFS的位置信息等,storeFile存在region里,存在磁盘上,相当一个索引。查询时先在MemStore里查询(这里查的是数据),然后在Storefile里查询(这里通过索引找HDFS上的数据)。因此会产生很多的小文件,需要合并。
---client:HBase的接口并维护cache来加快对HBase的访问;
---Zookeeper:保证任何时候,集群只有一个Master;存储所有Region的寻找地址入口;实时监控 Region Server的上线与下线,并实时通知Master,如果某一个RegionServer出现问题,则拷贝其所
有元数据到另一个regionServer中。存储Hbase的schema和table元数据。
---Master:负责负载均衡,使regionServer的数据数量不会变差太多,管理用户对table的增删改查。
只负责新插入数据的负载均衡。
---RegionServer:存储region,并负责把过大的region进行切分。
---Region:HBase自动把表进行切分,每个region包含连续的几行数据,一开始,一张表对应的一个
region,当数据不停插入时,region表示的数据不停增大,到达阈值时会裂变为两个。表会根据Row
Key进行数据排序。
---Memstore与storefile:
一个region对应多个store,一个store对应一个列族;
storefile数量增多到一定数量时,系统会合并这些(minor,major compaction),合并过程会进行版本合并或者删除(major),形成更大的storefile;
当一个region的所有storefile太大了,会裂变,由hmaster操作;
注意:
列族多了,store多,因此产生的storefile多,由于storefile的合并很耗内存,因此应是其数量少,所以Hbase表的列族不要超过三个。
---以region作为最小的管理单元,
外界可以根据row-Key去快速的定位到region,再快速的定位到store。
storefile合并,那么Hfile也进行合并。
列族里面存储的都是键值对的形式。
基于hadoop的HBase:
存储的文件是通过HBase建立的表导进去的,文件目录形式为:
/hbase/data/default/t_person/8281jsuququ8182u3192/cf1/
配置文件中会配置hbase存的文件在hdfs中的根目录为/hbase;
数据放在data下;
dafault为命名空间;
t_person为建立的表,也就是数据通过这个表结构导入进来的;
接下来后面的是regionServer里的region的名字;
cf1是列族;
接下来就是数据了。
具体操作:HA环境搭建Hbase
在hbase-site.xml里添加
<configuration> //是hbase文件在hdfs集群上存储的位置 <property> <name>hbase.rootdir</name> <value>hdfs://mycluster/hbase</value> </property> //指明是分布式的 <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> </configuration>
[root@hadoop1 conf]# vi regionservers hadoop2 hadoop3 //在regionservers中指明哪些节点作为regionserver。
在hbase-env.sh
首先要配置java_Home的路径;
还需更改ZK的启动方式为false,也就是指明启动hbase时,不启动自带的zookeeper。你需要修改conf/hbase-env.sh
里面的HBASE_MANAGES_ZK
来切换。这个值默认是true的,作用是让HBase启动的时候同时也启动zookeeper.
还需要在hbase-site.xml中加入:
//这个是告诉hbase哪些节点上有zookeeper <property> <name>hbase.zookeeper.quorum</name> <value>hadoop1,hadoop2,hadoop3</value> </property> //告诉hbase有zookeeper的节点,zookeeper的工作目录是哪个 <property> <name>hbase.zookeeper.property.dataDir</name> <value>/root/zookeeper</value> </property>
因为hbase是要在zookeeper下运行的,zookeeper是hbase的入口。
这样hbase就能看到上面的入口了,其操作的存储文件放在hdfs上,因此也需要知道hdfs的配置信息,
在${HBASE_HOME}/conf
下面加一个 hdfs-site.xml
(或者 hadoop-site.xml
) ,最好是软连接
把hadoop的hdfs-site.xml文件放在hbase的conf目录下。
在所有节点上都安装配置hbase后就可以在bin目录下运行./start-hbase.sh了。
在哪个节点上启动的hbase,则Hmaster就在哪个节点上有,而且还可以在其他节点上单独启动,只是运行一个,其它standby。(hbase-daemon.sh start master)
这里需要注意的一点就是:要保证所有节点的Hbase系统的时间同步,解决方法:
1.方案1
在hbase-site.xml添加配置
<property>
<name>hbase.master.maxclockskew</name>
<value>180000</value>
<description>Time difference of regionserver from master</description>
</property>
这个方案是把各个机器的时间差指明。
2.方案2
使用date -s指令修改时间。
这样hbase就正常启动了!./start-hbase.sh是启动后台服务。
下面操作hbase,使用./hbase shell进入hbase,在里面进行增删操作。在hbase里的操作不要加分号!!!
./hbase hfile 这个是查看hbase里的文件。任何一个节点都可以查看。
hbase(main):004:0> create ‘t_person‘,‘cf1‘ 0 row(s) in 1.5030 seconds hbase(main):006:0> put ‘t_person‘,‘007‘,‘cf1:name‘,‘zs‘ 0 row(s) in 0.1850 seconds hbase(main):008:0> flush ‘t_person‘ 0 row(s) in 0.3800 seconds
建立表,建立表示,在regionserver里就生成region了,对应表的数据可以根据表结构进行插入或者导入了。对应的查询端口是60010。
可以插入数据,要根据表结构来插入,007是row key,表示为同一条数据。在最小存储单元里,注意数据是列族里的值,时间戳和rowKey是标志。
可以使用flush将内存的数据写入disk,是对应表。
也可以使用major_compact + 表名字,把对应表的数据进行合并,因为小文件太多所以要合并。
[root@hadoop2 bin]# ./hbase hfile -p -f /hbase/data/default/t_person/7e08e465df252e1711e4a6c7bcfb0d1c/cf1/9a4ae2788b314ed58d7a433634836e00 SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/root/hbase-0.98.14-hadoop2/lib/slf4j-log4j12-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/root/hbase-0.98.14-hadoop2/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/root/hadoop-2.4.1/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 2015-09-30 07:58:41,646 INFO [main] Configuration.deprecation: fs.default.name is deprecated. Instead, use fs.defaultFS 2015-09-30 07:58:41,801 INFO [main] Configuration.deprecation: hadoop.native.lib is deprecated. Instead, use io.native.lib.available 2015-09-30 07:58:41,909 INFO [main] util.ChecksumType: Checksum using org.apache.hadoop.util.PureJavaCrc32 2015-09-30 07:58:41,911 INFO [main] util.ChecksumType: Checksum can use org.apache.hadoop.util.PureJavaCrc32C K: 007/cf1:age/1443612426300/Put/vlen=2/mvcc=0 V: 20 K: 007/cf1:name/1443612329875/Put/vlen=2/mvcc=0 V: zs Scanned kv count -> 2
这里是使用hbase去查看文件。
K: 007/cf1:age/1443612426300/Put/vlen=2/mvcc=0 V: 20 K: 007/cf1:name/1443612329875/Put/vlen=2/mvcc=0 V: zs
这个是插入的数据,一个列族为一个store,使用方式和时间戳都有,最后的是value值。
单元格由rowKey、列族+列来决定。
原文:http://wukong0716.blog.51cto.com/10442773/1700257