1-HBase的安装php
2-Java操做HBase例子html
3-HBase简单的优化技巧java
4–存储node
5(集群) -压力分载与失效转发linux
7 -安全&权限算法
HBase是什么?数据库
HBase是Apache Hadoop中的一个子项目,Hbase依托于Hadoop的HDFS做为最基本存储基础单元,经过使用hadoop的DFS工具就能够看到这些这些数据 存储文件夹的结构,还能够经过Map/Reduce的框架(算法)对HBase进行操做,如右侧的图所示:apache
HBase在产品中还包含了Jetty,在HBase启动时采用嵌入式的方式来启动Jetty,所以能够经过web界面对HBase进行管理和查看当前运行的一些状态,很是轻巧。
为何采用HBase?
HBase 不一样于通常的关系数据库,它是一个适合于非结构化数据存储的数据库.所谓非结构化数据存储就是说HBase是基于列的而不是基于行的模式,这样方面读写你的大数据内容。
HBase是介于Map Entry(key & value)和DB Row之间的一种数据存储方式。就点有点相似于如今流行的Memcache,但不只仅是简单的一个key对应一个 value,你极可能须要存储多个属性的数据结构,但没有传统数据库表中那么多的关联关系,这就是所谓的松散数据。
简单来讲,你在HBase中的表建立的能够看作是一张很大的表,而这个表的属性能够根据需求去动态增长,在HBase中没有表与表之间关联查询。你只须要 告诉你的数据存储到Hbase的那个column families 就能够了,不须要指定它的具体类型:char,varchar,int,tinyint,text等等。可是你须要注意HBase中不包含事务此类的功 能。
Apache HBase 和Google Bigtable 有很是类似的地方,一个数据行拥有一个可选择的键和任意数量的列。表是疏松的存储的,所以用户能够给行定义各类不一样的列,对于这样的功能在大项目中很是实用,能够简化设计和升级的成本。
如何运行HBase?
从 Apache的HBase的镜像网站上下载一个稳定版本的HBase http://mirrors.devlib.org/apache/hbase/stable/hbase-0.20.6.tar.gz, 下载完成后,对其进行解压缩。肯定你的机器中已经正确的安装了Java SDK、SSH,不然将没法正常运行。
$ cd /work/hbase
进入此目录
$ vim conf/hbase-env.sh
export JAVA_HOME=/JDK_PATH
编辑 conf/hbase-env.sh 文件,将JAVA_HOME修改成你的JDK安装目录
$ vim conf/regionservers
输入你的全部HBase服务器名,localhost,或者是ip地址
$ bin/start-hbase.sh
启动hbase, 中间须要你输入两次密码,也能够进行设置不须要输入密码,启动成功,如图所示:
$ bin/hbase rest start
启动hbase REST服务后就能够经过对uri: http://localhost:60050/api/ 的通用REST操做(GET/POST/PUT/DELETE)实现对hbase的REST形式数据操做.
也能够输入如下指令进入HQL指令模式
$ bin/hbase shell
$ bin/stop-hbase.sh
关闭HBase服务
启动时存在的问题
因为linux系统的主机名配置不正确,在运行HBase服务器中可能存在的问题,如图所示:
2010-11-05 11:10:20,189 ERROR org.apache.hadoop.hbase.master.HMaster: Can not start master
java.net.UnknownHostException: ubuntu-server216: ubuntu-server216
表示你的主机名不正确,你能够先查看一下 /etc/hosts/中名称是什么,再用 hostname 命令进行修改, hostname you_server_name
查看运行状态
若是你须要对HBase的日志进行监控你能够查看 hbase.x.x./logs/下的日志文件,可使用tail -f 来查看。
经过 web方式查看运行在 HBase 下的zookeeper http://localhost:60010/zk.jsp
若是你须要查看当前的运行状态能够经过web的方式对HBase服务器进行查看,如图所示:
扩展阅读1:
Apach 的 Hadoop的项目中包含了那些产品,如图所示:
Pig 是在MapReduce上构建的查询语言(SQL-like),适用于大量并行计算。
Chukwa 是基于Hadoop集群中监控系统,简单来讲就是一个“看门狗” (WatchDog)
Hive 是DataWareHouse 和 Map Reduce交集,适用于ETL方面的工做。
HBase 是一个面向列的分布式数据库。
Map Reduce 是Google提出的一种算法,用于超大型数据集的并行运算。
HDFS 能够支持千万级的大型分布式文件系统。
Zookeeper 提供的功能包括:配置维护、名字服务、分布式同步、组服务等,用于分布式系统的可靠协调系统。
Avro 是一个数据序列化系统,设计用于支持大批量数据交换的应用。
扩展阅读2:
什么是列存储?列存储不一样于传统的关系型数据库,其数据在表中是按行存储的,列方式所带来的重要好处之一就是,因为查询中的选择规则是经过列来定义的,因 此整个数据库是自动索引化的。按列存储每一个字段的数据汇集存储,在查询只须要少数几个字段的时候,能大大减小读取的数据量,一个字段的数据汇集存储,那就 更容易为这种汇集存储设计更好的压缩/解压算法。这张图讲述了传统的行存储和列存储的区别:
扩展阅读3:
对系统海量的Log4J日志能够存放在一个集中式的机器上,在此机器上安装 splunk 能够方便对全部日志查看,安装方法能够参考:
http://www.splunk.com/base/Documentation/latest/Installation/InstallonLinux
本篇文章讲述用HBase Shell命令 和 HBase Java API 对HBase 服务器 进行操做。在此以前须要对HBase的整体上有个大概的了解。好比说HBase服务器内部由哪些主要部件构成?HBase的内部工做原理是什么?我想学习任何一项知识、技术的态度不能只是知道如何使用,对产品的内部构建一点都不去关心,那样出了问题,很难让你很快的找到答案,甚至咱们但愿最后能对该项技术的领悟出本身的心得,为我所用,借鉴该项技术其中的设计思想创造出本身的解决方案,更灵活的去应对多变的计算场景与架构设计。以我目前的对HBase的了解还不够深刻,未来不断的学习,我会把我所知道的点滴分享到这个Blog上。
先来看一下读取一行记录HBase是如何进行工做的,首先HBase Client端会链接Zookeeper Qurom(从下面的代码也能看出来,例如:HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.50.216") )。经过Zookeeper组件Client能获知哪一个Server管理-ROOT- Region。那么Client就去访问管理-ROOT-的Server,在META中记录了HBase中全部表信息,(你可使用 scan '.META.' 命令列出你建立的全部表的详细信息),从而获取Region分布的信息。一旦Client获取了这一行的位置信息,好比这一行属于哪一个Region,Client将会缓存这个信息并直接访问HRegionServer。长此以往Client缓存的信息渐渐增多,即便不访问.META.表也能知道去访问哪一个HRegionServer。HBase中包含两种基本类型的文件,一种用于存储WAL的log,另外一种用于存储具体的数据,这些数据都经过DFS Client和分布式的文件系统HDFS进行交互实现存储。
如图所示:
再来看看HBase的一些内存实现原理:
HMaster— HBase中仅有一个Master server。
HRegionServer—负责多个HRegion使之能向client端提供服务,在HBase cluster中会存在多个HRegionServer。
ServerManager—负责管理Region server信息,如每一个Region server的HServerInfo(这个对象包含HServerAddress和startCode),已load Region个数,死亡的Region server列表
RegionManager—负责将region分配到region server的具体工做,还监视root和meta 这2个系统级的region状态。
RootScanner—按期扫描root region,以发现没有分配的meta region。
MetaScanner—按期扫描meta region,以发现没有分配的user region。
HBase基本命令
下面咱们再看看看HBase的一些基本操做命令,我列出了几个经常使用的HBase Shell命令,以下:
名称 |
命令表达式 |
|
建立表 | create '表名称', '列名称1','列名称2','列名称N' | |
添加记录 | put '表名称', '行名称', '列名称:', '值' | |
查看记录 | get '表名称', '行名称' | |
查看表中的记录总数 | count '表名称' | |
删除记录 | delete '表名' ,'行名称' , '列名称' | |
删除一张表 | 先要屏蔽该表,才能对该表进行删除,第一步 disable '表名称' 第二步 drop '表名称' | |
查看全部记录 | scan "表名称" | |
查看某个表某个列中全部数据 | scan "表名称" , ['列名称:'] | |
更新记录 | 就是重写一遍进行覆盖 |
若是你是一个新手队HBase的一些命令还不算很是熟悉的话,你能够进入 hbase 的shell 模式中你能够输入 help 命令查看到你能够执行的命令和对该命令的说明,例如对scan这个命令,help中不只仅提到有这个命令,还详细的说明了scan命令中可使用的参数和做用,例如,根据列名称查询的方法和带LIMIT 、STARTROW的使用方法:
scan Scan a table; pass table name and optionally a dictionary of scanner specifications. Scanner specifications may include one or more of the following: LIMIT, STARTROW, STOPROW, TIMESTAMP, or COLUMNS. If no columns are specified, all columns will be scanned. To scan all members of a column family, leave the qualifier empty as in 'col_family:'. Examples: hbase> scan '.META.' hbase> scan '.META.', {COLUMNS => 'info:regioninfo'} hbase> scan 't1', {COLUMNS => ['c1', 'c2'], LIMIT => 10, STARTROW => 'xyz'} |
使用Java API对HBase服务器进行操做
须要下列jar包
hbase-0.20.6.jar hadoop-core-0.20.1.jar commons-logging-1.1.1.jar zookeeper-3.3.0.jar log4j-1.2.91.jar import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.io.BatchUpdate; @SuppressWarnings("deprecation") public class HBaseTestCase { static HBaseConfiguration cfg = null; static { Configuration HBASE_CONFIG = new Configuration(); HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.50.216"); HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181"); cfg = new HBaseConfiguration(HBASE_CONFIG); } /** * 建立一张表 */ public static void creatTable(String tablename) throws Exception { HBaseAdmin admin = new HBaseAdmin(cfg); if (admin.tableExists(tablename)) { System.out.println("table Exists!!!"); } else{ HTableDescriptor tableDesc = new HTableDescriptor(tablename); tableDesc.addFamily(new HColumnDescriptor("name:")); admin.createTable(tableDesc); System.out.println("create table ok ."); } } /** * 添加一条数据 */ public static void addData (String tablename) throws Exception{ HTable table = new HTable(cfg, tablename); BatchUpdate update = new BatchUpdate("Huangyi"); update.put("name:java", "http://www.javabloger.com".getBytes()); table.commit(update); System.out.println("add data ok ."); } /** * 显示全部数据 */ public static void getAllData (String tablename) throws Exception{ HTable table = new HTable(cfg, tablename); Scan s = new Scan(); ResultScanner ss = table.getScanner(s); for(Result r:ss){ for(KeyValue kv:r.raw()){ System.out.print(new String(kv.getColumn())); System.out.println(new String(kv.getValue() )); } } } public static void main (String [] agrs) { try { String tablename="tablename"; HBaseTestCase.creatTable(tablename); HBaseTestCase.addData(tablename); HBaseTestCase.getAllData(tablename); } catch (Exception e) { e.printStackTrace(); } } } |
这篇文章浅显的从几个方面谈谈HBase的一些优化技巧,只能做为我学习笔记的一部分,由于学多了怕忘,留给本身之后看看。
1 修改 linux 系统参数
Linux系统最大可打开文件数通常默认的参数值是1024,若是你不进行修改并发量上来的时候会出现“Too Many Open Files”的错误,致使整个HBase不可运行,你能够用ulimit -n 命令进行修改,或者修改/etc/security/limits.conf 和/proc/sys/fs/file-max 的参数,具体如何修改能够去Google 关键字 “linux limits.conf ”
2 JVM 配置
修改 hbase-env.sh 文件中的配置参数,根据你的机器硬件和当前操做系统的JVM(32/64位)配置适当的参数
HBASE_HEAPSIZE 4000 HBase使用的 JVM 堆的大小
HBASE_OPTS "‐server ‐XX:+UseConcMarkSweepGC"JVM GC 选项
HBASE_MANAGES_ZKfalse 是否使用Zookeeper进行分布式管理
3 HBase持久化
重启操做系统后HBase中数据全无,你能够不作任何修改的状况下,建立一张表,写一条数据进行,而后将机器重启,重启后你再进入HBase的shell中使用 list 命令查看当前所存在的表,一个都没有了。是否是很杯具?没有关系你能够在hbase/conf/hbase-default.xml中设置hbase.rootdir的值,来设置文件的保存位置指定一个文件夹 ,例如:<value>file:///you/hbase-data/path</value>,你创建的HBase中的表和数据就直接写到了你的磁盘上,如图所示:
一样你也能够指定你的分布式文件系统HDFS的路径例如: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR,这样就写到了你的分布式文件系统上了。
4 配置HBase运行参数
其次就须要对hbase/conf/hbase-default.xml 文件进行配置,如下是我认为比较重要的配置参数
hbase.client.write.buffer
描述:这个参数能够设置写入数据缓冲区的大小,当客户端和服务器端传输数据,服务器为了提升系统运行性能开辟一个写的缓冲区来处理它, 这个参数设置若是设置的大了,将会对系统的内存有必定的要求,直接影响系统的性能。
hbase.master.meta.thread.rescanfrequency
描述:多长时间 HMaster对系统表 root 和 meta 扫描一次,这个参数能够设置的长一些,下降系统的能耗。
hbase.regionserver.handler.count
描述:因为HBase/Hadoop的Server是采用Multiplexed, non-blocking I/O方式而设计的,因此它能够透过一个Thread来完成处理,可是因为处理Client端所呼叫的方法是Blocking I/O,因此它的设计会将Client所传递过来的物件先放置在Queue,并在启动Server时就先产生一堆Handler(Thread),该Handler会透过Polling的方式来取得该物件并执行对应的方法,默认为25,根据实际场景能够设置大一些。
hbase.regionserver.thread.splitcompactcheckfrequency
描述:这个参数是表示多久去RegionServer服务器运行一次split/compaction的时间间隔,固然split以前会先进行一个compact操做.这个compact操做多是minor compact也多是major compact.compact后,会从全部的Store下的全部StoreFile文件最大的那个取midkey.这个midkey可能并不处于所有数据的mid中.一个row-key的下面的数据可能会跨不一样的HRegion。
hbase.hregion.max.filesize
描述:HRegion中的HStoreFile最大值,任何表中的列族一旦超过这个大小将会被切分,而HStroeFile的默认大小是256M。
hfile.block.cache.size
描述:指定 HFile/StoreFile 缓存在JVM堆中分配的百分比,默认值是0.2,意思就是20%,而若是你设置成0,就表示对该选项屏蔽。
hbase.zookeeper.property.maxClientCnxns
描述: 这项配置的选项就是从zookeeper中来的,表示ZooKeeper客户端同时访问的并发链接数,ZooKeeper对于HBase来讲就是一个入口这个参数的值能够适当放大些。
hbase.regionserver.global.memstore.upperLimit
描述:在Region Server中全部memstores占用堆的大小参数配置,默认值是0.4,表示40%,若是设置为0,就是对选项进行屏蔽。
hbase.hregion.memstore.flush.size
描述:Memstore中缓存的内容超过配置的范围后将会写到磁盘上,例如:删除操做是先写入MemStore里作个标记,指示那个value, column 或 family等下是要删除的,HBase会按期对存储文件作一个major compaction,在那时HBase会把MemStore刷入一个新的HFile存储文件中。若是在必定时间范围内没有作major compaction,而Memstore中超出的范围就写入磁盘上了。
5 HBase中log4j的日志
HBase中日志输出等级默认状态下是把debug、 info 级别的日志打开的,能够根据本身的须要调整log级别,HBase的log4j日志配置文件在 hbase\conf\log4j.properties 目录下。
在HBase中建立的一张表能够分布在多个Hregion,也就说一张表能够被拆分红多块,每一块称咱们呼为一个Hregion。每一个Hregion会保 存一个表里面某段连续的数据,用户建立的那个大表中的每一个Hregion块是由Hregion服务器提供维护,访问Hregion块是要经过 Hregion服务器,而一个Hregion块对应一个Hregion服务器,一张完整的表能够保存在多个Hregion 上。HRegion Server 与Region的对应关系是一对多的关系。每个HRegion在物理上会被分为三个部分:Hmemcache(缓存)、Hlog(日志)、HStore(持久层)。
上述这些关系在我脑海中的样子,如图所示:
1.HRegionServer、HRegion、Hmemcache、Hlog、HStore之间的关系,如图所示:
2.HBase表中的数据与HRegionServer的分布关系,如图所示:
HBase读数据
HBase读取数据优先读取HMemcache中的内容,若是未取到再去读取Hstore中的数据,提升数据读取的性能。
HBase写数据
HBase写入数据会写到HMemcache和Hlog中,HMemcache创建缓存,Hlog同步Hmemcache和Hstore的事务日志,发起Flush Cache时,数据持久化到Hstore中,并清空HMemecache。
客户端访问这些数据的时候经过Hmaster ,每一个 Hregion 服务器都会和Hmaster 服务器保持一个长链接,Hmaster 是HBase分布式系统中的管理者,他的主要任务就是要告诉每一个Hregion 服务器它要维护哪些Hregion。用户的这些都数据能够保存在Hadoop 分布式文件系统上。 若是主服务器Hmaster死机,那么整个系统都会无效。下面我会考虑如何解决Hmaster的SPFO的问题,这个问题有点相似Hadoop的SPFO 问题同样只有一个NameNode维护全局的DataNode,HDFS一旦死机所有挂了,也有人说采用Heartbeat来解决这个问题,但我总想找出 其余的解决方案,多点时间,总有办法的。
昨天在hadoop-0.21.0、hbase-0.20.6的环境中折腾了好久,一直报错,错误信息以下:
Exception in thread "main" java.io.IOException: Call to localhost/serv6:9000 failed on local exception: java.io.EOFException 10/11/10 15:34:34 ERROR master.HMaster: Can not start master java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.apache.hadoop.hbase.master.HMaster.doMain(HMaster.java:1233) at org.apache.hadoop.hbase.master.HMaster.main(HMaster.java:1274) |
死活链接不上HDFS,也没法链接HMaster,郁闷啊。
我想一想啊,慢慢想,我眼前一亮 java.io.EOFException 这个异常,是否是有多是RPC 协定格式不一致致使的?也就是说服务器端和客户端的版本不一致的问题?换了一个HDFS的服务器端之后,一切都好了,果真是版本的问题,最后采用 hadoop-0.20.2 搭配hbase-0.20.6 比较妥当。
最后的效果如图所示:
上图的一些文字说明:
hadoop版本是0.20.2 ,
hbase版本是0.20.6,
在hbase中建立了一张表 tab1,退出hbase shell环境,
用hadoop命令查看,文件系统中的文件果真多了一个刚刚建立的tab1目录,以上这张图片说明HBase在分布式文件系统Apache HDFS中运行了。
在上一篇关于HBase的文章中曾经讲述过HBase在分布式中的架构,这篇文章将会讲述HBase在分布式环境中是如何排除单点故障的(SPFO),作一个小实验讲述HBase在分布式环境中的高可用性,亲眼看到一些现象,延伸一些思考的话题。
先来回顾一下HBase主要部件:
HBaseMaster
HRegionServer
HBase Client
HBase Thrift Server
HBase REST Server
HBaseMaster
HMaster 负责给HRegionServer分配区域,而且负责对集群环境中的HReginServer进行负载均衡,HMaster还负责监控集群环境中的HReginServer的运行情况,若是某一台HReginServer down机,HBaseMaster将会把不可用的HReginServer来提供服务的HLog和表进行从新分配转交给其余HReginServer来提供,HBaseMaster还负责对数据和表进行管理,处理表结构和表中数据的变动,由于在 META 系统表中存储了全部的相关表信息。而且HMaster实现了ZooKeeper的Watcher接口能够和zookeeper集×××互。
HRegionServer
HReginServer负责处理用户的读和写的操做。HReginServer经过与HBaseMaster通讯获取本身须要服务的数据表,并向HMaster反馈本身的运行情况。当一个写的请求到来的时候,它首先会写到一个叫作HLog的write-ahead log中。HLog被缓存在内存中,称为Memcache,每个HStore只能有一个Memcache。当Memcache到达配置的大小之后,将会建立一个MapFile,将其写到磁盘中去。这将减小HReginServer的内存压力。当一块儿读取的请求到来的时候,HReginServer会先在Memcache中寻找该数据,当找不到的时候,才会去在MapFiles 中寻找。
HBase Client
HBase Client负责寻找提供需求数据的HReginServer。在这个过程当中,HBase Client将首先与HMaster通讯,找到ROOT区域。这个操做是Client和Master之间仅有的通讯操做。一旦ROOT区域被找到之后,Client就能够经过扫描ROOT区域找到相应的META区域去定位实际提供数据的HReginServer。当定位到提供数据的HReginServer之后,Client就能够经过这个HReginServer找到须要的数据了。这些信息将会被Client缓存起来,当下次请求的时候,就不须要走上面的这个流程了。
HBase服务接口
HBase Thrift Server和HBase REST Server是经过非Java程序对HBase进行访问的一种途径。
进入正题
先来看一个HBase集群的模拟环境,此环境中一共有4台机器,分别包含 zookeeper、HBaseMaster、HReginServer、HDSF 4个服务,为了展现失效转发的效果HBaseMaster、HReginServer各有2台,只是在一台机器上即运行了HBaseMaster,也运行了HReginServer。
注意,HBase的集群环境中HBaseMaster只有失效转发没有压力分载的功能,而HReginServer即提供失效转发也提供压力分载。
服务器清单以下:
zookeeper 192.168.20.214
HBaseMaster 192.168.20.213/192.168.20.215
HReginServer 192.168.20.213/192.168.20.215
HDSF 192.168.20.212
整个模拟环境的架构如图所示:
注意,这里只是作了一个模拟环境,由于这个环境的重点是HBase,因此zookeeper和HDFS服务都是单台。
虽说在整个HBase的集群环境中只能有一个HMaster,但是在集群环境中HMaster能够启动多个,但真正使用到的HMaster Server只有一个,他不down掉的时候,其余启动的HMaster Server并不会工做,直到与ZooKeeper服务器判断与当前运行的HMaster通信超时,认为这个正在运行的HMaster服务器down掉了,Zookeeper才会去链接下一台HMaster Server。
简单来讲,若是运行中HMaster服务器down掉了,那么zookeeper会从列表中选择下一个HMaster 服务器进行访问,让他接管down掉的HMaster任务,换而言之,用Java客户端对HBase进行操做是经过ZooKeeper的,也就是说若是zookeeper集群中的节点全挂了 那么HBase的集群也挂了。自己HBase并不存储中的任何数据 真正的数据是保存在HDFS上,因此HBase的数据是一致的,可是HDFS文件系统挂了,HBase的集群也挂。
在一台HMaster失败后,客户端对HBase集群环境访问时,客户端先会经过zookeeper识别到HMaster运行异常,直到确认屡次后,才链接到下一个HMaster,此时,备份的HMaster服务才生效,在IDE环境中的效果,如图所示:
上图中能看见抛出的一些异常和name:javahttp://www.javabloger.com和name:javahttp://www.javabloger.com1的结果集,由于我在serv215机器上用killall java命令把 HMaster和HReginServer都关掉,而且马上用Java客户端对HBase的集群环境进行访问有异常抛出,可是retry到必定次数后查询出结果,前面已经说了访问HBase是经过zookeeper再和真正的数据打交道,也就是说zookeeper接管了一个standby 的 HMaster,让原先Standby的HMaster接替了失效的HMaster任务,而被接管的HBaseMaster再对HReginServer的任务进行分配,当 HReginServer失败后zookeeper会通知 HMaster对HReginServer的任务进行分配。这样充分的说明了HBase作到了实效转发的功能。
如图所示:
口水:
一、HBase的失效转发的效率比较慢了,不期望能在1-2秒切换和恢复完毕,也许是我暂时没有发现有什么参数能够提升失效转发和恢复过程的速度,未来会继续关注这个问题。
二、在官方网站上看见HBase0.89.20100924的版本有篇讲述关于数据同步的文章,我尝试了一下在一台机器上能够运行所谓的HBase虚拟集群环境,可是切换到多台机器的分布式环境中,单点失效转发的速度很慢比HBase0.20.6还要慢,我又检查了是否存在网络的问题,目前还没有找到正确的答案,对与HBase0.89.20100924 新版中的数据同步的原理,如图所示:(更多信息)
个人废话1:
任何一项新技术并不是救命稻草,一抹一擦立马药到病除的百宝箱,并不是使用Spring或者NOSQL的产品就神乎其神+五颜六色,若是那样基本是扯淡。同类 型产品中无论那种技术最终要达到的目的是同样的,经过新的技术手段你每每可能避讳了当前你所须要面对的问题,但事后新的问题又来了。也许回过头来看看还不 如在原来的基础上多动动脑筋 想一想办法 作些改良能够获得更高的回报。
传统数据库是以数据块来存储数据,简单来讲,你的表字段越多,占用的数据空间就越多,那么查询有可能就要跨数据块,将会致使查询的速度变慢。在大型系统中一张表上百个字段,而且表中的数据上亿条这是彻底是有可能的。所以会带来数据库查询的瓶颈。咱们都知道一个常识数据库中表记录的多少对查询的性能有很是大的影响,此时你颇有可能想到分表、分库的作法来分载数据库运算的压力,那么又会带来新的问题,例如:分布式事务、全局惟一ID的生成、跨数据库查询 等,依旧会让你面对棘手的问题。若是打破这种按照行存储的模式,采用一种基于列存储的模式,对于大规模数据场景这样状况有可能发生一些好转。因为查询中的选择规则是经过列来定义的,所以整个数据库是自动索引化的。按列存储每一个字段的数据汇集存储, 能够动态增长,而且列为空就不存储数据,节省存储空间。 每一个字段的数据按照汇集存储,能大大减小读取的数据量,查询时指哪打哪,来的更直接。无需考虑分库、分表 Hbase将对存储的数据自动切分数据,并支持高并发读写操做,使得海量数据存储自动具备更强的扩展性。
Java中的HashMap是Key/Value的结构,你也能够把HBase的数据结构看作是一个Key/Value的体系,话说HBase的区域由表名和行界定的。在HBase区域每个"列族"都由一个名为HStore的对象管理。每一个HStore由一个或多个MapFiles(Hadoop中的一个文件类型)组成。MapFiles的概念相似于Google的SSTable。 在Hbase里面有如下两个主要的概念,Row key 和 Column Family,其次是Cell qualifier和Timestamp tuple,Column family咱们一般称之为“列族”,访问控制、磁盘和内存的使用统计都是在列族层面进行的。列族Column family是以前预先定义好的数据模型,每个Column Family均可以根据“限定符”有多个column。在HBase每一个cell存储单元对同一份数据有多个版本,根据惟一的时间戳来区分每一个版本之间的差别,最新的数据版本排在最前面 。
口水:Hbase将table水平划分红N个Region,region按column family划分红Store,每一个store包括内存中的memstore和持久化到disk上的HFile。
上述可能我表达的还不够到位,下面来看一个实践中的场景,将原来是存放在MySQL中Blog中的数据迁移到HBase中的过程:
MySQL中现有的表结构:
迁移HBase中的表结构:
原来系统中有2张表blogtable和comment表,采用HBase后只有一张blogtable表,若是按照传统的RDBMS的话,blogtable表中的列是固定的,好比schema 定义了Author,Title,URL,text等属性,上线后表字段是不能动态增长的。可是若是采用列存储系统,好比Hbase,那么咱们能够定义blogtable表,而后定义info 列族,User的数据能够分为:info:title ,info:author ,info:url 等,若是后来你又想增长另外的属性,这样很方便只须要 info:xxx 就能够了。
对于Row key你能够理解row key为传统RDBMS中的某一个行的主键,Hbase是不支持条件查询以及Order by等查询,所以Row key的设计就要根据你系统的查询需求来设计了额。 Hbase中的记录是按照rowkey来排序的,这样就使得查询变得很是快。
具体操做过程以下:
============================建立blogtable表========================= create 'blogtable', 'info','text','comment_title','comment_author','comment_text' ============================插入概要信息========================= put 'blogtable', '1', 'info:title', 'this is doc title' put 'blogtable', '1', 'info:author', 'javabloger' put 'blogtable', '1', 'info:url', 'http://www.javabloger.com/index.php' put 'blogtable', '2', 'info:title', 'this is doc title2' put 'blogtable', '2', 'info:author', 'H.E.' put 'blogtable', '2', 'info:url', 'http://www.javabloger.com/index.html' ============================插入正文信息========================= put 'blogtable', '1', 'text:', 'what is this doc context ?' put 'blogtable', '2', 'text:', 'what is this doc context2?' ==========================插入评论信息=============================== put 'blogtable', '1', 'comment_title:', 'this is doc comment_title ' put 'blogtable', '1', 'comment_author:', 'javabloger' put 'blogtable', '1', 'comment_text:', 'this is nice doc' put 'blogtable', '2', 'comment_title:', 'this is blog comment_title ' put 'blogtable', '2', 'comment_author:', 'H.E.' put 'blogtable', '2', 'comment_text:', 'this is nice blog' |
HBase的数据查询\读取,能够经过单个row key访问,row key的range和全表扫描,大体以下:
注意:HBase不能支持where条件、Order by 查询,只支持按照Row key来查询,可是能够经过HBase提供的API进行条件过滤。
例如:http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html
scan 'blogtable' ,{COLUMNS => ['text:','info:title'] } —> 列出 文章的内容和标题
scan 'blogtable' , {COLUMNS => 'info:url' , STARTROW => '2'} —> 根据范围列出 文章的内容和标题
get 'blogtable','1' —> 列出 文章id 等于1的数据
get 'blogtable','1', {COLUMN => 'info'} —> 列出 文章id 等于1 的 info 的头(Head)内容
get 'blogtable','1', {COLUMN => 'text'} —> 列出 文章id 等于1 的 text 的具体(Body)内容
get 'blogtable','1', {COLUMN => ['text','info:author']} —> 列出 文章id 等于1 的内容和做者(Body/Author)内容
个人废话2:
有人会问Java Web服务器中是Tomcat快仍是GlassFish快?小型数据库中是MySQL效率高仍是MS-SQL效率高?我看是关键用在什么场景和怎么使用这 个产品(技术),因此我渐渐的认为是须要对产品、技术自己深刻的了解,而并不是一项新的技术就是绝佳的选择。试问:Tomcat的默认的运行参数能和咱们线 上正在使用的GlassFish性能相提并论吗?我不相信GlassFishv2和GlassFishv3在默认的配置参数下有显著的差异。咱们须要对产 品自己作到深刻的了解才能发挥他最高的性能,而并不是感观遵从厂家的广告和本身的感性认识 迷信哪一个产品的优越性。
个人废话3:
对于NOSQL这样的新技术,的的确确是能够解决过去咱们所须要面对的问题,但也并不是适合每一个应用场景,因此在使用新产品的同时须要切合当前的产品须要, 是需求在引导新技术的投入,而并不是为了赶时髦去使用他。你的产品是否过硬不是你使用了什么新技术,用户关心的是速度和稳定性,不会关心你是否使用了 NOSQL。相反Google有着超大的数据量,能给全世界用户带来了惊人的速度和准确性,你们才会回过头来好奇Google究竟是怎么作到的。因此根据 本身的须要千万别太勉强本身使用了某项新技术。
个人废话4:
总之一句话,用什么不是最关键,最关键是怎么去使用!
个人废话:
大年三十夜,看春晚实在是太无聊了,整个《新闻联播》的电视剧版本,还不如上上网,看看资料,喝喝老酒,写点东西来的快活。
近2年来云计算的话题到目前为止风风火火历来没有平静过,一直是你们嘴边讨论的热门话题,人们指望运用云计算提供可靠、稳定、高速的计算,在云计算中Google是目前最大的云计算供应商,例如:Google GAE(Google App Engine)和Google的Docs在线文章服务,这些SaaS上线产品的数据存储(datastore)是由BigTable提供存储服务的,在次以前我提到过Yahoo贡献给Apache的那些山寨版本(Google与Yahoo的那些利器),其中Apache的HBase就是山寨了Google的BigTable。
咱们知道在云计算的技术话题中Apache的Hadoop项目是一块基石,利用Hadoop项目中的产品能够创建云计算平台和超大型的计算。不知道你是否有想过若是将HBase做为Google GAE上的数据存储(datastore),那么每一个用户之间的数据访问权限怎么办?若是使用HBase提供对大客户提供“私有云”(private cloud)或者另外一种可能一个公司内部的集群上运行HBase,公司的内部可能有几个部门,某几个部门之间的数据都是独立分离但又运行在一个平台上,那么你就会发现HBase不具有这样的功能,貌似目前HBase的最高版本0.90.0尚未这样的功能对用户的表、Row、Cell的访问权限。可是咱们知道Google的GAE上每一个用户访问的数据确定是有权限划分的,否则我只要有权限登陆GEA就能看见全部用户存放的数据了。这样的问题你有可能没有想过,但趋势公司的工程师们却为此想到了这点,而且把他们的设想和设计提交了HBase项目组,而且提出了如下主要的设计思想:
Client access to HBase is authenticated
User data is private unless access has been granted
Access to data can be granted at a table or per column family basis.
对HBase中的表和数据划分权限等级和身份验证后,操做权限被分为3大类,每类中包含的操做权限以下所示:
对于方案中涉及到存储的权限的是指整个表或表中的列族,也就是说只考虑在表这个级别的权限,表与表之间的所属关系是存放在 .META. 系统表中,以regioninfo:owner 的格式进行存放,例如:系统中table1这个表是有权限的,这个表权限的存根保存在3个地方 :
The row in .META. for the first region of table1
The node /hbase/acl/table1 of Zookeeper
The in-memory Permissions Mirror of every regionserver that serves table1
如图所示,图中的箭头表示了数据流向的顺序:
方案中HBase在分布式、集群环境下,而权限一致性的问题交给了Zookeeper来处理,在多个regionservers中,每一个服务器的HRegion中存放着多个表,而且实现了(implement)ZKPermissionWatcher接口的nodeCreated() 和 nodeChanged() 方法,这2个方法对Zookeeper 的节点进行监控, 节点的状态发生相应的变化时会ZooKeeper刷新镜像中的权限。
如图所示:
HBase的这一关于权限的功能正在设计和研讨当中,让咱们继续对他保持关注,看看从此将会发生的变化能给咱们带来什么样的效果,很是期待这个功能早日正式发布。