HBase 即Hadoop Database,是一个基于Google Bigtable实现的开源的、高可靠性、高性能、面向列、可伸缩、实时读写、大容量的分布式数据库。
以Hadoop MapReduce来处理HBase中的海量数据计算,
以Hadoop HDFS来处理HBase中的海量数据存储,
以Zookeeper作为其分布式协同服务、元数据存储,
主要用来存储结构化、非结构化、半结构化的数据,满足CAP定理(Consistency, Availability, and Partition Tolerance)中的CP项。
下面从如下几个方面介绍下其相关理论:
架构
核心知识点
部署方式
优缺点分析
常见应用场景
调优经验
API应用
1、Client
HBase的客户端。
包含访问HBase的接口并维护cache来加快对HBase的访问
使用RPC机制Zookeeper、HMaster、HRegionServer进行通信,完成提交请求和获取结果
2、Zookeeper
ZooKeeper为HBase集群提供协调服务、存储schema、table、Region寻址入口等元数据,主要要设计两个表:-ROOT-表(根数据表)和.MATA.(元数据表)。
管理着HMaster和HRegionServer的状态监控,保证集群中只有一个HMaster;
负责HMaster之间的故障自动切换(通过选举进行,采用PAXOS协议);
负责HRegionServer的故障后,通知给HMaster对HRegion集合进行修复,故障HRegionServer所辖HRegion分配给其他正常的HRegionServer;
Master与RegionServers 启动时会向ZooKeeper注册;
PS:
Zookeeper可以使用HBase自带的,也可以使用外部独立的(生产环境推荐用独立的)
3、Row key(行键)
Rowkey的概念和RDBMS(关系数据库)中的主键是完全一样的,HBase使用Rowkey来唯一的区分某一行的数据。
Row key可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在HBase内部,Row key保存为字节数组(即二进制码流)。
存储时,数据按照Row key的字典序(byte order)排序存储。设计key时,要充分利用排序存储这个特性,将经常一起读取的行存储放到一起(位置相关性)。
在HBase中,Row key对Hbase的性能影响非常大,所有对表的操作都要通过Rowkey,所以Rowkey的设计非常重要。下面罗列一些注意事项:
1)、Rowkey唯一原则
必须在设计上保证其唯一性。
2)、Rowkey散列原则
如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Row key的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。
如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。
3)、短小精简原则
Rowkey的长度被很多开发者建议说设计在10~100个字节,建议是越短越好,原因如下:
a、数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长,比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
b、MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
HBase只支持下面三种查询方式:
a、基于Rowkey的单行查询
b、基于Rowkey的范围扫描
c、全表扫描
PS:
a、字典序对int排序的结果是
1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。要保持整形的自然序,行键必须用0作左填充。
b、行的一次读写是原子操作 (不论一次读写多少列)。
4、Column Family(列族)
在HBase表中的每个列,都归属与某个列族,列族是表的schema的一部分(而列不是),必须在使用表之前定义,列名都以列族作为前缀,例如:courses:history , courses:math 都属于 courses 这个列族。
列族具有下面一些特性:
1)、一个列族可以包含多个列,可以动态增加列而不影响schema,列中的数据都是以二进制形式存在,没有数据类型
2)、权限控制、存储以及调优都是在列族层面进行的
3)、同一列族成员最好有相同的访问模式和大小特征
4)、同一列族里面的数据存储在同一目录下,由几个文件保存。
5、Cell
HBase中通过row和columns确定的一个存贮单元称为Cell。
每个Cell都保存着同一份数据的多个版本,每个版本的数据都包含一个生成时的时间戳,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。为了避免数据版本冲突,应用必须要保证时间戳唯一。
Cell中的数据是有版本的,由时间戳区分。
Cell由{Row key, column(=
Cell中的数据是没有类型的,全部是字节码形式存贮。
为了避免数据存在过多版本造成的管理 (包括存贮和索引)负担,HBase提供了两种数据版本回收方式:一是保存数据的最后n个版本,二是保存最近一段时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。
6、Timestamp时间戳:
在HBase中每个Cell存储单元同一份数据有个多个版本(数量可控制),每操作一次都会记录当时的操作时间作为时间戳来对各个版本进行区分。
时间戳的类型是 64位整型,可以由HBase自动赋值(精确到毫秒),也可以由应用端显示赋值,但应用端必须要保证唯一性。
7、Master
负责整个集群的管理,相当于集群的大脑,主要负责下面一些事宜:
1)、管理Region server,为Region server分配region
2)、负责Region server的负载均衡
3)、负责对失效的Region server的Region进行重新分配到其他Region server
4)、HDFS上的垃圾文件回收
5)、管理schema、table、Region寻址入口等元数据的操作
6)、管理权限控制(ACL)
8、Region Server
负责对数据的操作,一般和DataNode在同一台机器上运行,实现数据的本地访问,包含多个HRegion,具体内容包括HRegionServer、HRegion、WAL(HLog)、BlockCache、Store、MemStore、StoreFile、HFile、存储模型等。
1)HRegionServer
对Region Server进行管理,具体做下面一些事宜:
a、管理HMaster分配的Region
b、响应Client的读写数据操作,处理对Region的IO请求(从HMaster中获取元数据,找到RowKey所在的HRegionServer/HRegion后)
c、负责切分在运行过程中变得过大的Region
d、读写HDFS,管理Table中的数据。
HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列族创建一个Store实例,每个Store都会有一个MemStore和0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile, HFile就是实际的存储文件。
因此,一个HRegion有多少个列族就有多少个Store。 一个HRegionServer会有多个HRegion和一个HLog。
2)、HRegion
HRegion是一个Region在一个HRegionServer中的表达,是HBase中分布式存储和负载均衡的最小单元,一个Table可以有一个或多个Region,他们可以在一个相同的HRegionServer上,也可以分布在不同的HRegionServer上,但同一个Region只能在一个RegionServer上,不会跨RegionServer,一个HRegionServer可以有多个HRegion,他们分别属于不同的Table。
HBase使用RowKey将表在行的方向上(即水平)切割成多个HRegion,每个HRegion会保存一个表里某段连续的数据,因为每个HRegion都纪录了它的有且仅有一个StartKey和有且仅有一个EndKey(第一个HRegion的StartKey为空,最后一个HRegion的EndKey为空),由于RowKey是排序的(环形缓冲区进行字典排序或者是LinkedHashmap排序,每个HRegion里的RowKey是有序的,各个HRegion相对是无序的),所以HRegion内的数据是连续的。
Client可以通过HMaster快速的定位每个RowKey在哪个HRegion中。HRegion由HMaster分配到相应的HRegionServer中,然后由HRegionServer负责HRegion的启动和管理、和Client的通信、数据的读写(HDFS)。
每个HRegionServer可以同时管理1000个左右的HRegion。
Table 刚开始创建后,只有一个 Region,后续随着数据的逐渐增多(默认256M)会自动裂变为两个 Region。
发生裂变的依据是当Region中所有StoreFile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由HMaster分配到相应的RegionServer服务器,实现负载均衡。
每个Region由< 表名,startRowkey/endRowkey,创建时间> 标识,数据保存在两个表中:-ROOT- 和 .META.
-ROOT-:表包含.META.表所在的Region列表,该表只有一个Region;Zookeeper中记录了-ROOT-表的location
.META.:表包含所有的用户空间Region列表,以及Region Server服务器的地址
HRegion定位:Region被分配给哪个Region Server是完全动态的,HBase使用三层结构来定位Region:
a、通过zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一个Region。
b、通过-ROOT-表查找.META.表的第一个表中相应的Region的位置。其实-ROOT-表是.META.表的第一个Region;.META.表中的每一个Region在-ROOT-表中都是一行记录。
c、通过.META.表找到所要的用户表Region的位置。用户表中的每个Region在.META.表中都是一行记录。
PS:
-ROOT-表永远不会被分隔为多个Region,保证了最多需要三次跳转,就能定位到任意的Region。
Client会将查询的位置信息保存缓存起来,缓存不会主动失效,因此如果Client上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的Region,其中三次用来发现缓存失效,另外三次用来获取位置信息。
上面是早期的三层架构通过先找到 ROOT 表,从中获取分区 Meta 表位置;然后再获取分区 Meta 表信息,找出 Region 所在的 Region 服务器。
从 0.96 版本以后,三层架构被改为二层架构,去掉了 ROOT 表,同时 ZooKeeper 中的 /hbase/root-region-server 也被去掉。Meta 表所在的 Region 服务器信息直接存储在 ZooKeeper 中的 /hbase/meta-region-server 中。
下图为表和分区的分级管理机制。当客户端进行数据操作时, 根据操作的表名和行键,再按照一定的顺序即可寻找到对应的分区数据。
3)、WAL(HLog)
WAL即Write Ahead Log写入前记录的日志,不仅记录操作数据库的行为,还记录了数据,用来做灾难时恢复数据使用。在早期版本中称为HLog,它是HDFS上的一个文件,所有写操作都会先保证将数据写入这个Log文件后,才会真正更新MemStore,最后写入HFile中。
采用这种模式,可以保证HRegionServer宕机后,我们依然可以从该Log文件中读取数据,Replay所有的操作,而不至于数据丢失。
LogFlusher会定期的将缓存中信息写入到日志文件中;
LogRoller会实时监控对日志文件进行管理维护,产生新文件删除旧文件(那些已持久化到HFile中的Log可以删除)。
HLog文件就是一个普通的Hadoop Sequence File,Sequence File 的Key是HLogKey对象,HLogKey中记录了写入数据的归属信息,除了table和region名字外,同时还包括 sequence number和timestamp,
timestamp是”写入时间”,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number。
HLog SequeceFile的Value是HBase的KeyValue对象,即对应HFile中的KeyValue。
4)、BlockCache
BlockCache是一个读缓存,将数据预读取到内存中,以提升读的性能。
HBase中提供两种BlockCache的实现:默认on-heap LruBlockCache 和 BucketCache(通常是off-heap)。
通常BucketCache的性能要差于LruBlockCache,然而由于GC的影响,LruBlockCache的延迟会变的不稳定,而BucketCache由于是自己管理BlockCache,而不需要GC,因而它的延迟通常比较稳定,这也是有些时候需要选用BucketCache的原因。
5)、Store
每一个Region由一个或多个Store组成(至少是一个Store),每个Store对应了一个Table在这个Region中的一个Column Family(列族),每个Column Family(列族)是一个最小的存储单元,因而最好将具有相近IO需求的Column存储在一个Column Family(列族),以实现高效读取(数据局部性原理,可以提高缓存的命中率)。
Store包括位于内存中的MemStore 和 位于磁盘的 StoreFile。
HBase会为每个ColumnFamily(列族)建一个Store,如果有几个ColumnFamily,也就有几个Store。Store是HBase中存储的核心,它实现了读写HDFS功能,一个Store由一个MemStore 和 0或者多个StoreFile组成。
HBase以Store的大小来判断是否需要切分Region。
6)、MemStore
MemStore是一个写缓存(In Memory Sorted Buffer),是放在内存里的, 所有数据的写操作在完成WAL日志写后,会写入MemStore中保存修改的数据即keyValues。
当MemStore的大小达到一个阀值(默认64MB)时,MemStore会被flush到HDFS文件中,即生成一个快照。目前HBase 会有一个线程来负责MemStore的flush操作,同时系统会在Zookeeper中记录一个CheckPoint,表示这个时刻之前的数据变更已经持久化了,当系统出现意外时,可能导致MemStore中的数据丢失,
此时使用HLog来恢复CheckPoint之后的数据。
通常每个HRegion中的每个 Column Family有一个自己的MemStore。
客户端检索数据,先在MemStore找,找不到去BlockCache,找不到再找StoreFile。
7)、StoreFile
MemStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。HFile的存储是经过排序的键值映射结构,文件内部由连续的块组成,块的索引信息存储在文件的尾部。
StoreFile是只读的,一旦创建后就不可以再修改,因此Hbase的更新其实是不断追加的操作。文件格式见下图:
贴图 HFile格式
其中Data Block中的KeyValue对象格式如下:
贴图 Magic格式
KeyValue格式说明:
keylength:整型,表示key的长度
valuelength:整型,表示value的长度。
key:byte二进制码流,包括固定格式的数据
value:byte二进制码流,是raw data
Key的格式说明:
rowlength: 行的长度
row: 行键
columnfamilylength: 列族的长度
columnfamily: 列族名称
columnqualifier: 列的名称
timestamp: 时间戳或版本号
keytype: 键的类型,表示具体操作,分别是Put、Delete、 DeleteColumn和DeleteFamily
当StoreFile文件的数量增长到一定阈值后,系统会进行合并,有两种合并方式(minor、major):
Minor Compact
又叫small compact,在RS运行过程中会频繁进行,主要通过参数hbase.hstore.compactionThreshold进行控制,该参数配置了 HFile数量在满足该值时,进行minor compact,
minor compact只选取region下部分HFile进行compact操作,并且选取的HFile大小不能超过 hbase.hregion.max.filesize参数设置。
Major Compact
又叫large compact,major compact会对整个region下相同列簇的所有HFile进行compact,也就是说major compact结束后,同一个列簇下的HFile会被合并成一个大StoreFile。
major compact是一个比较长的过程,对底层I/O的压力相对较大,在合并过程同时会清理过期或者被删除的数据。
删除的原因:
因为Cell单元格的数据都是有版本号的,比如之前有cf:data=1;这个数据,然后我们如果再往这个单元格写一个cf:data=2;很明显这个数据的版本比之前的新(时间戳决定的),所以第一条数据就会成为失效数据,那么在合并的时候删除的就是这些数据。
合并的原因:
因为大数据不适合处理小文件,小文件虽然处理起来很快,但是每个小文件都需要开启一个maptask任务去执行,这样会造成巨大的资源浪费。
贴图合并
8)、HFile
HBase的中的所有Cell数据都以KeyValue的形式存储在HDFS里,这种文件就是HFile,对应于StoreFile,每个StoreFile都有一个HFile。
HFile是在HDFS内是以二进制形式存储的,数据是按RowKey、Column Family、Column排序,对相同的Cell(即这三个值都一样),则按timestamp倒序排列,存储格式如下:
贴图 Datablock格式
下面对HFile格式说明下,主要包括6个部分:
贴图 HFile描述格式
Data Block 段
保存表中的数据,是io的基本单元,这部分可以被压缩。每一个数据块由块头和一些KeyValue组成,key的值是严格按照顺序存储的。块大小默认为64K(由建表时创建cf时指定或者HColumnDescriptor.setBlockSize(size)),这一部分可以压缩存储。
大号的Block有利于顺序Scan,小号的Block利于随机查询。每个Data块除了开头的Magic以外就是一个个KeyValue对拼接而成。
在查询数据时,是以数据块为单位从硬盘load到内存。查找数据时,是顺序的遍历该块中的keyValue对。
贴图 Datablock格式
Meta Block 段 (可选的)
保存用户自定义的key-value对,可以被压缩。 比如booleam filter就是存在元数据块中的,该块只保留value值,key值保存在元数据索引块中。每一个元数据块由块头和value值组成。可以快速判断key是否都在这个HFile中。
File Info 段
HFile的元信息,这一段是定长的,不被压缩,用户也可以在这一部分添加自己的元信息。
Data Block Index 段
Data Block的索引,每条索引的key是被索引的block的第一条记录的key(格式为:头信息,(数据块在文件中的偏移 + 数据块长 + 数据块的第一个key),(数据块在文件中的偏移 + 数据块长 + 数据块的第一个key),……..)。
DataBlock Index采用LRU机制淘汰
贴图 datablockindex
Meta Block Index段 (可选的)
Meta Block的索引。 该块组成格式同数据块索引,只是某部分的意义不一样。
贴图 metablockindex
Trailer
这一段是定长的。保存了每一段的偏移量,读取一个HFile时,会首先读取Trailer,Trailer**保存了每个段的起始位置**(段的Magic Number用来做安全check),然后,DataBlock Index会被读取到内存中,这样,当检索某个key时,不需要扫描整个HFile,而只需从内存中找到key所在的block,通过一次磁盘io将整个 block读取到内存中,再找到需要的key。DataBlock Index采用LRU机制淘汰。
贴图 trailer
PS:
1、 FileInfo Offset – FileInfo信息在HFile中的偏移。long(8字节)。
2、 DataIndex Offset – 数据块索引在HFile中的偏移。long(8字节)。
3、 DataIndex Count – 数据块索引的个数。int(4字节)。
4、 MetaIndex Offset – 元数据索引块在HFile中的偏移。long(8字节)。
5、 MetaIndex Count – 元数据索引块的个数。int(4字节)。
6、 TotalUncompressedBytes – 未压缩的数据块部分的总大小。long(8字节)。
7、 Entry Count – 数据块中所有cell(key-value)的个数。int(4字节)
8、 Compression Codec – 压缩算法为enum类型,该值表示压缩算法代码。(LZO-0,GZ-1,NONE-2),int(4字节)
9、 Version – 版本信息。当前该版本值为1. int(4字节)。
HFile文件是不定长的,长度固定的只有其中的两块:Trailer和FileInfo。
其中Data Block,Meta Block通常采用压缩方式存储,压缩之后可以大大减少网络IO和磁盘IO。目前HFile的压缩支持两种方式:Gzip,Lzo。
9)、存储模型
HBase 中的每一张表就是所谓的 BigTable。
内部存储结构,见下图:
贴图 Magic格式
开始是两个固定长度的数值,分别表示key的长度和alue的长度。紧接着是Key,开始是固定长度的数值,表示RowKey的长度,紧接着是RowKey,然后是固定长度的数值,表示Family的长度,然后是Family,接着是Qualifier,然后是两个固定长度的数值,表示Time Stamp和Key Type(Put/Delete)。
Value部分没有那么复杂的结构,就是纯粹的二进制数据。
a、逻辑模型:
BigTable 会存储一系列的行记录,行记录有三个基本类型的定义:Row Key、Time Stamp、Column。
1、Row Key 是行在 BigTable 中的唯一标识。
2、Time Stamp 是每次数据操作对应关联的时间戳,可以看做 SVN 的版本。
3、Column 定义为< family>:< label>,通过这两部分可以指定唯一的数据的存储列,family 的定义和修改需要 对 HBase 进行类似于 DB 的 DDL 操作,而 label ,不需要定义直接可以使用,这也为动态定制列提供了一种手段 。
family 另一个作用体现在物理存储优化读写操作上,同 family 的数据物理上保存的会比较临近,因此在业务设计的过程中可以利用这个特性。
HBase 以表的形式存储数据。表由行和列组成。列划分为若干个列族(row family),如下图所示:
贴图 数据存储结构
从上图中可以看出,HBase是面向列簇进行存储的。每个Cell由 {row key,column(=< family> + < label>),version} 唯一确定的单元,他们组合在一起就是一个KeyValue。
这个KeyValue中的key就是{row key,column(=< family> + < label>),version} ,而value就是cell中的值。
HBase的三维有序存储中的三维是指:rowkey(行主键),column key(columnFamily +
b、物理模型
Table 中所有行都按照row key的字典序排列,在行的方向上分割为多个Region,Region是Hbase中分布式存储和负载均衡的最小单元。见下图:
贴图 行分隔region
不同的Region分散在不同的RegionServer中,同一个Region只会分布在一个RegionServer中,不会跨RegionServer分布。
见下图:
Table刚开始新建时只有一个Region,随着数据逐渐增多时(默认256M),会自动分解成两个Region,然后均衡分布到不同的RegionServer中。见下图:
贴图 分裂region
每个HRegion由多个Store构成,每个Store由一个memStore 和 0或多个StoreFile组成,每个Store保存一个Columns Family。
每个 Columns Family 存储在HDFS上的一个单独文件中,空值不会被保存;Key 和 Version number在每个 Columns Family 中均有一份;
HBase 为每个值维护了多级索引,即:
Region虽然是分布式存储的最小单元,但并不是存储的最小单元。Region由一个或者多个Store组成,每个store保存一个columns family;每个Strore又由一个memStore和0至多个StoreFile组成,StoreFile包含HFile;memStore存储在内存中,StoreFile存储在HDFS上。见下图:
贴图 存储物理Region
c、存储数据结构算法
HBase使用了LSM(Log-Structured Merge-Trees)树结构,常见的树结构还有二叉树、B+树、B-树、红黑树等。
LSM原理:
把一颗大树拆分成N棵小树, 它首先写入到内存中(内存没有寻道速度的问题,随机写的性能得到大幅提升),在内存中构建一颗有序小树,随着小树越来越大,内存的小树会flush到磁盘上。
当读时,由于不知道数据在哪棵小树上,因此必须遍历所有的小树,但在每颗小树内部数据是有序的。
贴图 LSM树结构
9、高可用
HBase通过下面一些机制来确保提供高可用。
1)、通过Zookeeper集群感知各节点状态;提供自主选举;信息存储。
2)、Master故障自动选举切换,在切换过程中,Region分配、负载均衡暂时不可用
3)、RegionServer故障,Master会自动重新再分配新的RegionServer并迁移数据,在RegionServer再分配、Region切分、Region分配、负载均衡时、Region暂时不可访问
4)、WAL(HLog)日志存储于Zookeeper,用于Master自动回复数据
5)、存储依赖HDFS,HDFS自身保证数据存储高可用
10、HBase写数据流程
1、Client先访问zookeeper,从root找到meta,然后从meta表获取所有region信息
2、从namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息
3、找到对应的regionserver
4、把数据分别写到HLog和MemStore上一份
5.向客户端发送ack响应;
7、MemStore达到一个阈值后则把数据刷成一个StoreFile文件。(若MemStore中的数据有丢失,则可以从HLog上恢复)
8、当多个StoreFile文件达到一定的大小后,会触发Compact合并操作,合并为一个StoreFile,(这里同时进行版本的合并和数据删除。)
9、当Storefile大小超过一定阈值后,会把当前的Region分割为两个(Split),并由Hmaster分配到相应的HRegionServer,实现负载均衡
其中7、8、9后台自动处理
贴图 WriteData
11、HBase读数据流程
1、Client先访问zookeeper,从root找到meta,然后从meta表获取所有region信息
2、从namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息
3、找到对应的regionserver
4、查找对应的region
5、先从MemStore找数据;如果没有,到BlockCache上读;还没有,再到StoreFile上读,并把读的结果放入BlockCache。
6、将查到的所有数据进行合并返回给客户端
贴图 readData
12、过滤器
1)、SingleColumnValueFilter
SingleColumnValueFilter 用于测试值的情况(相等,不等,范围等)
2)、SingleColumnValueExcludeFilter
跟SingleColumnValueFilter 功能一样,只是不查询出该列的值。
3)、FamilyFilter
用于过滤列族(通常在 Scan 过程中通过设定某些列族来实现该功能,而不是直接使用该过滤器)。
4)、QualifierFilter
用于列名(Qualifier)过滤
5)、ColumnPrefixFilter
用于列名(Qualifier)前缀过滤,即包含某个前缀的所有列名。
6)、RowFilter
行键过滤器,一般来讲,执行 Scan 使用 startRow/stopRow 方式比较好,而 RowFilter 过滤器也可以完成对某一行的过滤。
7)、RandomRowFilter
该过滤器是随机选择一行的过滤器。参数 chance 是一个浮点值,介于 0.1 和 1.0 之间。
8)、PageFilter
1、单机模式
所有进程都宿主在一个JVM里,运行在一台主机上,只有一个Master, 文件可以存储在本地或HDFS(不配置hbase.rootdir默认写在tmp下,重启会丢失),仅用于开发者搭建学习和试验环境。
2、伪集群模式
由Master(2个)、RegionServer(3个以上)将以守护进程的形式在单机运行,分别宿主于不同端口,文件存储HDFS(必须先搭建好Hadoop集群),一般用于运维测试集群环境搭建过程。
3、集群模式
HBase的生产环境模式,需要独立的Zookeeper分布式集群、Hadoop分布式集群,用于提供生产级服务。
缺点:
1、不支持多条件查询,只支持按照Row key来查询
仅支持单行事务
仅支持三种查询方式(single row key、range row key、scan all rows of table)
仅基于row key的索引
2、查询数据功能很简单,不支持 join 等复杂操作
3、数据类型有限,只支持字符串数据,底层所有数据都是二进制码流存储于HDFS
4、Region在自动切分、故障转移、数据合并时,短暂影响数据读取
5、没有内置的身份和权限认证
优点:
1、大容量且支持实时处理。
2、支持面向列、稀疏设计,可动态增加列,不受模式制约,列为空就不存储,节省存储空间。
3、行级别原子性,数据操作一定是完全成功或者完全失败
4、强一致性,同行数据只支持在一个RegionServer上操作
5、数据类型简单,只有字符串,支持数据多版本
6、高容错性
采用WAL机制,保证数据写入不丢失
采用自动感知节点状态及Replication机制,保证存储数据不丢失
底层存储采用HDFS,确保底层数据存储不丢失
7、高扩展性
支持数据在行和列2个维度动态扩展
自身存储逻辑支持动态水平扩展(扩展RegionServer)
底层物理数据支持动态水平扩展(扩展DataNode)
8、高性能
数据写入时先写入内存,写入性能非常高,支持高并发写
采用RowKey主键索引、Region自动切分、HFile自动合并、LSM树存储,确保海量数据的随机读写性能
9、高可靠性
自动感知节点状态
Master发生故障会自主切换
RegionServer发生故障会自主迁移数据到其他节点
底层采用HDFS,天然的保证高可用
10、可以跟Hive集成,使用类SQL进行查询
11、对于大容量查询优化,支持块缓存Block Cache 和 布隆过滤器 Bloom Filter;
12、支持Thirft协议,通过内置的 REST 为非Java端的访问提供支持;
13、通过MapReduce支持大并发处理
14、支持JMX通过内置网页便于运维管理
HBase具有下面一些特性:
1. 容量大且支持实时处理,具有强一致性(严格一致的读取和写入)
2. 面向列存储,确保应用数据在横向(列)和纵向(行)两个维度都可以弹性扩展
3. 多版本,天然的支持数据变更履历,适合将数据履历作为资产来进行分析挖掘
4. 稀疏性,便利存储半结构化和非结构化数据
5. 非常容易拓展,自身动态扩展RegionServer且自动切分Region,底层依赖HDFS
6. 高可靠性,采用WAL、MemStore快照、Replication,确保数据不会丢失
7. 高性能,采用RowKey主键索引、Region自动切分、HFile自动合并、LSM树存储,确保海量数据的随机读写性能
基于以上一些特性,从下面几个应用维度来概括下常见应用场景。
贴图 场景
PS:后续逐渐把实践调优过程补充上来
各个平台一般都有相应的操作组件,下面介绍下java和DoNet平台下的访问组件。
java平台:
1、纯原生java客户端 推荐用这个
2、使用内置的REST Gateway访问
DoNet平台:
1、HBase没有为Java外的语言直接提供原生客户端,是通过一个内置的REST服务,以Thirft协议为桥梁,可扩展支持其他语言。
C#要想访问HBase也只能走这个通道。
通过thrift-0.12.0.tar.gz、thrift-0.12.0.exe、hbase.thrift这三个东西生成C#的访问客户端
执行命令 thrift-0.12.0.exe --gen csharp hbase.thrift 生成gen-csharp,然后引用thrift-0.12.0.tar.gz里的csharp\src下面的一些类一起生成。
2、Microsoft.HBase.Client
这个不知道能不能直接访问原生的HBase,需要测试下? 可能只能访问微软封装的云原生HBase
Nuget: 下载Microsoft.HBase.Client