HBase简介

HBase:是建立的hdfs之上,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统,位于结构化存储层,Hadoop HDFS为HBase提供了高可靠性的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定服务和failover机制。
 
含义:HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分 布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
     HBase利用Hadoop HDFS作为其文件存储系统;Google运行MapReduce来处理Bigtable中的海量数据,HBase同样利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用 Chubby作为协同服务,HBase利用Zookeeper作为对应。
特点:1.分布式存储:   分布式系统主要需要考虑两个方面:partitioning(分区存储,也可以理解为通常说的Sharding)、replication(数据复制,主要是将数据复制成多份以提高可用性)。
      2.列式存储:     普通的RDBMS通常是行式存储的,一行数据是连续存在一段磁盘空间上的。列式存储是将各个列分别进行连续的存储。它对于处理字段中的NULL字段,能够不占用过多的空间。同时能够支持灵活松散的列定义。
      3.顺序写磁盘:   对写性能进行的优化。它的写都是通过先记一条操作日志,然后直接写在内存中的数据集合,然后其集合按条件或定时将数据flush到磁盘。这里涉及到的记操作日志或者数据flush到磁盘都会顺序的磁盘操作。故而避免了磁盘随机操作造成的无谓的磁盘寻道时间。
      4.读操作数据合并: 写操作是通过定时将数据直接flush到磁盘进行的,每次flush都会生成一个数据块,那可能造成一个数据在多个数据块中的情况,而在读的时候就需要将这多个版本中的值进行合并。其中在判断一个数据块是否包含指定值时使用了bloom-filter算法。
      5.定期数据合并:   一个数据可能存在于多个数据块,如果我们不做处理,随着时间的推移,数据块会越来越多。所以系统会进行定时的数据合并。将内存中的数据直接flush到磁盘的过程中,flush之前进行了一次数据的排序操作,既是说存在磁盘中的块中的数据,都是顺序的,那么对一堆顺序的数据进行排重合并,其实和我们熟知的多路归并排序很相似。故而其定时数据合并的效率也是非常高的。
      6.稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。 
 
  
数据模型:          
      table:非结构化的,也就是基于列而不是行
            行健(row key):table主键, HBase不支持条件查询和Order by等查询,读取记录只能按Row key(及其range)或全表扫描,因此Row key需要根据业务来设计以利用其存储排序特性(Table按Row key字典序排序如1,10,100,11,2)提高性能。
            时间戳(Timestamp):每次数据操作对应的时间戳,可以看做是数据version number
            列簇(column Family):
                列(column):HBase的每个列都属于一个列族,以列族名为前缀,如列article:title和article:content属于article列族,author:name和author:nickname属于author列族。
           
 
 
Table与Region:由来:当Table随着记录数不断增加而变大后,会逐渐分裂成多份splits,成为regions,一个region由[startkey,endkey)表示,不同的region会被Master分配给相应的RegionServer进行管理:
   
Client访问用户表执行过程:
       HBase中的俩张特殊表:
            1..META.:记录了用户表的Region信息,.META.可以有多个regoin
            2.-ROOT-:记录了.META.表的Region信息,-ROOT-只有一个region
            Zookeeper中记录了-ROOT-表的location            
       执行过程: Client访问用户数据之前需要首先访问zookeeper,然后访问-ROOT-表,接着访问.META.表,最后才能找到用户数据的位置去访问,中间需要多次网络操作,不过client端会做cache缓存。

并行处理运算(MapReduce on HBase)
       HBase系统架构:
           Client:  HBase Client使用HBase的RPC机制与HMaster和HRegionServer进行通信,对于管理类操作,Client与HMaster进行RPC;对于数据读写类操作,Client与HRegionServer进行RPC
           Zookeeper:   Zookeeper Quorum中除了存储了-ROOT-表的地址和HMaster的地址,HRegionServer也会把自己以Ephemeral方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的健康状态。
    此外,Zookeeper也避免了HMaster的单点问题
           HMaster:     HMaster没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行 
                作用:1. 管理用户对Table的增、删、改、查操作
                      2. 管理HRegionServer的负载均衡,调整Region分布
                      3. 在Region Split后,负责新Region的分配
                      4. 在HRegionServer停机后,负责失效HRegionServer 上的Regions迁移
           HRegionServer:   HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。总的来说,一个表由多个Region组成(里面有HLog),一个Region包括多个store,每个store存储一个列簇,每个Strore又由一个memStore和0至多个StoreFile组成(和HFile)。
                 HRegionServer内部管理了一系列HRegion对象,每个HRegion对应了Table中的一个Region,HRegion中由多个HStore组成。每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。
                      HStore存储是HBase存储的核心了(由MemStore和StoreFiles组成)。
                          MemStore:  是Sorted Memory Buffer,用户写入的数据首先会放入MemStore,
                          StoreFile;当MemStore满了以后会Flush成一个StoreFile(底层实现是HFile),当StoreFile文件数量增长到一定阈值,会触发Compact合并操作,将多个StoreFiles合并成一个StoreFile,合并过程中会进行版本合并和数据删除,因此可以看出HBase其实只有增加数据,所有的更新和删除操作都是在后续的compact过程中进行的,这使得用户的写操作只要进入内存中就可以立即返回,保证了HBase I/O的高性能
                          当StoreFiles Compact后,会逐步形成越来越大的StoreFile,当单个StoreFile大小超过一定阈值后,会触发Split操作,同时把当前Region Split成2个Region,父Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer上,使得原先1个Region的压力得以分流到2个Region上。
                      HLog: 每个HRegionServer中都有一个HLog对象,以防系统出错或者宕机而导致HRegionServer意外退出。在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中(HLog文件格式见后续),HLog文件定期会滚动出新的,并删除旧的文件(已持久化到StoreFile中的数据)。当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的 HLog文件,将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取 到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。

       HBase存储格式(文件类型):  HBase中的所有数据文件都存储在Hadoop HDFS文件系统上
           HFile: (能快速高效的存储数据)   HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile
                原理(结构):1.HFile文件时不定长的。
        HLog File: HBase中WAL(Write Ahead Log) 的存储格式,物理上是Hadoop的Sequence File

           读的流程:通过某个特定的RowKey查询一行记录,首先Client端会连接Zookeeper Qurom,通过Zookeeper,Client能获知哪个Server管理-ROOT- Region。接着Client访问管理-ROOT-的Server,进而获知哪个Server管理.META.表。这两个信息Client只会获取一次并缓存起来。在后续的操作中Client会直接访问管理.META.表的Server,并获取Region分布的信息。一旦Client获取了这一行的位置信息,比如这一行属于哪个Region,Client将会缓存这个信息并直接访问HRegionServer。久而久之Client缓存的信息渐渐增多,即使不访问.META.表也能知道去访问哪个HRegionServer。
           写流程:1.Client发起了一个HTable.put(Put)请求给HRegionServer,HRegionServer会将请求匹配到某个具体的HRegion上面。
                   2.决定是否写WAL log。是否写WAL log由Client传递的一个标志决定,你可以设置这个标志:Put.writeToWAL(boolean)。WAL log文件是一个标准的Hadoop SequenceFile(现在还在讨论是否应该把文件格式改成一个更适合HBase的格式)。在文件中存储了HLogKey,这些Keys包含了和实际数据对应的序列号,用途是当RegionServer崩溃以后能将WAL log中的数据同步到永久存储中去。
                   3.Put数据会被保存到MemStore中,同时会检查MemStore是否已经满了,如果已经满了,则会触发一个Flush to Disk的请求。HRegionServer有一个独立的线程来处理Flush to Disk的请求,它负责将数据写成HFile文件并存到HDFS上。它也会存储最后写入的数据序列号,这样就可以知道哪些数据已经存入了永久存储的HDFS中。 
HBase coprocessor:
           简介:HBase协处理器,是RegionServer和Master进程内的通信框架.它是一个类似mapReduce的分析组件,但是极大的简化mapreduce模型,只是将请求独立地在各个region中并行的运行,并且提供了一套框架能够让用户非常灵活地编写自定义的coprocessor.客户端向RegionServer注入代码并行执行获取结果.其核心是轻量级RPC远程调用和通信框架。
   工作流程:1.客户端获得一个服务端通信接口的实例;
    2.客户端调用这个实例中的方法;
    3.客户端向服务端传输调用请求;
    4.服务端接口实现被调用;
    5.服务端向客户端传输结果.
   优先级:所有的coprocessor实现类都是基于coprocessor类这个接口,这个接口提供了两种类型的优先级,分别为系统和用户.SYSTEM(系统) 最高优先级,USER(用户) 次优先级,优先级定义了coprocessor执行的先后顺序,系统级别的要优于用户级别的先执行.同级别的coprocessor根据设定的优先级顺序执行,设定优先级的值为整数,从0开始,值越大优先级越低.
   实现模式:coprocessor有两种实现模式,分别为observer模式和endpoint模式.我们可以将observer模式看成关系型数据库中的触发器,而endpoint可以看成是关系型存储过程.
    observer模式:称为观察者模式,观察者的设计意图是允许用户通过插入代码来重载协处理器框架的call方法,而具体的事件触发的callback方法由HBase的核心代码来执行.协处理器框架处理所有的callback调用细节,协处理器自身只需要插入、添加或者改变的功能,它提供三种观察者接口:
       1.RegionObserver:提供客户端的数据操纵事件钩子:Get、Put、Delete、Scan等;
       2.WALObserver:提供WAL相关操作钩子;
       3.MasterObserver:提供DDL-类型的操作钩子.如创建、删除、修改数据表等。
       这些接口可以同时使用在同一个地方,按照不同优先级顺序执行.用户可以任意基于协处理器实现复杂的HBase功能层.它们的工作原理类似于钩子函数,在真实的函数实现前加入pre(),实现后加入post()方法,来实现对操作进行一些嵌入式的改变.效率上的影响仅仅取决于嵌入的钩子函数本身的影响.
    endpoint模式:终端是动态RPC插件的接口,它的实现代码被安装在服务器端,从而能够通过HBase RPC唤醒.客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个终端,它们的实现代码会被目标region远程执行,结果会返回到终端.用户可以结合使用这些强大的插件接口,为HBase添加全新的特性,终端的使用,如下面的流程所示:
      1.定义一个新的protocol接口,必须继承CoprocessorProtocol;
      2.实现终端接口,该实现会被导入region环境执行;
      3.继承抽象类BaseEndpointCoprocessor;
      4.在客户端,终端可以被两个新的HBase Client API调用,单个                                                                       region:HTableInterface.coprocessorProxy(Class<T> protocol,byte[] row) ; region区域:                
HTableInterface.coprocessorExec(Class<T> protocol,byte[] startKey,byte[] endKey,Batch.Call<T,R> callable).      
   加载方式:两种加载方式,一种是通过修改hbase-site.xml的配置文件,一种是通过修改表的属性.
      配置文件加载  :
            1.修改hbase-site.xml,具体操作:
<property>
<name>hbase.coprocessor.user.region.classes</name>
<value>com.jd.coprocessortest.AccessControlCoprocessor</value>
</property>
            com.jd.coprocessortest.AccessControlCoprocessor:coprocessor方法实现类的全名,如果实现的类有多个,依次按顺序写入,coprocessor的执行顺序,即是按这时的类名的顺序.
            2.把实现类放到hbase的classpath中
            这种加载方式是全局的,即如果是对表的操作的话,所有的表都会被加载上这份coprocessor,所以这种方法不常用,除了一些不涉及到表的操作时,才会用到,如masterobserver的preCreateTable.
      修改表属性加载:对表属性修改的加载方式,有两种:
            1.直接在创建表的时候,把coprocessor实现类加载上去,具体操作过程:
a.对需要加载的coprocessor的实现类打成jar包,如accessControl.jar;
b.将该jar包上传到hdfs上,上传成功后,获取路径如hdfs://uhp2.54300/coprocessor/accessControl.jar
c.使用client创建表时,对表加上tableDescripter.addCoprocessor("com.jd.coprocessortest.AccessControlCoprocessor",new Path("hdfs://uhp2.54300/coprocessor/accessControl.jar"),100,null).
            com.jd.coprocessortest.AccessControlCoprocessor:为加载coprocessor的全类名,100:该coprocessor的优先级.需要设置优先级,是因为每个region上可能会加载上多个coprocessor,但是每次只能有一个coprocessor被执行,所以需要对coprocessor设置优先级.region上coprocessor的执行就按优先级顺序执行。优先级的类型是自然整数,并且越小,优先级越靠前
            2.表创建完成后,使用hbase shell命令执行
a. disable指定表:    hbase> disable 'mytable'
b. 加载coprocessor   hbase> alter 'mytable', METHOD => 'table_att','coprocessor'=>'hdfs://uhp2:54310/coprocessor/accessControl.jar:AccessControlCoprocessor:100'
c. 重启指定表        hbase> enable 'mytable'

在hbase中的应用
coprocessor在master上应用
1.对表的管理,实现用户权限验证,如只有赋予权限的用户才能创建表、修改表、禁/启用表、对表的region负载均衡、开关闭master管理等。
2.提供DDL-类型的操作钩子。如创建、删除、修改数据表等
coprocessor在regionserver应用
1.可以实现对表的get,scan,put,delete等操作实现用户权限验证
2.可以对put操作实现数据同步
3.实现二级索引,在向表中插入数据时,在另一张表中建立对数据的索引
4.实现触发器的功能
coprocessor WAL中的应用
1.Hlog数据同步,在写入、删除或更新数据时,将Hlog推送到另一个集群
2.监控和拦截WAL写事件或者重建事件
coprocessor endpoint应用  实现服务端自定义函数的开发,类似关系型数据库的存储过程,如编写sum、avg、max、min等
coprocessor实现故障隔离  当region关闭前后,如遇到故障,可以通知master。设置优先级,优先级是针对同一region上的不同coprocessor
提供region的管理的钩子函数,如 open/close/split/flush/compact等操作         
     
    总结:
个人片面理解:HBase的工作流程就相当于上门送货服务:送货员(Client)到了小区门口,会先通过门卫室(Zookeeper)查询到送货地址的具体在几好单位(这是HRegionService)那一层(HRegion)那一间(HStore)。
什么时候用Hbase:  
1.半结构化或非结构化数据。    对于数据结构字段不够确定或杂乱无章很难按一个概念去进行抽取的数据适合用HBase。以上面的例子为例,当业务发展需要存储author的email,phone,address信息时RDBMS需要停机维护,而HBase支持动态增加.
2.记录非常稀疏。              RDBMS的行有多少列是固定的,为null的列浪费了存储空间。而如上文提到的,HBase为null的Column不会被存储,这样既节省了空间又提高了读性能。
3.多版本数据。                如上文提到的根据Row key和Column key定位到的Value可以有任意数量的版本值,因此对于需要存储变动历史记录的数据,用HBase就非常方便了。比如上例中的author的Address是会变动的,业务上一般只需要最新的值,但有时可能需要查询到历史值。
4.超大数据量                当数据量越来越大,RDBMS数据库撑不住了,就出现了读写分离策略,通过一个Master专门负责写操作,多个Slave负责读操作,服务器成本倍增。随着压力增加,Master撑不住了,这时就要分库了,把关联不大的数据分开部署,一些join查询不能用了,需要借助中间层。随着数据量的进一步增加,一个表的记录越来越大,查询就变得很慢,于是又得搞分表,比如按ID取模分成多个表以减少单个表的记录数。经历过这些事的人都知道过程是多么的折腾。采用HBase就简单了,只需要加机器即可,HBase会自动水平切分扩展,跟Hadoop的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性能(MapReduce)。
        

你可能感兴趣的:(数据库,zookeeper,hbase,hdfs,存储)